IBR-DTNSuite  0.10
BundleAuthenticationBlock.cpp
Go to the documentation of this file.
1 /*
2  * BundleAuthenticationBlock.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "ibrdtn/data/Bundle.h"
26 #include <ibrcommon/Logger.h>
27 #include <cstring>
28 #include <set>
29 #include <algorithm>
30 
31 #ifdef __DEVELOPMENT_ASSERTIONS__
32 #include <cassert>
33 #endif
34 
35 namespace dtn
36 {
37  namespace security
38  {
40 
42  {
43  return new BundleAuthenticationBlock();
44  }
45 
48  {
49  }
50 
52  {
53  }
54 
56  {
59 
60  // set security source
61  if (key.reference != bundle.source.getNode()) bab_begin.setSecuritySource( key.reference );
62 
63  dtn::data::Number correlator = createCorrelatorValue(bundle);
64  bab_begin.setCorrelator(correlator);
65  bab_begin.setCiphersuiteId(BAB_HMAC);
66 
69 
70  bab_end.setCorrelator(correlator);
72 
73  std::string sizehash_hash = calcMAC(bundle, key);
75  }
76 
78  {
79  // store the correlator of the verified BABs
80  dtn::data::Number correlator;
81 
82  // verify the babs of the bundle
83  verify(bundle, key, correlator);
84  }
85 
87  {
88  // store the correlator of the verified BABs
89  dtn::data::Number correlator;
90 
91  // verify the babs of the bundle
92  verify(bundle, key, correlator);
93 
94  // iterate over all BABs
96  while (it.next(bundle.end()))
97  {
98  const BundleAuthenticationBlock &bab = dynamic_cast<const BundleAuthenticationBlock&>(**it);
99 
100  // if the correlator is already authenticated, then remove the BAB
101  if ((bab._ciphersuite_flags & SecurityBlock::CONTAINS_CORRELATOR) && (bab._correlator == correlator))
102  {
103  bundle.erase(it);
104  }
105  }
106  }
107 
109  {
110  bundle.erase(std::remove(bundle.begin(), bundle.end(), BundleAuthenticationBlock::BLOCK_TYPE), bundle.end());
111  }
112 
114  {
115  // get the blocks, with which the key should match
116  std::set<dtn::data::Number> correlators;
117 
118  // calculate the MAC of this bundle
119  std::string our_hash_string = calcMAC(bundle, key);
120 
122  while (it.next(bundle.end()))
123  {
124  const BundleAuthenticationBlock &bab = dynamic_cast<const BundleAuthenticationBlock&>(**it);
125 
126  // the bab contains a security result
127  if (bab._ciphersuite_flags & CONTAINS_SECURITY_RESULT)
128  {
129  // is this correlator known?
130  if (correlators.find(bab._correlator) == correlators.end()) continue;
131 
132  std::string bab_result = bab._security_result.get(SecurityBlock::integrity_signature);
133  if (our_hash_string == bab_result)
134  {
135  // hash matched
136  correlator = bab._correlator;
137  return;
138  }
139 
140  IBRCOMMON_LOGGER_DEBUG_TAG("BundleAuthenticationBlock", 15) << "security mac does not match" << IBRCOMMON_LOGGER_ENDL;
141  }
142  // bab contains no security result but a correlator
143  else if (bab._ciphersuite_flags & CONTAINS_CORRELATOR)
144  {
145  // currently we only support BAB_HMAC mechanism
146  if (bab._ciphersuite_id != SecurityBlock::BAB_HMAC) continue;
147 
148  // skip this BAB if the security source do not match the key
149  if (!bab.isSecuritySource(bundle, key.reference)) continue;
150 
151  // remember it for later check
152  correlators.insert(bab._correlator);
153  }
154  }
155 
156  throw ibrcommon::Exception("verification failed");
157  }
158 
159  std::string BundleAuthenticationBlock::calcMAC(const dtn::data::Bundle& bundle, const dtn::security::SecurityKey &key, const bool with_correlator, const dtn::data::Number &correlator)
160  {
161  std::string hmac_key = key.getData();
162  ibrcommon::HMacStream hms((const unsigned char*)hmac_key.c_str(), static_cast<int>(hmac_key.length()));
163  dtn::security::StrictSerializer ss(hms, BUNDLE_AUTHENTICATION_BLOCK, with_correlator, correlator);
164  (dtn::data::DefaultSerializer&)ss << bundle;
165  hms << std::flush;
166 
167  return ibrcommon::HashStream::extract(hms);
168  }
169 
171  {
172  // TLV type
173  dtn::data::Length size = 1;
174  // length of value length
175  size += dtn::data::Number(EVP_MD_size(EVP_sha1())).getLength();
176  // length of value
177  size += EVP_MD_size(EVP_sha1());
178  return size;
179  }
180 
181  }
182 }