Go to the documentation of this file.00001 #include "ibrdtn/data/Bundle.h"
00002 #include "ibrdtn/security/BundleAuthenticationBlock.h"
00003 #include "ibrdtn/security/StrictSerializer.h"
00004 #include "ibrcommon/ssl/HMacStream.h"
00005 #include <ibrcommon/Logger.h>
00006 #include <cstring>
00007 #include <set>
00008
00009 #ifdef __DEVELOPMENT_ASSERTIONS__
00010 #include <cassert>
00011 #endif
00012
00013 namespace dtn
00014 {
00015 namespace security
00016 {
00017 dtn::data::Block* BundleAuthenticationBlock::Factory::create()
00018 {
00019 return new BundleAuthenticationBlock();
00020 }
00021
00022 BundleAuthenticationBlock::BundleAuthenticationBlock()
00023 : SecurityBlock(BUNDLE_AUTHENTICATION_BLOCK, BAB_HMAC)
00024 {
00025 }
00026
00027 BundleAuthenticationBlock::~BundleAuthenticationBlock()
00028 {
00029 }
00030
00031 void BundleAuthenticationBlock::auth(dtn::data::Bundle &bundle, const dtn::security::SecurityKey &key)
00032 {
00033 BundleAuthenticationBlock& bab_begin = bundle.push_front<BundleAuthenticationBlock>();
00034
00035
00036 if (key.reference != bundle._source.getNodeEID()) bab_begin.setSecuritySource( key.reference );
00037
00038 u_int64_t correlator = createCorrelatorValue(bundle);
00039 bab_begin.setCorrelator(correlator);
00040 bab_begin.setCiphersuiteId(BAB_HMAC);
00041
00042 BundleAuthenticationBlock& bab_end = bundle.push_back<BundleAuthenticationBlock>();
00043 bab_end.setCorrelator(correlator);
00044 bab_end._ciphersuite_flags |= CONTAINS_SECURITY_RESULT;
00045
00046 std::string sizehash_hash = calcMAC(bundle, key);
00047 bab_end._security_result.set(SecurityBlock::integrity_signature, sizehash_hash);
00048 }
00049
00050 void BundleAuthenticationBlock::verify(const dtn::data::Bundle &bundle, const dtn::security::SecurityKey &key) throw (ibrcommon::Exception)
00051 {
00052
00053 u_int64_t correlator;
00054
00055
00056 verify(bundle, key, correlator);
00057 }
00058
00059 void BundleAuthenticationBlock::strip(dtn::data::Bundle &bundle, const dtn::security::SecurityKey &key)
00060 {
00061
00062 u_int64_t correlator;
00063
00064
00065 verify(bundle, key, correlator);
00066
00067
00068 const std::list<const BundleAuthenticationBlock *> babs = bundle.getBlocks<BundleAuthenticationBlock>();
00069
00070 for (std::list<const BundleAuthenticationBlock *>::const_iterator it = babs.begin(); it != babs.end(); it++)
00071 {
00072 const BundleAuthenticationBlock &bab = (**it);
00073
00074
00075 if ((bab._ciphersuite_flags & SecurityBlock::CONTAINS_CORRELATOR) && (bab._correlator == correlator))
00076 {
00077 bundle.remove(bab);
00078 }
00079 }
00080 }
00081
00082 void BundleAuthenticationBlock::strip(dtn::data::Bundle& bundle)
00083 {
00084
00085 const std::list<const BundleAuthenticationBlock *> babs = bundle.getBlocks<BundleAuthenticationBlock>();
00086
00087 for (std::list<const BundleAuthenticationBlock *>::const_iterator it = babs.begin(); it != babs.end(); it++)
00088 {
00089 bundle.remove(*(*it));
00090 }
00091 }
00092
00093 void BundleAuthenticationBlock::verify(const dtn::data::Bundle& bundle, const dtn::security::SecurityKey &key, u_int64_t &correlator) throw (ibrcommon::Exception)
00094 {
00095 std::list<const BundleAuthenticationBlock *> babs = bundle.getBlocks<BundleAuthenticationBlock>();
00096
00097
00098 std::set<u_int64_t> correlators;
00099
00100
00101 std::string our_hash_string = calcMAC(bundle, key);
00102
00103 for (std::list<const BundleAuthenticationBlock *>::const_iterator it = babs.begin(); it != babs.end(); it++)
00104 {
00105 const BundleAuthenticationBlock &bab = (**it);
00106
00107
00108 if (bab._ciphersuite_flags & CONTAINS_SECURITY_RESULT)
00109 {
00110
00111 if (correlators.find(bab._correlator) == correlators.end()) continue;
00112
00113 std::string bab_result = bab._security_result.get(SecurityBlock::integrity_signature);
00114 if (our_hash_string == bab_result)
00115 {
00116
00117 correlator = bab._correlator;
00118 return;
00119 }
00120
00121 IBRCOMMON_LOGGER_DEBUG(15) << "security mac does not match" << IBRCOMMON_LOGGER_ENDL;
00122 }
00123
00124 else if (bab._ciphersuite_flags & CONTAINS_CORRELATOR)
00125 {
00126
00127 if (bab._ciphersuite_id != SecurityBlock::BAB_HMAC) continue;
00128
00129
00130 if (!bab.isSecuritySource(bundle, key.reference)) continue;
00131
00132
00133 correlators.insert(bab._correlator);
00134 }
00135 }
00136
00137 throw ibrcommon::Exception("verification failed");
00138 }
00139
00140 std::string BundleAuthenticationBlock::calcMAC(const dtn::data::Bundle& bundle, const dtn::security::SecurityKey &key, const bool with_correlator, const u_int64_t correlator)
00141 {
00142 std::string hmac_key = key.getData();
00143 ibrcommon::HMacStream hms((const unsigned char*)hmac_key.c_str(), hmac_key.length());
00144 dtn::security::StrictSerializer ss(hms, BUNDLE_AUTHENTICATION_BLOCK, with_correlator, correlator);
00145 ss << bundle;
00146 hms << std::flush;
00147
00148 return ibrcommon::HashStream::extract(hms);
00149 }
00150
00151 size_t BundleAuthenticationBlock::getSecurityResultSize() const
00152 {
00153
00154 size_t size = 1;
00155
00156 size += dtn::data::SDNV::getLength(EVP_MD_size(EVP_sha1()));
00157
00158 size += EVP_MD_size(EVP_sha1());
00159 return size;
00160 }
00161
00162 }
00163 }