IBR-DTNSuite
0.8
|
00001 #include "security/SecurityManager.h" 00002 #include "security/SecurityKeyManager.h" 00003 #include "core/BundleCore.h" 00004 #include "routing/QueueBundleEvent.h" 00005 #include <ibrcommon/Logger.h> 00006 00007 #include <openssl/rsa.h> 00008 #include <openssl/pem.h> 00009 #include <openssl/err.h> 00010 00011 #ifdef __DEVELOPMENT_ASSERTIONS__ 00012 #include <cassert> 00013 #endif 00014 00015 namespace dtn 00016 { 00017 namespace security 00018 { 00019 SecurityManager& SecurityManager::getInstance() 00020 { 00021 static SecurityManager sec_man; 00022 return sec_man; 00023 } 00024 00025 SecurityManager::SecurityManager() 00026 : _accept_only_bab(false), _accept_only_pib(false) 00027 { 00028 } 00029 00030 SecurityManager::~SecurityManager() 00031 { 00032 } 00033 00034 void SecurityManager::auth(dtn::data::Bundle &bundle) const throw (KeyMissingException) 00035 { 00036 IBRCOMMON_LOGGER_DEBUG(10) << "auth bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00037 00038 try { 00039 // try to load the local key 00040 const SecurityKey key = SecurityKeyManager::getInstance().get(dtn::core::BundleCore::local, SecurityKey::KEY_SHARED); 00041 00042 // sign the bundle with BABs 00043 dtn::security::BundleAuthenticationBlock::auth(bundle, key); 00044 } catch (const SecurityKeyManager::KeyNotFoundException &ex) { 00045 throw KeyMissingException(ex.what()); 00046 } 00047 } 00048 00049 void SecurityManager::sign(dtn::data::Bundle &bundle) const throw (KeyMissingException) 00050 { 00051 IBRCOMMON_LOGGER_DEBUG(10) << "sign bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00052 00053 try { 00054 // try to load the local key 00055 const SecurityKey key = SecurityKeyManager::getInstance().get(dtn::core::BundleCore::local, SecurityKey::KEY_PRIVATE); 00056 00057 // sign the bundle with PIB 00058 dtn::security::PayloadIntegrityBlock::sign(bundle, key, bundle._destination.getNode()); 00059 } catch (const SecurityKeyManager::KeyNotFoundException &ex) { 00060 throw KeyMissingException(ex.what()); 00061 } 00062 } 00063 00064 void SecurityManager::prefetchKey(const dtn::data::EID &eid) 00065 { 00066 IBRCOMMON_LOGGER_DEBUG(10) << "prefetch key for: " << eid.getString() << IBRCOMMON_LOGGER_ENDL; 00067 00068 // prefetch the key for this EID 00069 SecurityKeyManager::getInstance().prefetchKey(eid, SecurityKey::KEY_PUBLIC); 00070 } 00071 00072 void SecurityManager::verify(dtn::data::Bundle &bundle) const throw (VerificationFailedException) 00073 { 00074 verifyBAB(bundle); 00075 verifyPIB(bundle); 00076 } 00077 00078 void SecurityManager::verifyPIB(dtn::data::Bundle &bundle) const throw (VerificationFailedException) 00079 { 00080 IBRCOMMON_LOGGER_DEBUG(10) << "verify signed bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00081 00082 // get all PIBs of this bundle 00083 std::list<const dtn::security::PayloadIntegrityBlock*> pibs = bundle.getBlocks<dtn::security::PayloadIntegrityBlock>(); 00084 00085 for (std::list<const dtn::security::PayloadIntegrityBlock*>::iterator it = pibs.begin(); it != pibs.end(); it++) 00086 { 00087 const dtn::security::PayloadIntegrityBlock& pib = (**it); 00088 00089 try { 00090 const SecurityKey key = SecurityKeyManager::getInstance().get(pib.getSecuritySource(bundle), SecurityKey::KEY_PUBLIC); 00091 00092 if (pib.isSecurityDestination(bundle, dtn::core::BundleCore::local)) 00093 { 00094 try { 00095 dtn::security::PayloadIntegrityBlock::strip(bundle, key); 00096 00097 // set the verify bit, after verification 00098 bundle.set(dtn::data::Bundle::DTNSEC_STATUS_VERIFIED, true); 00099 00100 IBRCOMMON_LOGGER_DEBUG(5) << "Bundle from " << bundle._source.getString() << " successfully verified using PayloadIntegrityBlock" << IBRCOMMON_LOGGER_ENDL; 00101 return; 00102 } catch (const ibrcommon::Exception&) { 00103 throw VerificationFailedException(); 00104 } 00105 } 00106 else 00107 { 00108 try { 00109 dtn::security::PayloadIntegrityBlock::verify(bundle, key); 00110 00111 // set the verify bit, after verification 00112 bundle.set(dtn::data::Bundle::DTNSEC_STATUS_VERIFIED, true); 00113 00114 IBRCOMMON_LOGGER_DEBUG(5) << "Bundle from " << bundle._source.getString() << " successfully verified using PayloadIntegrityBlock" << IBRCOMMON_LOGGER_ENDL; 00115 } catch (const ibrcommon::Exception&) { 00116 throw VerificationFailedException(); 00117 } 00118 } 00119 } catch (const ibrcommon::Exception&) { 00120 // key not found? 00121 } 00122 } 00123 } 00124 00125 void SecurityManager::verifyBAB(dtn::data::Bundle &bundle) const throw (VerificationFailedException) 00126 { 00127 IBRCOMMON_LOGGER_DEBUG(10) << "verify authenticated bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00128 00129 // get all BABs of this bundle 00130 std::list <const dtn::security::BundleAuthenticationBlock* > babs = bundle.getBlocks<dtn::security::BundleAuthenticationBlock>(); 00131 00132 for (std::list <const dtn::security::BundleAuthenticationBlock* >::iterator it = babs.begin(); it != babs.end(); it++) 00133 { 00134 const dtn::security::BundleAuthenticationBlock& bab = (**it); 00135 00136 // look for the right BAB-factory 00137 const dtn::data::EID node = bab.getSecuritySource(bundle); 00138 00139 try { 00140 // try to load the key of the BAB 00141 const SecurityKey key = SecurityKeyManager::getInstance().get(node, SecurityKey::KEY_SHARED); 00142 00143 // verify the bundle 00144 dtn::security::BundleAuthenticationBlock::verify(bundle, key); 00145 00146 // strip all BAB of this bundle 00147 dtn::security::BundleAuthenticationBlock::strip(bundle); 00148 00149 // set the verify bit, after verification 00150 bundle.set(dtn::data::Bundle::DTNSEC_STATUS_AUTHENTICATED, true); 00151 00152 // at least one BAB has been authenticated, we're done! 00153 break; 00154 } catch (const SecurityKeyManager::KeyNotFoundException&) { 00155 // no key for this node found 00156 } catch (const ibrcommon::Exception &ex) { 00157 // verification failed 00158 throw SecurityManager::VerificationFailedException(ex.what()); 00159 } 00160 } 00161 } 00162 00163 void SecurityManager::fastverify(const dtn::data::Bundle &bundle) const throw (VerificationFailedException) 00164 { 00165 // do a fast verify without manipulating the bundle 00166 const dtn::daemon::Configuration::Security &secconf = dtn::daemon::Configuration::getInstance().getSecurity(); 00167 00168 if (secconf.getLevel() & dtn::daemon::Configuration::Security::SECURITY_LEVEL_ENCRYPTED) 00169 { 00170 // check if the bundle is encrypted and throw an exception if not 00171 //throw VerificationFailedException("Bundle is not encrypted"); 00172 IBRCOMMON_LOGGER_DEBUG(10) << "encryption required, verify bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00173 00174 const std::list<const dtn::security::PayloadConfidentialBlock* > pcbs = bundle.getBlocks<dtn::security::PayloadConfidentialBlock>(); 00175 if (pcbs.size() == 0) throw VerificationFailedException("No PCB available!"); 00176 } 00177 00178 if (secconf.getLevel() & dtn::daemon::Configuration::Security::SECURITY_LEVEL_AUTHENTICATED) 00179 { 00180 // check if the bundle is signed and throw an exception if not 00181 //throw VerificationFailedException("Bundle is not signed"); 00182 IBRCOMMON_LOGGER_DEBUG(10) << "authentication required, verify bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00183 00184 const std::list<const dtn::security::BundleAuthenticationBlock* > babs = bundle.getBlocks<dtn::security::BundleAuthenticationBlock>(); 00185 if (babs.size() == 0) throw VerificationFailedException("No BAB available!"); 00186 } 00187 } 00188 00189 void SecurityManager::decrypt(dtn::data::Bundle &bundle) const throw (DecryptException, KeyMissingException) 00190 { 00191 // check if the bundle has to be decrypted, return when not 00192 if (bundle.getBlocks<dtn::security::PayloadConfidentialBlock>().size() <= 0) return; 00193 00194 // decrypt 00195 try { 00196 IBRCOMMON_LOGGER_DEBUG(10) << "decrypt bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00197 00198 // get the encryption key 00199 dtn::security::SecurityKey key = SecurityKeyManager::getInstance().get(dtn::core::BundleCore::local, dtn::security::SecurityKey::KEY_PRIVATE); 00200 00201 // encrypt the payload of the bundle 00202 dtn::security::PayloadConfidentialBlock::decrypt(bundle, key); 00203 00204 bundle.set(dtn::data::Bundle::DTNSEC_STATUS_CONFIDENTIAL, true); 00205 } catch (const ibrcommon::Exception &ex) { 00206 throw DecryptException(ex.what()); 00207 } 00208 } 00209 00210 void SecurityManager::encrypt(dtn::data::Bundle &bundle) const throw (EncryptException, KeyMissingException) 00211 { 00212 try { 00213 IBRCOMMON_LOGGER_DEBUG(10) << "encrypt bundle: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00214 00215 // get the encryption key 00216 dtn::security::SecurityKey key = SecurityKeyManager::getInstance().get(bundle._destination, dtn::security::SecurityKey::KEY_PUBLIC); 00217 00218 // encrypt the payload of the bundle 00219 dtn::security::PayloadConfidentialBlock::encrypt(bundle, key, dtn::core::BundleCore::local); 00220 } catch (const ibrcommon::Exception &ex) { 00221 throw EncryptException(ex.what()); 00222 } 00223 } 00224 } 00225 }