IBR-DTNSuite
0.8
|
00001 /* 00002 * SecurityBlock.cpp 00003 * 00004 * Created on: 08.03.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrdtn/security/SecurityBlock.h" 00009 #include "ibrdtn/security/MutualSerializer.h" 00010 #include "ibrdtn/data/Bundle.h" 00011 #include "ibrdtn/data/PayloadBlock.h" 00012 #include "ibrdtn/data/ExtensionBlock.h" 00013 00014 #include <ibrcommon/Logger.h> 00015 #include <cstdlib> 00016 #include <openssl/rand.h> 00017 #include <openssl/err.h> 00018 #include <openssl/rsa.h> 00019 #include <netinet/in.h> 00020 00021 #ifdef __DEVELOPMENT_ASSERTIONS__ 00022 #include <cassert> 00023 #endif 00024 00025 namespace dtn 00026 { 00027 namespace security 00028 { 00029 const std::string SecurityBlock::TLVList::toString() const 00030 { 00031 std::stringstream ss; 00032 00033 for (std::set<TLV>::const_iterator iter = begin(); iter != end(); iter++) 00034 { 00035 ss << (*iter); 00036 } 00037 00038 return ss.str(); 00039 } 00040 00041 size_t SecurityBlock::TLVList::getLength() const 00042 { 00043 size_t len = getPayloadLength(); 00044 return len; 00045 } 00046 00047 size_t SecurityBlock::TLVList::getPayloadLength() const 00048 { 00049 size_t len = 0; 00050 00051 for (std::set<SecurityBlock::TLV>::const_iterator iter = begin(); iter != end(); iter++) 00052 { 00053 len += (*iter).getLength(); 00054 } 00055 00056 return len; 00057 } 00058 00059 const std::string SecurityBlock::TLVList::get(SecurityBlock::TLV_TYPES type) const 00060 { 00061 for (std::set<SecurityBlock::TLV>::const_iterator iter = begin(); iter != end(); iter++) 00062 { 00063 if ((*iter).getType() == type) 00064 { 00065 return (*iter).getValue(); 00066 } 00067 } 00068 00069 throw ibrcommon::Exception("element not found"); 00070 } 00071 00072 void SecurityBlock::TLVList::get(TLV_TYPES type, unsigned char *value, size_t length) const 00073 { 00074 const std::string data = get(type); 00075 00076 if (length < data.size()) 00077 { 00078 ::memcpy(value, data.c_str(), length); 00079 } 00080 else 00081 { 00082 ::memcpy(value, data.c_str(), data.size()); 00083 } 00084 } 00085 00086 void SecurityBlock::TLVList::set(SecurityBlock::TLV_TYPES type, std::string value) 00087 { 00088 SecurityBlock::TLV tlv(type, value); 00089 00090 erase(tlv); 00091 insert(tlv); 00092 } 00093 00094 void SecurityBlock::TLVList::set(TLV_TYPES type, const unsigned char *value, size_t length) 00095 { 00096 const std::string data(reinterpret_cast<const char *>(value), length); 00097 set(type, data); 00098 } 00099 00100 void SecurityBlock::TLVList::remove(SecurityBlock::TLV_TYPES type) 00101 { 00102 erase(SecurityBlock::TLV(type, "")); 00103 } 00104 00105 const std::string SecurityBlock::TLV::getValue() const 00106 { 00107 return _value; 00108 } 00109 00110 SecurityBlock::TLV_TYPES SecurityBlock::TLV::getType() const 00111 { 00112 return _type; 00113 } 00114 00115 size_t SecurityBlock::TLV::getLength() const 00116 { 00117 return _value.getLength() + sizeof(char); 00118 } 00119 00120 std::ostream& operator<<(std::ostream &stream, const SecurityBlock::TLVList &tlvlist) 00121 { 00122 dtn::data::SDNV length(tlvlist.getPayloadLength()); 00123 stream << length; 00124 00125 for (std::set<SecurityBlock::TLV>::const_iterator iter = tlvlist.begin(); iter != tlvlist.end(); iter++) 00126 { 00127 stream << (*iter); 00128 } 00129 return stream; 00130 } 00131 00132 std::istream& operator>>(std::istream &stream, SecurityBlock::TLVList &tlvlist) 00133 { 00134 dtn::data::SDNV length; 00135 stream >> length; 00136 size_t read_length = 0; 00137 00138 while (read_length < length.getValue()) 00139 { 00140 SecurityBlock::TLV tlv; 00141 stream >> tlv; 00142 tlvlist.insert(tlv); 00143 read_length += tlv.getLength(); 00144 } 00145 00146 return stream; 00147 } 00148 00149 bool SecurityBlock::TLV::operator<(const SecurityBlock::TLV &tlv) const 00150 { 00151 return (_type < tlv._type); 00152 } 00153 00154 bool SecurityBlock::TLV::operator==(const SecurityBlock::TLV &tlv) const 00155 { 00156 return (_type == tlv._type); 00157 } 00158 00159 std::ostream& operator<<(std::ostream &stream, const SecurityBlock::TLV &tlv) 00160 { 00161 stream.put((char)tlv._type); 00162 stream << tlv._value; 00163 return stream; 00164 } 00165 00166 std::istream& operator>>(std::istream &stream, SecurityBlock::TLV &tlv) 00167 { 00168 char tlv_type; 00169 stream.get(tlv_type); tlv._type = SecurityBlock::TLV_TYPES(tlv_type); 00170 stream >> tlv._value; 00171 return stream; 00172 } 00173 00174 SecurityBlock::SecurityBlock(const dtn::security::SecurityBlock::BLOCK_TYPES type, const dtn::security::SecurityBlock::CIPHERSUITE_IDS id) 00175 : Block(type), _ciphersuite_id(id), _ciphersuite_flags(0), _correlator(0) 00176 { 00177 00178 } 00179 00180 SecurityBlock::SecurityBlock(const dtn::security::SecurityBlock::BLOCK_TYPES type) 00181 : Block(type), _ciphersuite_flags(0), _correlator(0) 00182 { 00183 00184 } 00185 00186 SecurityBlock::~SecurityBlock() 00187 { 00188 } 00189 00190 void SecurityBlock::store_security_references() 00191 { 00192 // clear the EID list 00193 _eids.clear(); 00194 00195 // first the security source 00196 if (_security_source == dtn::data::EID()) 00197 { 00198 _ciphersuite_flags &= ~(SecurityBlock::CONTAINS_SECURITY_SOURCE); 00199 } 00200 else 00201 { 00202 _ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_SOURCE; 00203 _eids.push_back(_security_source); 00204 } 00205 00206 // then the destination 00207 if (_security_destination == dtn::data::EID()) 00208 { 00209 _ciphersuite_flags &= ~(SecurityBlock::CONTAINS_SECURITY_DESTINATION); 00210 } 00211 else 00212 { 00213 _ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_DESTINATION; 00214 _eids.push_back(_security_destination); 00215 } 00216 00217 if (_eids.size() > 0) 00218 { 00219 set(Block::BLOCK_CONTAINS_EIDS, true); 00220 } 00221 else 00222 { 00223 set(Block::BLOCK_CONTAINS_EIDS, false); 00224 } 00225 } 00226 00227 const dtn::data::EID SecurityBlock::getSecuritySource() const 00228 { 00229 return _security_source; 00230 } 00231 00232 const dtn::data::EID SecurityBlock::getSecurityDestination() const 00233 { 00234 return _security_destination; 00235 } 00236 00237 void SecurityBlock::setSecuritySource(const dtn::data::EID &source) 00238 { 00239 _security_source = source; 00240 store_security_references(); 00241 } 00242 00243 void SecurityBlock::setSecurityDestination(const dtn::data::EID &destination) 00244 { 00245 _security_destination = destination; 00246 store_security_references(); 00247 } 00248 00249 void SecurityBlock::setCiphersuiteId(const CIPHERSUITE_IDS id) 00250 { 00251 _ciphersuite_id = static_cast<u_int64_t>(id); 00252 } 00253 00254 void SecurityBlock::setCorrelator(const u_int64_t corr) 00255 { 00256 _correlator = corr; 00257 _ciphersuite_flags |= SecurityBlock::CONTAINS_CORRELATOR; 00258 } 00259 00260 bool SecurityBlock::isCorrelatorPresent(const dtn::data::Bundle& bundle, const u_int64_t correlator) 00261 { 00262 std::list<const dtn::data::Block *> blocks = bundle.getBlocks(); 00263 bool return_val = false; 00264 for (std::list<const dtn::data::Block *>::const_iterator it = blocks.begin(); it != blocks.end() && !return_val; it++) 00265 { 00266 char type = (*it)->getType(); 00267 if (type == BUNDLE_AUTHENTICATION_BLOCK 00268 || type == PAYLOAD_INTEGRITY_BLOCK 00269 || type == PAYLOAD_CONFIDENTIAL_BLOCK 00270 || type == EXTENSION_SECURITY_BLOCK) 00271 return_val = static_cast<const SecurityBlock*>(*it)->_correlator == correlator; 00272 } 00273 return return_val; 00274 } 00275 00276 u_int64_t SecurityBlock::createCorrelatorValue(const dtn::data::Bundle& bundle) 00277 { 00278 u_int64_t corr = random(); 00279 while (isCorrelatorPresent(bundle, corr)) 00280 corr = random(); 00281 return corr; 00282 } 00283 00284 size_t SecurityBlock::getLength() const 00285 { 00286 size_t length = dtn::data::SDNV::getLength(_ciphersuite_id) 00287 + dtn::data::SDNV::getLength(_ciphersuite_flags); 00288 00289 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00290 { 00291 length += dtn::data::SDNV::getLength(_correlator); 00292 } 00293 00294 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00295 { 00296 const dtn::data::SDNV size(_ciphersuite_params.getLength()); 00297 length += size.getLength() + size.getValue(); 00298 } 00299 00300 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00301 { 00302 const dtn::data::SDNV size(getSecurityResultSize()); 00303 length += size.getLength() + size.getValue(); 00304 } 00305 00306 return length; 00307 } 00308 00309 size_t SecurityBlock::getLength_mutable() const 00310 { 00311 // ciphersuite_id 00312 size_t length = MutualSerializer::sdnv_size; 00313 00314 // ciphersuite_flags 00315 length += MutualSerializer::sdnv_size; 00316 00317 // correlator 00318 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00319 { 00320 length += MutualSerializer::sdnv_size; 00321 } 00322 00323 // ciphersuite parameters 00324 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00325 { 00326 length += MutualSerializer::sdnv_size; 00327 length += _ciphersuite_params.getLength(); 00328 } 00329 // security result 00330 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00331 { 00332 length += MutualSerializer::sdnv_size + getSecurityResultSize(); 00333 } 00334 00335 return length; 00336 } 00337 00338 std::ostream& SecurityBlock::serialize(std::ostream &stream, size_t &length) const 00339 { 00340 stream << dtn::data::SDNV(_ciphersuite_id) << dtn::data::SDNV(_ciphersuite_flags); 00341 00342 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00343 { 00344 stream << dtn::data::SDNV(_correlator); 00345 } 00346 00347 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00348 { 00349 stream << _ciphersuite_params; 00350 } 00351 00352 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00353 { 00354 stream << _security_result; 00355 } 00356 00357 return stream; 00358 } 00359 00360 std::ostream& SecurityBlock::serialize_strict(std::ostream &stream, size_t &length) const 00361 { 00362 stream << dtn::data::SDNV(_ciphersuite_id) << dtn::data::SDNV(_ciphersuite_flags); 00363 00364 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00365 { 00366 stream << dtn::data::SDNV(_correlator); 00367 } 00368 00369 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00370 { 00371 stream << _ciphersuite_params; 00372 } 00373 00374 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00375 { 00376 stream << dtn::data::SDNV(getSecurityResultSize()); 00377 } 00378 00379 return stream; 00380 } 00381 00382 std::istream& SecurityBlock::deserialize(std::istream &stream, const size_t length) 00383 { 00384 #ifdef __DEVELOPMENT_ASSERTIONS__ 00385 // recheck blocktype. if blocktype is set wrong, this will be a huge fail 00386 assert(_blocktype == BUNDLE_AUTHENTICATION_BLOCK || _blocktype == PAYLOAD_INTEGRITY_BLOCK || _blocktype == PAYLOAD_CONFIDENTIAL_BLOCK || _blocktype == EXTENSION_SECURITY_BLOCK); 00387 #endif 00388 00389 dtn::data::SDNV ciphersuite_id, ciphersuite_flags; 00390 stream >> ciphersuite_id >> ciphersuite_flags; 00391 _ciphersuite_id = ciphersuite_id.getValue(); 00392 _ciphersuite_flags = ciphersuite_flags.getValue(); 00393 00394 #ifdef __DEVELOPMENT_ASSERTIONS__ 00395 // recheck ciphersuite_id 00396 assert(_ciphersuite_id == BAB_HMAC || _ciphersuite_id == PIB_RSA_SHA256 || _ciphersuite_id == PCB_RSA_AES128_PAYLOAD_PIB_PCB || _ciphersuite_id == ESB_RSA_AES128_EXT); 00397 // recheck ciphersuite_flags, could be more exhaustive 00398 assert(_ciphersuite_flags < 32); 00399 #endif 00400 00401 // copy security source and destination 00402 if (_ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_SOURCE) 00403 { 00404 if (_eids.size() == 0) 00405 throw dtn::SerializationFailedException("ciphersuite flags indicate a security source, but it is not present"); 00406 00407 _security_source = _eids.front(); 00408 } 00409 00410 if (_ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_DESTINATION) 00411 { 00412 if (_ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_SOURCE) 00413 { 00414 if (_eids.size() < 2) 00415 throw dtn::SerializationFailedException("ciphersuite flags indicate a security destination, but it is not present"); 00416 00417 _security_destination = (*(_eids.begin())++); 00418 } 00419 else 00420 { 00421 if (_eids.size() == 0) 00422 throw dtn::SerializationFailedException("ciphersuite flags indicate a security destination, but it is not present"); 00423 00424 _security_destination = _eids.front(); 00425 } 00426 } 00427 00428 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00429 { 00430 dtn::data::SDNV correlator; 00431 stream >> correlator; 00432 _correlator = correlator.getValue(); 00433 } 00434 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00435 { 00436 stream >> _ciphersuite_params; 00437 #ifdef __DEVELOPMENT_ASSERTIONS__ 00438 assert(_ciphersuite_params.getLength() > 0); 00439 #endif 00440 } 00441 00442 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00443 { 00444 stream >> _security_result; 00445 #ifdef __DEVELOPMENT_ASSERTIONS__ 00446 assert(_security_result.getLength() > 0); 00447 #endif 00448 } 00449 00450 return stream; 00451 } 00452 00453 dtn::security::MutualSerializer& SecurityBlock::serialize_mutable(dtn::security::MutualSerializer &serializer) const 00454 { 00455 serializer << dtn::data::SDNV(_ciphersuite_id); 00456 serializer << dtn::data::SDNV(_ciphersuite_flags); 00457 00458 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00459 serializer << dtn::data::SDNV(_ciphersuite_flags); 00460 00461 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00462 { 00463 serializer << _ciphersuite_params; 00464 } 00465 00466 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00467 { 00468 serializer << _security_result; 00469 } 00470 00471 return serializer; 00472 } 00473 00474 dtn::security::MutualSerializer& SecurityBlock::serialize_mutable_without_security_result(dtn::security::MutualSerializer &serializer) const 00475 { 00476 serializer << dtn::data::SDNV(_ciphersuite_id); 00477 serializer << dtn::data::SDNV(_ciphersuite_flags); 00478 00479 if (_ciphersuite_flags & CONTAINS_CORRELATOR) 00480 serializer << dtn::data::SDNV(_ciphersuite_flags); 00481 00482 if (_ciphersuite_flags & CONTAINS_CIPHERSUITE_PARAMS) 00483 { 00484 serializer << _ciphersuite_params; 00485 } 00486 00487 if (_ciphersuite_flags & CONTAINS_SECURITY_RESULT) 00488 { 00489 serializer << dtn::data::SDNV(getSecurityResultSize()); 00490 } 00491 00492 return serializer; 00493 } 00494 00495 size_t SecurityBlock::getSecurityResultSize() const 00496 { 00497 #ifdef __DEVELOPMENT_ASSERTIONS__ 00498 assert(_security_result.getLength() != 0); 00499 #endif 00500 return _security_result.getLength(); 00501 } 00502 00503 void SecurityBlock::createSaltAndKey(u_int32_t& salt, unsigned char* key, size_t key_size) 00504 { 00505 00506 if (!RAND_bytes(reinterpret_cast<unsigned char *>(&salt), sizeof(u_int32_t))) 00507 { 00508 IBRCOMMON_LOGGER_ex(critical) << "failed to generate salt. maybe /dev/urandom is missing for seeding the PRNG" << IBRCOMMON_LOGGER_ENDL; 00509 ERR_print_errors_fp(stderr); 00510 } 00511 if (!RAND_bytes(key, key_size)) 00512 { 00513 IBRCOMMON_LOGGER_ex(critical) << "failed to generate key. maybe /dev/urandom is missing for seeding the PRNG" << IBRCOMMON_LOGGER_ENDL; 00514 ERR_print_errors_fp(stderr); 00515 } 00516 } 00517 00518 void SecurityBlock::addKey(TLVList& security_parameter, unsigned char const * const key, size_t key_size, RSA * rsa) 00519 { 00520 // encrypt the ephemeral key and place it in _ciphersuite_params 00521 #ifdef __DEVELOPMENT_ASSERTIONS__ 00522 assert(key_size < RSA_size(rsa)-41); 00523 #endif 00524 unsigned char encrypted_key[RSA_size(rsa)]; 00525 int encrypted_key_len = RSA_public_encrypt(key_size, key, encrypted_key, rsa, RSA_PKCS1_OAEP_PADDING); 00526 if (encrypted_key_len == -1) 00527 { 00528 IBRCOMMON_LOGGER_ex(critical) << "failed to encrypt the symmetric AES key" << IBRCOMMON_LOGGER_ENDL; 00529 ERR_print_errors_fp(stderr); 00530 } 00531 security_parameter.set(SecurityBlock::key_information, std::string(reinterpret_cast<char *>(encrypted_key), encrypted_key_len)); 00532 } 00533 00534 bool SecurityBlock::getKey(const TLVList& security_parameter, unsigned char * key, size_t key_size, RSA * rsa) 00535 { 00536 std::string key_string = security_parameter.get(SecurityBlock::key_information); 00537 // get key, convert with reinterpret_cast 00538 unsigned char const * encrypted_key = reinterpret_cast<const unsigned char*>(key_string.c_str()); 00539 unsigned char the_key[RSA_size(rsa)]; 00540 RSA_blinding_on(rsa, NULL); 00541 int plaintext_key_len = RSA_private_decrypt(key_string.size(), encrypted_key, the_key, rsa, RSA_PKCS1_OAEP_PADDING); 00542 RSA_blinding_off(rsa); 00543 if (plaintext_key_len == -1) 00544 { 00545 IBRCOMMON_LOGGER_ex(critical) << "failed to decrypt the symmetric AES key" << IBRCOMMON_LOGGER_ENDL; 00546 ERR_print_errors_fp(stderr); 00547 return false; 00548 } 00549 #ifdef __DEVELOPMENT_ASSERTIONS__ 00550 assert(plaintext_key_len == key_size); 00551 #endif 00552 std::copy(the_key, the_key+key_size, key); 00553 return true; 00554 } 00555 00556 void SecurityBlock::copyEID(const Block& from, Block& to, size_t skip) 00557 { 00558 // take eid list, getEIDList() is broken 00559 std::list<dtn::data::EID> their_eids = from.getEIDList(); 00560 std::list<dtn::data::EID>::iterator it = their_eids.begin(); 00561 00562 while (it != their_eids.end() && skip > 0) 00563 { 00564 skip--; 00565 it++; 00566 } 00567 00568 for (; it != their_eids.end(); it++) 00569 to.addEID(*it); 00570 } 00571 00572 void SecurityBlock::addSalt(TLVList& security_parameters, const u_int32_t &salt) 00573 { 00574 u_int32_t nsalt = htonl(salt); 00575 security_parameters.set(SecurityBlock::salt, (const unsigned char*)&nsalt, sizeof(nsalt)); 00576 } 00577 00578 u_int32_t SecurityBlock::getSalt(const TLVList& security_parameters) 00579 { 00580 u_int32_t nsalt = 0; 00581 security_parameters.get(SecurityBlock::salt, (unsigned char*)&nsalt, sizeof(nsalt)); 00582 return ntohl(nsalt); 00583 } 00584 00585 void SecurityBlock::decryptBlock(dtn::data::Bundle& bundle, const dtn::security::SecurityBlock &block, u_int32_t salt, const unsigned char key[ibrcommon::AES128Stream::key_size_in_bytes]) 00586 { 00587 // the array for the extracted tag 00588 unsigned char tag[ibrcommon::AES128Stream::tag_len]; 00589 00590 // the array for the extracted iv 00591 unsigned char iv[ibrcommon::AES128Stream::iv_len]; 00592 00593 // get iv, convert with reinterpret_cast 00594 block._ciphersuite_params.get(SecurityBlock::initialization_vector, iv, ibrcommon::AES128Stream::iv_len); 00595 00596 // get data and tag, the last tag_len bytes are the tag. cut them of and reinterpret_cast 00597 std::string block_data = block._security_result.get(SecurityBlock::encapsulated_block); 00598 00599 // create a pointer to the tag begin 00600 const char *tag_p = block_data.c_str() + (block_data.size() - ibrcommon::AES128Stream::tag_len); 00601 00602 // copy the tag 00603 ::memcpy(tag, tag_p, ibrcommon::AES128Stream::tag_len); 00604 00605 // strip off the tag from block data 00606 block_data.resize(block_data.size() - ibrcommon::AES128Stream::tag_len); 00607 00608 // decrypt block 00609 std::stringstream plaintext; 00610 ibrcommon::AES128Stream decrypt(ibrcommon::CipherStream::CIPHER_DECRYPT, plaintext, key, salt, iv); 00611 decrypt << block_data << std::flush; 00612 00613 // verify the decrypt tag 00614 if (!decrypt.verify(tag)) 00615 { 00616 throw ibrcommon::Exception("decryption of block failed - tag is bad"); 00617 } 00618 00619 // deserialize block 00620 dtn::data::DefaultDeserializer ddser(plaintext); 00621 00622 // peek the block type 00623 char block_type = plaintext.peek(); 00624 00625 if (block_type == dtn::data::PayloadBlock::BLOCK_TYPE) 00626 { 00627 dtn::data::PayloadBlock &plaintext_block = bundle.insert<dtn::data::PayloadBlock>(block); 00628 ddser >> plaintext_block; 00629 } 00630 else 00631 { 00632 try { 00633 dtn::data::ExtensionBlock::Factory &f = dtn::data::ExtensionBlock::Factory::get(block_type); 00634 dtn::data::Block &plaintext_block = bundle.insert(f, block); 00635 ddser >> plaintext_block; 00636 00637 plaintext_block.getEIDList().clear(); 00638 00639 // copy eids 00640 // remove security_source and destination 00641 size_t skip = 0; 00642 if (block._ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_DESTINATION) 00643 skip++; 00644 if (block._ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_SOURCE) 00645 skip++; 00646 copyEID(plaintext_block, plaintext_block, skip); 00647 00648 } catch (const ibrcommon::Exception &ex) { 00649 dtn::data::ExtensionBlock &plaintext_block = bundle.insert<dtn::data::ExtensionBlock>(block); 00650 ddser >> plaintext_block; 00651 00652 plaintext_block.getEIDList().clear(); 00653 00654 // copy eids 00655 // remove security_source and destination 00656 size_t skip = 0; 00657 if (block._ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_DESTINATION) 00658 skip++; 00659 if (block._ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_SOURCE) 00660 skip++; 00661 copyEID(plaintext_block, plaintext_block, skip); 00662 } 00663 } 00664 00665 bundle.remove(block); 00666 } 00667 00668 void SecurityBlock::addFragmentRange(TLVList& ciphersuite_params, size_t fragmentoffset, size_t payload_length) 00669 { 00670 dtn::data::SDNV offset(fragmentoffset); 00671 dtn::data::SDNV range_sdnv(payload_length); 00672 00673 std::stringstream ss; 00674 ss << offset << range_sdnv; 00675 00676 ciphersuite_params.set(SecurityBlock::fragment_range, ss.str()); 00677 } 00678 00679 bool SecurityBlock::isSecuritySource(const dtn::data::Bundle& bundle, const dtn::data::EID& eid) const 00680 { 00681 IBRCOMMON_LOGGER_DEBUG(30) << "check security source: " << getSecuritySource(bundle).getString() << " == " << eid.getNode().getString() << IBRCOMMON_LOGGER_ENDL; 00682 return getSecuritySource(bundle) == eid.getNode(); 00683 } 00684 00685 bool SecurityBlock::isSecurityDestination(const dtn::data::Bundle& bundle, const dtn::data::EID& eid) const 00686 { 00687 IBRCOMMON_LOGGER_DEBUG(30) << "check security destination: " << getSecurityDestination(bundle).getString() << " == " << eid.getNode().getString() << IBRCOMMON_LOGGER_ENDL; 00688 return getSecurityDestination(bundle) == eid.getNode(); 00689 } 00690 00691 const dtn::data::EID SecurityBlock::getSecuritySource(const dtn::data::Bundle& bundle) const 00692 { 00693 dtn::data::EID source = getSecuritySource(); 00694 if (source == dtn::data::EID()) 00695 source = bundle._source.getNode(); 00696 return source; 00697 } 00698 00699 const dtn::data::EID SecurityBlock::getSecurityDestination(const dtn::data::Bundle& bundle) const 00700 { 00701 dtn::data::EID destination = getSecurityDestination(); 00702 if (destination == dtn::data::EID()) 00703 destination = bundle._destination.getNode(); 00704 return destination; 00705 } 00706 } 00707 }