IBR-DTNSuite
0.8
|
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_ */