00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #ifdef BSP_ENABLED
00022
00023 #include "Ciphersuite.h"
00024 #include "BA_BlockProcessor.h"
00025 #include "Ciphersuite_BA1.h"
00026 #include "PS_BlockProcessor.h"
00027 #include "Ciphersuite_PS2.h"
00028 #include "C_BlockProcessor.h"
00029 #include "Ciphersuite_C3.h"
00030 #include "bundling/Bundle.h"
00031 #include "bundling/BundleDaemon.h"
00032 #include "bundling/BundleProtocol.h"
00033 #include "contacts/Link.h"
00034 #include "bundling/SDNV.h"
00035
00036 namespace dtn {
00037
00038
00039 #define CS_MAX 1024
00040 Ciphersuite* Ciphersuite::ciphersuites_[CS_MAX];
00041
00042 static const char* log = "/dtn/bundle/ciphersuite";
00043
00044 bool Ciphersuite::inited = false;
00045
00046
00047 Ciphersuite::Ciphersuite()
00048
00049 {
00050 log_debug_p(log, "Ciphersuite::Ciphersuite()");
00051 }
00052
00053
00054 Ciphersuite::~Ciphersuite()
00055 { }
00056
00057
00058 void
00059 Ciphersuite::register_ciphersuite(Ciphersuite* cs)
00060 {
00061 log_debug_p(log, "Ciphersuite::register_ciphersuite()");
00062 u_int16_t num = cs->cs_num();
00063
00064 if ( num <= 0 || num >= CS_MAX )
00065 return;
00066
00067
00068 ASSERT(ciphersuites_[num] == 0);
00069 ciphersuites_[num] = cs;
00070 }
00071
00072
00073 Ciphersuite*
00074 Ciphersuite::find_suite(u_int16_t num)
00075 {
00076 Ciphersuite* ret = NULL;
00077 log_debug_p(log, "Ciphersuite::find_suite()");
00078
00079 if ( num > 0 && num < CS_MAX )
00080 ret = ciphersuites_[num];
00081
00082 return ret;
00083 }
00084
00085
00086 void
00087 Ciphersuite::init_default_ciphersuites()
00088 {
00089 log_debug_p(log, "Ciphersuite::init_default_ciphersuites()");
00090 if ( ! inited ) {
00091
00092 BundleProtocol::register_processor(new BA_BlockProcessor());
00093 BundleProtocol::register_processor(new PS_BlockProcessor());
00094 BundleProtocol::register_processor(new C_BlockProcessor());
00095
00096
00097 register_ciphersuite(new Ciphersuite_BA1());
00098 register_ciphersuite(new Ciphersuite_PS2());
00099 register_ciphersuite(new Ciphersuite_C3());
00100
00101 inited = true;
00102 }
00103 }
00104
00105
00106 u_int16_t
00107 Ciphersuite::cs_num(void)
00108 {
00109
00110 return 0;
00111 }
00112
00113
00114 void
00115 Ciphersuite::parse(BlockInfo* block)
00116 {
00117 Ciphersuite* cs_owner = NULL;
00118 BP_Local_CS* locals = NULL;
00119 u_char* buf;
00120 size_t len;
00121 u_int64_t cs_flags;
00122 u_int64_t suite_num;
00123 int sdnv_len;
00124 u_int64_t security_correlator = 0LL;
00125 u_int64_t field_length = 0LL;
00126 bool has_source;
00127 bool has_dest;
00128 bool has_params;
00129 bool has_correlator;
00130 bool has_result;
00131 EndpointIDVector::const_iterator iter;
00132
00133
00134
00135
00136 log_debug_p(log, "Ciphersuite::parse() block %p", block);
00137 ASSERT(block != NULL);
00138
00139
00140
00141
00142
00143
00144 buf = block->contents().buf() + block->data_offset();
00145 len = block->data_length();
00146
00147
00148 sdnv_len = SDNV::decode(buf,
00149 len,
00150 &suite_num);
00151 buf += sdnv_len;
00152 len -= sdnv_len;
00153
00154 sdnv_len = SDNV::decode(buf,
00155 len,
00156 &cs_flags);
00157 buf += sdnv_len;
00158 len -= sdnv_len;
00159
00160 has_source = (cs_flags & CS_BLOCK_HAS_SOURCE) != 0;
00161 has_dest = (cs_flags & CS_BLOCK_HAS_DEST) != 0;
00162 has_params = (cs_flags & CS_BLOCK_HAS_PARAMS) != 0;
00163 has_correlator = (cs_flags & CS_BLOCK_HAS_CORRELATOR) != 0;
00164 has_result = (cs_flags & CS_BLOCK_HAS_RESULT) != 0;
00165 log_debug_p(log, "Ciphersuite::parse() suite_num %llu cs_flags 0x%llx",
00166 U64FMT(suite_num), U64FMT(cs_flags));
00167
00168 cs_owner = dynamic_cast<Ciphersuite*>(find_suite(suite_num));
00169
00170 if ( ciphersuites_[suite_num] != NULL )
00171 cs_owner = ciphersuites_[suite_num];
00172
00173 if ( block->locals() == NULL ) {
00174 if ( cs_owner != NULL )
00175 cs_owner->init_locals(block);
00176 else
00177 block->set_locals( new BP_Local_CS );
00178 }
00179
00180 locals = dynamic_cast<BP_Local_CS*>(block->locals());
00181 ASSERT ( locals != NULL );
00182
00183 ASSERT ( suite_num < 65535 );
00184 locals->set_owner_cs_num(suite_num);
00185
00186
00187 ASSERT ( cs_flags < 65535 );
00188 locals->set_cs_flags(cs_flags);
00189
00190
00191 if ( has_correlator ) {
00192 sdnv_len = SDNV::decode(buf,
00193 len,
00194 &security_correlator);
00195 buf += sdnv_len;
00196 len -= sdnv_len;
00197 }
00198 log_debug_p(log, "Ciphersuite::parse() correlator %llu",
00199 U64FMT(security_correlator));
00200 locals->set_correlator(security_correlator);
00201
00202
00203
00204 if ( has_params ) {
00205 sdnv_len = SDNV::decode(buf,
00206 len,
00207 &field_length);
00208 buf += sdnv_len;
00209 len -= sdnv_len;
00210
00211 locals->writable_security_params()->reserve(field_length);
00212 memcpy( locals->writable_security_params()->end(), buf, field_length);
00213 locals->writable_security_params()->set_len(field_length);
00214 buf += field_length;
00215 len -= field_length;
00216 log_debug_p(log, "Ciphersuite::parse() security_params len %llu",
00217 U64FMT(field_length));
00218 }
00219
00220
00221
00222 log_debug_p(log, "Ciphersuite::parse() eid_list().size() %zu has_source %u has_dest %u",
00223 block->eid_list().size(), has_source, has_dest);
00224
00225
00226 if ( block->eid_list().size() > 0 ) {
00227 iter = block->eid_list().begin();
00228 if ( has_source ) {
00229 locals->set_security_src( iter->str() );
00230 iter++;
00231 }
00232
00233
00234
00235 if ( has_dest ) {
00236 locals->set_security_dest( iter->str() );
00237 }
00238 }
00239
00240
00241
00242 if ( has_result ) {
00243 sdnv_len = SDNV::decode(buf,
00244 len,
00245 &field_length);
00246 buf += sdnv_len;
00247 len -= sdnv_len;
00248
00249 locals->writable_security_result()->reserve(field_length);
00250 memcpy( locals->writable_security_result()->end(), buf, field_length);
00251 locals->writable_security_result()->set_len(field_length);
00252 buf += field_length;
00253 len -= field_length;
00254
00255 }
00256
00257
00258
00259
00260 }
00261
00262
00263
00264 int
00265 Ciphersuite::reload_post_process(Bundle* bundle,
00266 BlockInfoVec* block_list,
00267 BlockInfo* block)
00268 {
00269 (void)bundle;
00270 (void)block_list;
00271 (void)block;
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 block->set_reloaded(false);
00283 return 0;
00284
00285 }
00286
00287
00288 void
00289 Ciphersuite::generate_preamble(BlockInfoVec* xmit_blocks,
00290 BlockInfo* block,
00291 u_int8_t type,
00292 u_int64_t flags,
00293 u_int64_t data_length)
00294 {
00295 block->owner()->generate_preamble(xmit_blocks, block, type,
00296 flags, data_length);
00297 }
00298
00299
00300 bool
00301 Ciphersuite::destination_is_local_node(const Bundle* bundle,
00302 const BlockInfo* block)
00303 {
00304 u_int16_t cs_flags = 0;
00305 EndpointID local_eid = BundleDaemon::instance()->local_eid();
00306 BP_Local_CS* locals;
00307 bool result = false;
00308
00309 log_debug_p(log, "Ciphersuite::destination_is_local_node()");
00310 if ( block == NULL )
00311 return false;
00312
00313 if ( block->locals() == NULL )
00314 return false;
00315
00316 locals = dynamic_cast<BP_Local_CS*>(block->locals());
00317 if ( locals == NULL )
00318 return false;
00319
00320 cs_flags = locals->cs_flags();
00321
00322
00323 std::string bundle_dest_str = bundle->dest().uri().scheme() + "://" +
00324 bundle->dest().uri().host();
00325 EndpointID dest_node(bundle_dest_str);
00326
00327
00328
00329 if ( ( (cs_flags & Ciphersuite::CS_BLOCK_HAS_DEST) && (local_eid == locals->security_dest())) ||
00330 ( !(cs_flags & Ciphersuite::CS_BLOCK_HAS_DEST) && (local_eid == dest_node) ) )
00331 {
00332 result = true;
00333 }
00334
00335 return result;
00336 }
00337
00338
00339 bool
00340 Ciphersuite::source_is_local_node(const Bundle* bundle, const BlockInfo* block)
00341 {
00342 u_int16_t cs_flags = 0;
00343 EndpointID local_eid = BundleDaemon::instance()->local_eid();
00344 BP_Local_CS* locals;
00345 bool result = false;
00346
00347 log_debug_p(log, "Ciphersuite::source_is_local_node()");
00348 if ( block == NULL )
00349 return false;
00350
00351 if ( block->locals() == NULL )
00352 return false;
00353
00354 locals = dynamic_cast<BP_Local_CS*>(block->locals());
00355 if ( locals == NULL )
00356 return false;
00357
00358 cs_flags = locals->cs_flags();
00359
00360
00361 std::string bundle_src_str = bundle->source().uri().scheme() + "://" +
00362 bundle->source().uri().host();
00363 EndpointID src_node(bundle_src_str);
00364
00365
00366
00367 if ( ( (cs_flags & Ciphersuite::CS_BLOCK_HAS_SOURCE) && (local_eid == locals->security_src())) ||
00368 ( !(cs_flags & Ciphersuite::CS_BLOCK_HAS_SOURCE) && (local_eid == src_node) ) )
00369 {
00370 result = true;
00371 }
00372
00373 return result;
00374 }
00375
00376
00377 bool
00378 Ciphersuite::check_validation(const Bundle* bundle,
00379 const BlockInfoVec* block_list,
00380 u_int16_t num)
00381 {
00382 (void)bundle;
00383 u_int16_t proc_flags = 0;
00384 BP_Local_CS* locals;
00385 BlockInfoVec::const_iterator iter;
00386
00387 log_debug_p(log, "Ciphersuite::check_validation(%hu)", num);
00388 if ( block_list == NULL )
00389 return false;
00390
00391 for ( iter = block_list->begin();
00392 iter != block_list->end();
00393 ++iter)
00394 {
00395 if ( iter->locals() == NULL )
00396 continue;
00397
00398 locals = dynamic_cast<BP_Local_CS*>(iter->locals());
00399 if ( locals == NULL )
00400 continue;
00401
00402 if (locals->owner_cs_num() != num )
00403 continue;
00404
00405
00406 proc_flags |= locals->proc_flags();
00407 }
00408
00409
00410
00411 if ( proc_flags & CS_BLOCK_PASSED_VALIDATION )
00412 return true;
00413
00414
00415 if ( proc_flags & CS_BLOCK_FAILED_VALIDATION )
00416 return false;
00417
00418
00419
00420 if ( proc_flags & CS_BLOCK_DID_NOT_FAIL )
00421 return true;
00422
00423 return false;
00424 }
00425
00426
00427 u_int64_t
00428 Ciphersuite::create_correlator(const Bundle* bundle,
00429 const BlockInfoVec* block_list)
00430 {
00431 (void)bundle;
00432 u_int64_t result = 0LLU;
00433 u_int16_t high_val = 1;
00434 u_int16_t value;
00435 BP_Local_CS* locals;
00436 BlockInfoVec::const_iterator iter;
00437
00438 log_debug_p(log, "Ciphersuite::create_correlator()");
00439 if ( bundle == NULL )
00440 return 1LLU;
00441
00442 if ( block_list == NULL )
00443 return 1LLU;
00444
00445 if ( bundle->is_fragment() ) {
00446 result = bundle->frag_offset() << 24;
00447 }
00448
00449 for ( iter = block_list->begin();
00450 iter != block_list->end();
00451 ++iter)
00452 {
00453 if ( iter->locals() == NULL )
00454 continue;
00455
00456 locals = dynamic_cast<BP_Local_CS*>(iter->locals());
00457 if ( locals == NULL )
00458 continue;
00459
00460 value = locals->correlator();
00461
00462 value = value > high_val ? value : high_val;
00463 }
00464
00465 result |= high_val;
00466
00467 return result;
00468 }
00469
00470
00471 void
00472 Ciphersuite::init_locals(BlockInfo* block)
00473 {
00474
00475
00476
00477
00478
00479
00480 if ( block->locals() == NULL )
00481 block->set_locals( new BP_Local_CS );
00482
00483 }
00484
00485
00486 BP_Local_CS::BP_Local_CS()
00487 : BP_Local(),
00488 cs_flags_(0),
00489 security_result_offset_(0),
00490 correlator_(0LL),
00491 security_params_(),
00492 security_result_(),
00493 owner_cs_num_(0)
00494 {
00495 }
00496
00497
00498 BP_Local_CS::BP_Local_CS(const BP_Local_CS& b)
00499 : BP_Local(),
00500 cs_flags_(b.cs_flags_),
00501 security_result_offset_(b.security_result_offset_),
00502 correlator_(b.correlator_),
00503 security_params_(b.security_params_),
00504 security_result_(b.security_result_),
00505 owner_cs_num_(b.owner_cs_num_)
00506
00507 {
00508 }
00509
00510
00511 BP_Local_CS::~BP_Local_CS()
00512 {
00513 }
00514
00515
00516 void
00517 BP_Local_CS::set_key(u_char* k, size_t len)
00518 {
00519 key_.reserve(len);
00520 key_.set_len(len);
00521 memcpy(key_.buf(), k, len);
00522 }
00523
00524
00525 void
00526 BP_Local_CS::set_salt(u_char* s, size_t len)
00527 {
00528 salt_.reserve(len);
00529 salt_.set_len(len);
00530 memcpy(salt_.buf(), s, len);
00531 }
00532
00533
00534 void
00535 BP_Local_CS::set_iv(u_char* iv, size_t len)
00536 {
00537 iv_.reserve(len);
00538 iv_.set_len(len);
00539 memcpy(iv_.buf(), iv, len);
00540 }
00541
00542
00543 }
00544
00545 #endif