IBR-DTNSuite  0.12
SecurityBlock.h
Go to the documentation of this file.
1 /*
2  * SecurityBlock.h
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 #ifndef SECURITYBLOCK_H_
23 #define SECURITYBLOCK_H_
24 
25 #include "ibrdtn/data/Block.h"
26 #include "ibrdtn/data/EID.h"
28 #include "ibrdtn/data/Bundle.h"
29 #include <ibrcommon/Exceptions.h>
30 #include <ibrcommon/ssl/AES128Stream.h> // TODO <-- this include sucks
31 #include <list>
32 #include <sys/types.h>
33 
34 // forward deklaration needed for struct RSA
35 struct rsa_st;
36 // forward deklaration of RSA object
37 typedef rsa_st RSA;
38 
39 namespace dtn
40 {
41  namespace security
42  {
44  {
45  public:
46  SecurityException(std::string what = "security has been violated") : ibrcommon::Exception(what)
47  {};
48 
49  virtual ~SecurityException() throw() {};
50  };
51 
53  {
54  public:
55  EncryptException(std::string what = "Encryption failed.") : SecurityException(what)
56  {};
57 
58  virtual ~EncryptException() throw() {};
59  };
60 
62  {
63  public:
64  DecryptException(std::string what = "Decryption failed.") : SecurityException(what)
65  {};
66 
67  virtual ~DecryptException() throw() {};
68  };
69 
71  {
72  public:
73  VerificationFailedException(std::string what = "Verification failed.") : SecurityException(what)
74  {};
75 
76  virtual ~VerificationFailedException() throw() {};
77  };
78 
80  {
81  public:
82  ElementMissingException(std::string what = "Requested element is missing.") : ibrcommon::Exception(what)
83  {};
84 
85  virtual ~ElementMissingException() throw() {};
86  };
87 
88  class MutableSerializer;
89  class StrictSerializer;
90 
105  {
106  friend class StrictSerializer;
107  friend class MutableSerializer;
108  public:
111  {
116  };
120  {
121  not_set = 0,
126  salt = 7,
130  };
133  {
139  BIT5_RESERVED = 1 << 5,
140  BIT6_RESERVED = 1 << 6
141  };
144  {
145  BAB_HMAC = 0x001,
146  PIB_RSA_SHA256 = 0x002,
149  };
150 
151  class TLV
152  {
153  public:
154  TLV() : _type(not_set) {};
155  TLV(TLV_TYPES type, std::string value)
156  : _type(type), _value(value)
157  { }
158 
159  bool operator<(const TLV &tlv) const;
160  bool operator==(const TLV &tlv) const;
161 
162  const std::string getValue() const;
163  TLV_TYPES getType() const;
165 
166  friend std::ostream& operator<<(std::ostream &stream, const TLV &tlv);
167  friend std::istream& operator>>(std::istream &stream, TLV &tlv);
168 
169  private:
170  TLV_TYPES _type;
172  };
173 
174  class TLVList : public std::set<TLV>
175  {
176  public:
177  TLVList() {};
178  virtual ~TLVList() {};
179 
180  friend std::ostream& operator<<(std::ostream &stream, const TLVList &tlvlist);
181  friend std::istream& operator>>(std::istream &stream, TLVList &tlvlist);
182 
183  const std::string get(TLV_TYPES type) const;
184  void get(TLV_TYPES type, unsigned char *value, dtn::data::Length length) const;
185  void set(TLV_TYPES type, std::string value);
186  void set(TLV_TYPES type, const unsigned char *value, dtn::data::Length length);
187  void remove(TLV_TYPES type);
188 
189  const std::string toString() const;
191 
192  private:
193  dtn::data::Length getPayloadLength() const;
194  };
195 
197  virtual ~SecurityBlock() = 0;
198 
203  virtual dtn::data::Length getLength() const;
204 
210  virtual dtn::data::Length getLength_mutable() const;
211 
217  virtual std::ostream &serialize(std::ostream &stream, dtn::data::Length &length) const;
218 
225  virtual std::ostream &serialize_strict(std::ostream &stream, dtn::data::Length &length) const;
226 
231  virtual std::istream &deserialize(std::istream &stream, const dtn::data::Length &length);
232 
236  const dtn::data::EID getSecuritySource() const;
237 
243 
248  void setSecuritySource(const dtn::data::EID &source);
249 
254  void setSecurityDestination(const dtn::data::EID &destination);
255 
262  bool isSecuritySource(const dtn::data::Bundle&, const dtn::data::EID&) const;
263 
270  bool isSecurityDestination(const dtn::data::Bundle&, const dtn::data::EID&) const;
271 
278 
285 
286  protected:
296 
300 
303 
306 
309 
312 
320 
327 
332  void setCiphersuiteId(const CIPHERSUITE_IDS id);
333 
338  void setCorrelator(const dtn::data::Number &corr);
339 
346  static bool isCorrelatorPresent(const dtn::data::Bundle &bundle, const dtn::data::Number &correlator);
347 
355 
361  virtual MutableSerializer &serialize_mutable(MutableSerializer &serializer, bool include_security_result = true) const;
362 
373 
380  static void createSaltAndKey(uint32_t& salt, unsigned char * key, dtn::data::Length key_size);
381 
392  static void addKey(TLVList& security_parameter, unsigned char const * const key, dtn::data::Length key_size, RSA * rsa);
393 
403  static bool getKey(const TLVList& security_parameter, unsigned char * key, dtn::data::Length key_size, RSA * rsa);
404 
410  static void addSalt(TLVList& security_parameters, const uint32_t &salt);
411 
416  static uint32_t getSalt(const TLVList& security_parameters);
417 
424  static void copyEID(const dtn::data::Block& from, dtn::data::Block& to, dtn::data::Length skip = 0);
425 
439  template <class T>
440  static T& encryptBlock(dtn::data::Bundle& bundle, dtn::data::Bundle::iterator &it, uint32_t salt, const unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes]);
441 
453  static void decryptBlock(dtn::data::Bundle& bundle, dtn::data::Bundle::iterator &it, uint32_t salt, const unsigned char key[ibrcommon::AES128Stream::key_size_in_bytes]);
454 
460  static void addFragmentRange(TLVList& ciphersuite_params, const dtn::data::Number &fragmentoffset, const dtn::data::Number &payload_length);
461 
462  private:
466  SecurityBlock& operator=(const SecurityBlock&);
467  };
468 
469  template <class T>
471  {
472  const dtn::data::Block &block = (**it);
473 
474  // insert ESB, block can be removed after encryption, because bundle will destroy it
475  T& esb = bundle.insert<T>(it);
476 
477  // take eid list
478  copyEID(block, esb);
479 
480  std::stringstream ss;
481  ibrcommon::AES128Stream encrypt(ibrcommon::CipherStream::CIPHER_ENCRYPT, ss, ephemeral_key, salt);
482  dtn::data::Dictionary dict(bundle);
483  dtn::data::DefaultSerializer dser(encrypt, dict);
484  dser << block;
485  encrypt << std::flush;
486 
487  // append tag at the end of the ciphertext
488  unsigned char tag[ibrcommon::AES128Stream::tag_len]; encrypt.getTag(tag);
489  ss.write((const char*)&tag, ibrcommon::AES128Stream::tag_len);
490 
491  esb._security_result.set(SecurityBlock::encapsulated_block, ss.str());
492  esb._ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_RESULT;
493 
494  unsigned char iv[ibrcommon::AES128Stream::iv_len]; encrypt.getIV(iv);
496 
497  esb._ciphersuite_flags |= SecurityBlock::CONTAINS_CIPHERSUITE_PARAMS;
498 
499  bundle.erase(it++);
500 
501  return esb;
502  }
503  }
504 }
505 
506 #endif /* SECURITYBLOCK_H_ */