IBR-DTNSuite  0.8
ibrdtn/ibrdtn/security/SecurityBlock.h
Go to the documentation of this file.
00001 #ifndef SECURITYBLOCK_H_
00002 #define SECURITYBLOCK_H_
00003 
00004 #include "ibrdtn/data/Block.h"
00005 #include "ibrdtn/data/EID.h"
00006 #include "ibrdtn/data/BundleString.h"
00007 #include "ibrdtn/data/Bundle.h"
00008 #include <ibrcommon/ssl/AES128Stream.h> // TODO <-- this include sucks
00009 #include <list>
00010 #include <sys/types.h>
00011 
00012 // forward deklaration needed for struct RSA
00013 struct rsa_st;
00014 // forward deklaration of RSA object
00015 typedef rsa_st RSA;
00016 
00017 namespace dtn
00018 {
00019         namespace security
00020         {
00034                 class SecurityBlock : public dtn::data::Block
00035                 {
00036                         friend class StrictSerializer;
00037                         friend class MutualSerializer;
00038                 public:
00040                         enum BLOCK_TYPES
00041                         {
00042                                 BUNDLE_AUTHENTICATION_BLOCK = 0x02,
00043                                 PAYLOAD_INTEGRITY_BLOCK = 0x03,
00044                                 PAYLOAD_CONFIDENTIAL_BLOCK = 0x04,
00045                                 EXTENSION_SECURITY_BLOCK = 0x09
00046                         };
00049                         enum TLV_TYPES
00050                         {
00051                                 not_set = 0,
00052                                 initialization_vector = 1,
00053                                 key_information = 3,
00054                                 fragment_range = 4,
00055                                 integrity_signature = 5,
00056                                 salt = 7,
00057                                 PCB_integrity_check_value = 8,
00058                                 encapsulated_block = 10,
00059                                 block_type_of_encapsulated_block = 11
00060                         };
00062                         enum CIPHERSUITE_FLAGS
00063                         {
00064                                 CONTAINS_SECURITY_RESULT = 1 << 0,
00065                                 CONTAINS_CORRELATOR = 1 << 1,
00066                                 CONTAINS_CIPHERSUITE_PARAMS = 1 << 2,
00067                                 CONTAINS_SECURITY_DESTINATION = 1 << 3,
00068                                 CONTAINS_SECURITY_SOURCE = 1 << 4,
00069                                 BIT5_RESERVED = 1 << 5,
00070                                 BIT6_RESERVED = 1 << 6
00071                         };
00073                         enum CIPHERSUITE_IDS
00074                         {
00075                                 BAB_HMAC = 0x001,
00076                                 PIB_RSA_SHA256 = 0x002,
00077                                 PCB_RSA_AES128_PAYLOAD_PIB_PCB = 0x003,
00078                                 ESB_RSA_AES128_EXT = 0x004
00079                         };
00080 
00081                         class TLV
00082                         {
00083                         public:
00084                                 TLV() : _type(not_set) {};
00085                                 TLV(TLV_TYPES type, std::string value)
00086                                  : _type(type), _value(value)
00087                                 { }
00088 
00089                                 bool operator<(const TLV &tlv) const;
00090                                 bool operator==(const TLV &tlv) const;
00091 
00092                                 const std::string getValue() const;
00093                                 TLV_TYPES getType() const;
00094                                 size_t getLength() const;
00095 
00096                                 friend std::ostream& operator<<(std::ostream &stream, const TLV &tlv);
00097                                 friend std::istream& operator>>(std::istream &stream, TLV &tlv);
00098 
00099                         private:
00100                                 TLV_TYPES _type;
00101                                 dtn::data::BundleString _value;
00102                         };
00103 
00104                         class TLVList : public std::set<TLV>
00105                         {
00106                         public:
00107                                 TLVList() {};
00108                                 virtual ~TLVList() {};
00109 
00110                                 friend std::ostream& operator<<(std::ostream &stream, const TLVList &tlvlist);
00111                                 friend std::istream& operator>>(std::istream &stream, TLVList &tlvlist);
00112 
00113                                 const std::string get(TLV_TYPES type) const;
00114                                 void get(TLV_TYPES type, unsigned char *value, size_t length) const;
00115                                 void set(TLV_TYPES type, std::string value);
00116                                 void set(TLV_TYPES type, const unsigned char *value, size_t length);
00117                                 void remove(TLV_TYPES type);
00118 
00119                                 const std::string toString() const;
00120                                 size_t getLength() const;
00121 
00122                         private:
00123                                 size_t getPayloadLength() const;
00124                         };
00125 
00127                         virtual ~SecurityBlock() = 0;
00128 
00133                         virtual size_t getLength() const;
00134 
00140                         virtual size_t getLength_mutable() const;
00141 
00147                         virtual std::ostream &serialize(std::ostream &stream, size_t &length) const;
00148 
00155                         virtual std::ostream &serialize_strict(std::ostream &stream, size_t &length) const;
00156 
00161                         virtual std::istream &deserialize(std::istream &stream, const size_t length);
00162 
00166                         const dtn::data::EID getSecuritySource() const;
00167 
00172                         const dtn::data::EID getSecurityDestination() const;
00173 
00178                         void setSecuritySource(const dtn::data::EID &source);
00179 
00184                         void setSecurityDestination(const dtn::data::EID &destination);
00185                                 
00192                         bool isSecuritySource(const dtn::data::Bundle&, const dtn::data::EID&) const;
00193                         
00200                         bool isSecurityDestination(const dtn::data::Bundle&, const dtn::data::EID&) const;
00201                         
00207                         const dtn::data::EID getSecuritySource(const dtn::data::Bundle&) const;
00208                         
00214                         const dtn::data::EID getSecurityDestination(const dtn::data::Bundle&) const;
00215 
00216                 protected:
00219                         u_int64_t _ciphersuite_id;
00223                         u_int64_t _ciphersuite_flags;
00225                         u_int64_t _correlator;
00226 
00229                         TLVList _ciphersuite_params;
00230 
00232                         TLVList _security_result;
00233 
00235                         dtn::data::EID _security_destination;
00236 
00238                         dtn::data::EID _security_source;
00239 
00241                         void store_security_references();
00242 
00249                         SecurityBlock(const SecurityBlock::BLOCK_TYPES type, const CIPHERSUITE_IDS id);
00250 
00256                         SecurityBlock(const SecurityBlock::BLOCK_TYPES type);
00257 
00262                         void setCiphersuiteId(const CIPHERSUITE_IDS id);
00263 
00268                         void setCorrelator(const u_int64_t corr);
00269 
00276                         static bool isCorrelatorPresent(const dtn::data::Bundle &bundle, const u_int64_t correlator);
00277 
00284                         static u_int64_t createCorrelatorValue(const dtn::data::Bundle &bundle);
00285 
00291                         virtual dtn::security::MutualSerializer &serialize_mutable(dtn::security::MutualSerializer &serializer) const;
00292                         virtual dtn::security::MutualSerializer &serialize_mutable_without_security_result(dtn::security::MutualSerializer &serializer) const;
00293 
00303                         virtual size_t getSecurityResultSize() const;
00304 
00311                         static void createSaltAndKey(u_int32_t& salt, unsigned char * key, size_t key_size);
00312 
00323                         static void addKey(TLVList& security_parameter, unsigned char const * const key, size_t key_size, RSA * rsa);
00324 
00334                         static bool getKey(const TLVList& security_parameter, unsigned char * key, size_t key_size, RSA * rsa);
00335 
00341                         static void addSalt(TLVList& security_parameters, const u_int32_t &salt);
00342 
00347                         static u_int32_t getSalt(const TLVList& security_parameters);
00348 
00355                         static void copyEID(const dtn::data::Block& from, dtn::data::Block& to, size_t skip = 0);
00356 
00370                         template <class T>
00371                         static T& encryptBlock(dtn::data::Bundle& bundle, const dtn::data::Block &block, u_int32_t salt, const unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes]);
00372 
00384                         static void decryptBlock(dtn::data::Bundle& bundle, const dtn::security::SecurityBlock &block, u_int32_t salt, const unsigned char key[ibrcommon::AES128Stream::key_size_in_bytes]);
00385 
00391                         static void addFragmentRange(TLVList& ciphersuite_params, size_t fragmentoffset, size_t payload_length);
00392 
00393                 private:
00395                         SecurityBlock(const SecurityBlock&);
00397                         SecurityBlock& operator=(const SecurityBlock&);
00398                 };
00399 
00400                 template <class T>
00401                 T& SecurityBlock::encryptBlock(dtn::data::Bundle& bundle, const dtn::data::Block &block, u_int32_t salt, const unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes])
00402                 {
00403                         // insert ESB, block can be removed after encryption, because bundle will destroy it
00404                         T& esb = bundle.insert<T>(block);
00405 
00406                         // take eid list
00407                         copyEID(block, esb);
00408 
00409                         std::stringstream ss;
00410                         ibrcommon::AES128Stream encrypt(ibrcommon::CipherStream::CIPHER_ENCRYPT, ss, ephemeral_key, salt);
00411                         dtn::data::Dictionary dict(bundle);
00412                         dtn::data::DefaultSerializer dser(encrypt, dict);
00413                         dser << block;
00414                         encrypt << std::flush;
00415 
00416                         // append tag at the end of the ciphertext
00417                         unsigned char tag[ibrcommon::AES128Stream::tag_len]; encrypt.getTag(tag);
00418                         ss.write((const char*)&tag, ibrcommon::AES128Stream::tag_len);
00419 
00420                         esb._security_result.set(SecurityBlock::encapsulated_block, ss.str());
00421                         esb._ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_RESULT;
00422 
00423                         unsigned char iv[ibrcommon::AES128Stream::iv_len]; encrypt.getIV(iv);
00424                         esb._ciphersuite_params.set(SecurityBlock::initialization_vector, iv, ibrcommon::AES128Stream::iv_len);
00425 
00426                         esb._ciphersuite_flags |= SecurityBlock::CONTAINS_CIPHERSUITE_PARAMS;
00427 
00428                         bundle.remove(block);
00429 
00430                         return esb;
00431                 }
00432         }
00433 }
00434 
00435 #endif /* SECURITYBLOCK_H_ */