29 #include <ibrcommon/Logger.h>
31 #include <openssl/rand.h>
32 #include <openssl/err.h>
33 #include <openssl/rsa.h>
36 #ifdef __DEVELOPMENT_ASSERTIONS__
51 for (std::set<TLV>::const_iterator iter = begin(); iter != end(); ++iter)
61 return getPayloadLength();
68 for (std::set<SecurityBlock::TLV>::const_iterator iter = begin(); iter != end(); ++iter)
70 len += (*iter).getLength();
78 for (std::set<SecurityBlock::TLV>::const_iterator iter = begin(); iter != end(); ++iter)
80 if ((*iter).getType() == type)
82 return (*iter).getValue();
91 const std::string data =
get(type);
93 if (length < data.size())
95 ::memcpy(value, data.c_str(), length);
99 ::memcpy(value, data.c_str(), data.size());
113 const std::string data(reinterpret_cast<const char *>(value), length);
134 return _value.getLength() +
sizeof(char);
142 for (std::set<SecurityBlock::TLV>::const_iterator iter = tlvlist.begin(); iter != tlvlist.end(); ++iter)
155 while (length > read_length)
168 return (_type < tlv._type);
173 return (_type == tlv._type);
178 stream.put((
char)tlv._type);
179 stream << tlv._value;
187 stream >> tlv._value;
198 : Block(type), _ciphersuite_id(0), _ciphersuite_flags(0), _correlator(0)
234 if (
_eids.size() > 0)
236 set(Block::BLOCK_CONTAINS_EIDS,
true);
240 set(Block::BLOCK_CONTAINS_EIDS,
false);
279 bool return_val =
false;
404 #ifdef __DEVELOPMENT_ASSERTIONS__
411 #ifdef __DEVELOPMENT_ASSERTIONS__
415 assert(_ciphersuite_flags < 32);
421 if (
_eids.size() == 0)
429 if (_ciphersuite_flags & SecurityBlock::CONTAINS_SECURITY_SOURCE)
431 if (
_eids.size() < 2)
438 if (
_eids.size() == 0)
452 #ifdef __DEVELOPMENT_ASSERTIONS__
453 assert(_ciphersuite_params.getLength() > 0);
460 #ifdef __DEVELOPMENT_ASSERTIONS__
461 assert(_security_result.getLength() > 0);
485 if (include_security_result) {
497 #ifdef __DEVELOPMENT_ASSERTIONS__
506 if (!RAND_bytes(reinterpret_cast<unsigned char *>(&salt),
sizeof(uint32_t)))
508 IBRCOMMON_LOGGER_ex(critical) <<
"failed to generate salt. maybe /dev/urandom is missing for seeding the PRNG" << IBRCOMMON_LOGGER_ENDL;
509 ERR_print_errors_fp(stderr);
511 if (!RAND_bytes(key, static_cast<int>(key_size)))
513 IBRCOMMON_LOGGER_ex(critical) <<
"failed to generate key. maybe /dev/urandom is missing for seeding the PRNG" << IBRCOMMON_LOGGER_ENDL;
514 ERR_print_errors_fp(stderr);
521 #ifdef __DEVELOPMENT_ASSERTIONS__
524 std::vector<unsigned char> encrypted_key(RSA_size(rsa));
525 int encrypted_key_len = RSA_public_encrypt(static_cast<int>(key_size), key, &encrypted_key[0], rsa, RSA_PKCS1_OAEP_PADDING);
526 if (encrypted_key_len == -1)
528 IBRCOMMON_LOGGER_ex(critical) <<
"failed to encrypt the symmetric AES key" << IBRCOMMON_LOGGER_ENDL;
529 ERR_print_errors_fp(stderr);
539 const unsigned char *encrypted_key =
reinterpret_cast<const unsigned char*
>(key_string.c_str());
540 std::vector<unsigned char> the_key(RSA_size(rsa));
541 RSA_blinding_on(rsa, NULL);
542 int plaintext_key_len = RSA_private_decrypt(static_cast<int>(key_string.size()), encrypted_key, &the_key[0], rsa, RSA_PKCS1_OAEP_PADDING);
543 RSA_blinding_off(rsa);
544 if (plaintext_key_len == -1)
546 IBRCOMMON_LOGGER_ex(critical) <<
"failed to decrypt the symmetric AES key" << IBRCOMMON_LOGGER_ENDL;
547 ERR_print_errors_fp(stderr);
550 #ifdef __DEVELOPMENT_ASSERTIONS__
553 std::copy(&the_key[0], &the_key[key_size], key);
560 std::list<dtn::data::EID> their_eids = from.getEIDList();
561 std::list<dtn::data::EID>::iterator it = their_eids.begin();
563 while (it != their_eids.end() && skip > 0)
569 for (; it != their_eids.end(); ++it)
591 unsigned char tag[ibrcommon::AES128Stream::tag_len];
594 unsigned char iv[ibrcommon::AES128Stream::iv_len];
603 const char *tag_p = block_data.c_str() + (block_data.size() - ibrcommon::AES128Stream::tag_len);
606 ::memcpy(tag, tag_p, ibrcommon::AES128Stream::tag_len);
609 block_data.resize(block_data.size() - ibrcommon::AES128Stream::tag_len);
612 std::stringstream plaintext;
613 ibrcommon::AES128Stream decrypt(ibrcommon::CipherStream::CIPHER_DECRYPT, plaintext, key, salt, iv);
614 decrypt << block_data << std::flush;
617 if (!decrypt.verify(tag))
634 ddser >> plaintext_block;
641 ddser >> plaintext_block;
652 copyEID(plaintext_block, plaintext_block, skip);
654 }
catch (
const ibrcommon::Exception &ex) {
656 ddser >> plaintext_block;
667 copyEID(plaintext_block, plaintext_block, skip);
676 std::stringstream ss;
677 ss << offset << range;
685 ss >> offset >> range;
dtn::data::Bitset< CIPHERSUITE_FLAGS > _ciphersuite_flags
bool sameHost(const std::string &other) const
void setCorrelator(const dtn::data::Number &corr)
const dtn::data::EID getSecuritySource() const
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])
virtual std::istream & deserialize(std::istream &stream, const dtn::data::Length &length)
void set(ProcFlags flag, const bool &value)
bool isSecurityDestination(const dtn::data::Bundle &, const dtn::data::EID &) const
void set(TLV_TYPES type, std::string value)
void setSecurityDestination(const dtn::data::EID &destination)
virtual dtn::data::Length getSecurityResultSize() const
void remove(const Block &block)
TLVList _ciphersuite_params
dtn::data::EID _security_destination
void setCiphersuiteId(const CIPHERSUITE_IDS id)
bool operator<(const TLV &tlv) const
const std::string get(TLV_TYPES type) const
static bool getKey(const TLVList &security_parameter, unsigned char *key, dtn::data::Length key_size, RSA *rsa)
T & insert(iterator before)
dtn::data::Length getLength() const
dtn::data::Length getLength() const
const std::string toString() const
std::ostream & operator<<(std::ostream &stream, const SecurityBlock::TLVList &tlvlist)
virtual MutableSerializer & serialize_mutable(MutableSerializer &serializer, bool include_security_result=true) const
std::istream & operator>>(std::istream &stream, SecurityBlock::TLVList &tlvlist)
block_list::const_iterator const_iterator
virtual ~SecurityBlock()=0
static void addFragmentRange(TLVList &ciphersuite_params, const dtn::data::Number &fragmentoffset, const dtn::data::Number &payload_length)
static void copyEID(const dtn::data::Block &from, dtn::data::Block &to, dtn::data::Length skip=0)
TLV_TYPES getType() const
dtn::data::Number _correlator
virtual std::ostream & serialize_strict(std::ostream &stream, dtn::data::Length &length) const
static void getFragmentRange(const TLVList &ciphersuite_params, dtn::data::Number &offset, dtn::data::Number &range)
block_list::iterator iterator
virtual std::ostream & serialize(std::ostream &stream, dtn::data::Length &length) const
static bool isCorrelatorPresent(const dtn::data::Bundle &bundle, const dtn::data::Number &correlator)
static Factory & get(block_t type)
static void addKey(TLVList &security_parameter, unsigned char const *const key, dtn::data::Length key_size, RSA *rsa)
static const dtn::data::block_t BLOCK_TYPE
dtn::data::EID _security_source
static void addSalt(TLVList &security_parameters, const uint32_t &salt)
std::string getString() const
virtual dtn::data::Length getLength_mutable() const
const dtn::data::EID getSecurityDestination() const
SecurityBlock(const SecurityBlock::BLOCK_TYPES type, const CIPHERSUITE_IDS id)
iterator find(block_t blocktype)
dtn::data::Number _ciphersuite_id
static uint32_t getSalt(const TLVList &security_parameters)
bool isSecuritySource(const dtn::data::Bundle &, const dtn::data::EID &) const
dtn::data::SDNV< Size > Number
const block_t & getType() const
static void createSaltAndKey(uint32_t &salt, unsigned char *key, dtn::data::Length key_size)
bool operator==(const TLV &tlv) const
void setSecuritySource(const dtn::data::EID &source)
const std::string getValue() const
void store_security_references()
void remove(TLV_TYPES type)
static dtn::data::Number createCorrelatorValue(const dtn::data::Bundle &bundle)
static const dtn::data::Length sdnv_size
virtual dtn::data::Length getLength() const