void PayloadIntegrityBlock::sign(dtn::data::Bundle &bundle, const SecurityKey &key, const dtn::data::EID& destination) { PayloadIntegrityBlock& pib = bundle.push_front<PayloadIntegrityBlock>(); pib.set(REPLICATE_IN_EVERY_FRAGMENT, true); // check if this is a fragment if (bundle.get(dtn::data::PrimaryBlock::FRAGMENT)) { dtn::data::PayloadBlock& plb = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference blobref = plb.getBLOB(); ibrcommon::BLOB::iostream stream = blobref.iostream(); addFragmentRange(pib._ciphersuite_params, bundle.fragmentoffset, stream.size()); } // set the source and destination address of the new block if (!key.reference.sameHost(bundle.source)) pib.setSecuritySource( key.reference ); if (!destination.sameHost(bundle.destination)) pib.setSecurityDestination( destination ); pib.setResultSize(key); pib.setCiphersuiteId(SecurityBlock::PIB_RSA_SHA256); pib._ciphersuite_flags |= CONTAINS_SECURITY_RESULT; std::string sign = calcHash(bundle, key, pib); pib._security_result.set(SecurityBlock::integrity_signature, sign); }
void Registration::processIncomingBundle(const dtn::data::EID &source, dtn::data::Bundle &bundle) { // check address fields for "api:me", this has to be replaced static const dtn::data::EID clienteid("api:me"); // set the source address to the sending EID bundle.source = source; if (bundle.destination == clienteid) bundle.destination = source; if (bundle.reportto == clienteid) bundle.reportto = source; if (bundle.custodian == clienteid) bundle.custodian = source; // if the timestamp is not set, add a ageblock if (bundle.timestamp == 0) { // check for ageblock try { bundle.find<dtn::data::AgeBlock>(); } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) { // add a new ageblock bundle.push_front<dtn::data::AgeBlock>(); } } // modify TrackingBlock try { dtn::data::TrackingBlock &track = bundle.find<dtn::data::TrackingBlock>(); track.append(dtn::core::BundleCore::local); } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) { }; #ifdef WITH_COMPRESSION // if the compression bit is set, then compress the bundle if (bundle.get(dtn::data::PrimaryBlock::IBRDTN_REQUEST_COMPRESSION)) { try { dtn::data::CompressedPayloadBlock::compress(bundle, dtn::data::CompressedPayloadBlock::COMPRESSION_ZLIB); } catch (const ibrcommon::Exception &ex) { IBRCOMMON_LOGGER_TAG(Registration::TAG, warning) << "compression of bundle failed: " << ex.what() << IBRCOMMON_LOGGER_ENDL; }; } #endif #ifdef WITH_BUNDLE_SECURITY // if the encrypt bit is set, then try to encrypt the bundle if (bundle.get(dtn::data::PrimaryBlock::DTNSEC_REQUEST_ENCRYPT)) { try { dtn::security::SecurityManager::getInstance().encrypt(bundle); bundle.set(dtn::data::PrimaryBlock::DTNSEC_REQUEST_ENCRYPT, false); } catch (const dtn::security::SecurityManager::KeyMissingException&) { // sign requested, but no key is available IBRCOMMON_LOGGER_TAG(Registration::TAG, warning) << "No key available for encrypt process." << IBRCOMMON_LOGGER_ENDL; } catch (const dtn::security::SecurityManager::EncryptException&) { IBRCOMMON_LOGGER_TAG(Registration::TAG, warning) << "Encryption of bundle failed." << IBRCOMMON_LOGGER_ENDL; } } // if the sign bit is set, then try to sign the bundle if (bundle.get(dtn::data::PrimaryBlock::DTNSEC_REQUEST_SIGN)) { try { dtn::security::SecurityManager::getInstance().sign(bundle); bundle.set(dtn::data::PrimaryBlock::DTNSEC_REQUEST_SIGN, false); } catch (const dtn::security::SecurityManager::KeyMissingException&) { // sign requested, but no key is available IBRCOMMON_LOGGER_TAG(Registration::TAG, warning) << "No key available for sign process." << IBRCOMMON_LOGGER_ENDL; } } #endif // get the payload size maximum size_t maxPayloadLength = dtn::daemon::Configuration::getInstance().getLimit("payload"); // check if fragmentation is enabled // do not try pro-active fragmentation if the payload length is not limited if (dtn::daemon::Configuration::getInstance().getNetwork().doFragmentation() && (maxPayloadLength > 0)) { try { std::list<dtn::data::Bundle> fragments; dtn::core::FragmentManager::split(bundle, maxPayloadLength, fragments); //for each fragment raise bundle received event for(std::list<dtn::data::Bundle>::iterator it = fragments.begin(); it != fragments.end(); ++it) { // raise default bundle received event dtn::net::BundleReceivedEvent::raise(source, *it, true); } return; } catch (const FragmentationProhibitedException&) { } catch (const FragmentationNotNecessaryException&) { } catch (const FragmentationAbortedException&) { // drop the bundle return; } } // raise default bundle received event dtn::net::BundleReceivedEvent::raise(source, bundle, true); }
void PayloadConfidentialBlock::encrypt(dtn::data::Bundle& bundle, const dtn::security::SecurityKey &long_key, const dtn::data::EID& source) { // contains the random salt uint32_t salt; // contains the random key unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes]; unsigned char iv[ibrcommon::AES128Stream::iv_len]; unsigned char tag[ibrcommon::AES128Stream::tag_len]; // create a new correlator value dtn::data::Number correlator = createCorrelatorValue(bundle); // create a random salt and key createSaltAndKey(salt, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes); // count all PCBs dtn::data::Size pcbs_size = std::count(bundle.begin(), bundle.end(), PayloadConfidentialBlock::BLOCK_TYPE); // count all PIBs dtn::data::Size pibs_size = std::count(bundle.begin(), bundle.end(), PayloadIntegrityBlock::BLOCK_TYPE); // encrypt PCBs and PIBs dtn::data::Bundle::find_iterator find_pcb(bundle.begin(), PayloadConfidentialBlock::BLOCK_TYPE); while (find_pcb.next(bundle.end())) { SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pcb, salt, ephemeral_key).setCorrelator(correlator); } dtn::data::Bundle::find_iterator find_pib(bundle.begin(), PayloadIntegrityBlock::BLOCK_TYPE); while (find_pib.next(bundle.end())) { SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pib, salt, ephemeral_key).setCorrelator(correlator); } // create a new payload confidential block PayloadConfidentialBlock& pcb = bundle.push_front<PayloadConfidentialBlock>(); // set the correlator if (pcbs_size > 0 || pibs_size > 0) pcb.setCorrelator(correlator); // get reference to the payload block dtn::data::PayloadBlock& plb = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference blobref = plb.getBLOB(); // encrypt payload - BEGIN { ibrcommon::BLOB::iostream stream = blobref.iostream(); ibrcommon::AES128Stream aes_stream(ibrcommon::CipherStream::CIPHER_ENCRYPT, *stream, ephemeral_key, salt); // encrypt in place ((ibrcommon::CipherStream&)aes_stream).encrypt(*stream); // check if this is a fragment if (bundle.get(dtn::data::PrimaryBlock::FRAGMENT)) { // ... and set the corresponding cipher suit params addFragmentRange(pcb._ciphersuite_params, bundle.fragmentoffset, stream.size()); } // get the IV aes_stream.getIV(iv); // get the tag aes_stream.getTag(tag); } // encrypt payload - END // set the source and destination address of the new block if (source != bundle.source.getNode()) pcb.setSecuritySource( source ); if (long_key.reference != bundle.destination.getNode()) pcb.setSecurityDestination( long_key.reference ); // set replicate in every fragment to true pcb.set(REPLICATE_IN_EVERY_FRAGMENT, true); // store encypted key, tag, iv and salt addSalt(pcb._ciphersuite_params, salt); // get the RSA key RSA *rsa_key = long_key.getRSA(); // encrypt the random key and add it to the ciphersuite params addKey(pcb._ciphersuite_params, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes, rsa_key); // free the RSA key long_key.free(rsa_key); pcb._ciphersuite_params.set(SecurityBlock::initialization_vector, iv, ibrcommon::AES128Stream::iv_len); pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_CIPHERSUITE_PARAMS; pcb._security_result.set(SecurityBlock::PCB_integrity_check_value, tag, ibrcommon::AES128Stream::tag_len); pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_RESULT; }