void SecurityManager::verifyPIB(dtn::data::Bundle &bundle) const throw (VerificationFailedException) { IBRCOMMON_LOGGER_DEBUG_TAG("SecurityManager", 10) << "verify signed bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; // iterate through all blocks for (dtn::data::Bundle::iterator it = bundle.begin(); it != bundle.end();) { const dtn::data::Block &block = (**it); if (block.getType() == dtn::security::PayloadConfidentialBlock::BLOCK_TYPE) { // payload after a PCB can not verified until the payload is decrypted break; } try { const dtn::security::PayloadIntegrityBlock& pib = dynamic_cast<const dtn::security::PayloadIntegrityBlock&>(block); const SecurityKey key = SecurityKeyManager::getInstance().get(pib.getSecuritySource(bundle), SecurityKey::KEY_PUBLIC); // try to verify the bundle with the key for the current PIB dtn::security::PayloadIntegrityBlock::verify(bundle, key); // if we are the security destination if (pib.isSecurityDestination(bundle, dtn::core::BundleCore::local)) { // remove the valid PIB bundle.erase(it++); } else { ++it; } // set the verify bit, after verification bundle.set(dtn::data::PrimaryBlock::DTNSEC_STATUS_VERIFIED, true); IBRCOMMON_LOGGER_DEBUG_TAG("SecurityManager", 5) << "Bundle " << bundle.toString() << " successfully verified" << IBRCOMMON_LOGGER_ENDL; continue; } catch (const dtn::security::VerificationSkippedException&) { // un-set the verify bit bundle.set(dtn::data::PrimaryBlock::DTNSEC_STATUS_VERIFIED, false); } catch (const SecurityKey::KeyNotFoundException&) { // un-set the verify bit bundle.set(dtn::data::PrimaryBlock::DTNSEC_STATUS_VERIFIED, false); } catch (const std::bad_cast&) { // current block is not a PIB } ++it; } }
void SecurityManager::verifyBAB(dtn::data::Bundle &bundle) const throw (VerificationFailedException) { IBRCOMMON_LOGGER_DEBUG_TAG("SecurityManager", 10) << "verify authenticated bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; // iterate over all BABs of this bundle dtn::data::Bundle::find_iterator it(bundle.begin(), dtn::security::BundleAuthenticationBlock::BLOCK_TYPE); while (it.next(bundle.end())) { const dtn::security::BundleAuthenticationBlock& bab = dynamic_cast<const dtn::security::BundleAuthenticationBlock&>(**it); // look for the right BAB-factory const dtn::data::EID node = bab.getSecuritySource(bundle); try { // try to load the key of the BAB const SecurityKey key = SecurityKeyManager::getInstance().get(node, SecurityKey::KEY_SHARED); // verify the bundle dtn::security::BundleAuthenticationBlock::verify(bundle, key); // strip all BAB of this bundle dtn::security::BundleAuthenticationBlock::strip(bundle); // set the verify bit, after verification bundle.set(dtn::data::Bundle::DTNSEC_STATUS_AUTHENTICATED, true); // at least one BAB has been authenticated, we're done! break; } catch (const SecurityKey::KeyNotFoundException&) { // no key for this node found } } }
void SecurityManager::decrypt(dtn::data::Bundle &bundle) const throw (DecryptException, KeyMissingException) { // check if the bundle has to be decrypted, return when not if (std::count(bundle.begin(), bundle.end(), dtn::security::PayloadConfidentialBlock::BLOCK_TYPE) <= 0) return; // decrypt try { IBRCOMMON_LOGGER_DEBUG_TAG("SecurityManager", 10) << "decrypt bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; // get the encryption key dtn::security::SecurityKey key = SecurityKeyManager::getInstance().get(dtn::core::BundleCore::local, dtn::security::SecurityKey::KEY_PRIVATE); // encrypt the payload of the bundle dtn::security::PayloadConfidentialBlock::decrypt(bundle, key); bundle.set(dtn::data::Bundle::DTNSEC_STATUS_CONFIDENTIAL, true); } catch (const ibrcommon::Exception &ex) { throw DecryptException(ex.what()); } }
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); }