Commit b9cdc3ba authored by garciay's avatar garciay
Browse files

Major security bugs fixed for signature. Encryption to do.

parent f45b607e
This diff is collapsed.
......@@ -17,11 +17,37 @@
using namespace LibItsGeoNetworking__TypesAndValues;
geonetworking_layer::geonetworking_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _gbc_packet(nullptr), _shb_packet(nullptr), _tsb_packet(nullptr), _ls_reply(nullptr), _location_table(), _pass_beacon_table(), _device_mode{false}, _secured_mode{false}, _encrypted_mode{false}, _enable_security_checks{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}, _sequence_number{0}, _latitude{0}, _longitude{0} {
loggers::get_instance().log(">>> geonetworking_layer::geonetworking_layer: %s, %s", to_string().c_str(), param.c_str());
geonetworking_layer::geonetworking_layer(const std::string & p_type, const std::string & p_param) : t_layer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _gbc_packet(nullptr), _shb_packet(nullptr), _tsb_packet(nullptr), _ls_reply(nullptr), _location_table(), _pass_beacon_table(), _device_mode{false}, _secured_mode{false}, _encrypted_mode{false}, _enable_security_checks{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}, _sequence_number{0}, _latitude{0}, _longitude{0} {
loggers::get_instance().log(">>> geonetworking_layer::geonetworking_layer: %s, %s", to_string().c_str(), p_param.c_str());
init(p_type, p_param);
} // End of constructor
geonetworking_layer::~geonetworking_layer() {
loggers::get_instance().log(">>> geonetworking_layer::~geonetworking_layer");
if (_timerid != 0) {
timer_delete(_timerid);
}
if (_beacon != nullptr) {
delete _beacon;
}
if (_gbc_packet != nullptr) {
delete _gbc_packet;
}
if (_shb_packet != nullptr) {
delete _shb_packet;
}
if (_ls_reply != nullptr) {
delete _ls_reply;
}
} // End of destructor
void geonetworking_layer::init(const std::string & p_type, const std::string & p_param) {
loggers::get_instance().log(">>> geonetworking_layer::init: %s, %s", to_string().c_str(), p_param.c_str());
// Setup parameters
params::convert(_params, param);
params::convert(_params, p_param);
// Sanity checks
params::const_iterator it = _params.find(params::latitude);
if (it != _params.cend()) {
......@@ -121,27 +147,7 @@ geonetworking_layer::geonetworking_layer(const std::string & p_type, const std::
// Register this object for AdapterControlPort
loggers::get_instance().log("geonetworking_layer::geonetworking_layer: Register %s/%p", p_type.c_str(), this);
registration<geonetworking_layer>::get_instance().add_item(p_type, this);
} // End of constructor
geonetworking_layer::~geonetworking_layer() {
loggers::get_instance().log(">>> geonetworking_layer::~geonetworking_layer");
if (_timerid != 0) {
timer_delete(_timerid);
}
if (_beacon != nullptr) {
delete _beacon;
}
if (_gbc_packet != nullptr) {
delete _gbc_packet;
}
if (_shb_packet != nullptr) {
delete _shb_packet;
}
if (_ls_reply != nullptr) {
delete _ls_reply;
}
} // End of destructor
} // End of init_params
void geonetworking_layer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, params& params) {
loggers::get_instance().log(">>> geonetworking_layer::sendMsg");
......
......@@ -115,7 +115,7 @@ class geonetworking_layer : public t_layer<LibItsGeoNetworking__TestSystem::GeoN
public:
explicit geonetworking_layer() : t_layer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(), _params(), _codec(), _beacon(NULL), _gbc_packet(NULL), _shb_packet(nullptr), _ls_reply(nullptr), _location_table(), _pass_beacon_table(), _device_mode{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}, _sequence_number{0} { };
geonetworking_layer(const std::string& p_type, const std::string& param);
geonetworking_layer(const std::string& p_type, const std::string& p_param);
virtual ~geonetworking_layer();
/*!
......@@ -163,6 +163,7 @@ public:
int disable_secured_mode();
private:
void init(const std::string & p_type, const std::string & p_param);
void send_beacon();
int build_geonetworking_pdu(OCTETSTRING& data, params& params);
int build_secured_pdu(OCTETSTRING& data, params& params);
......
......@@ -96,6 +96,20 @@ int security_cache::get_hashed_id(const std::string& p_certificate_id, OCTETSTRI
return 0;
}
int security_cache::get_hash(const std::string& p_certificate_id, OCTETSTRING& p_hash) const {
loggers::get_instance().log(">>> security_cache::get_hash: '%s'", p_certificate_id.c_str());
std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
if (it == _certificates.cend()) {
loggers::get_instance().warning("security_cache::get_hash: record not found");
return -1;
}
const std::vector<unsigned char> hash = it->second.get()->hash();
p_hash = OCTETSTRING(hash.size(), hash.data());
return 0;
}
int security_cache::get_private_key(const std::string& p_certificate_id, OCTETSTRING& p_private_key) const {
loggers::get_instance().log(">>> security_cache::get_private_key: '%s'", p_certificate_id.c_str());
......
......@@ -36,6 +36,7 @@ public: /*! \publicsection */
int get_certificate(const std::string& p_certificate_id, IEEE1609dot2::CertificateBase& p_certificate) const;
int get_issuer(const std::string& p_certificate_id, OCTETSTRING& p_hashed_id_issuer) const;
int get_hashed_id(const std::string& p_certificate_id, OCTETSTRING& p_hashed_id) const;
int get_hash(const std::string& p_certificate_id, OCTETSTRING& p_hash) const;
int get_private_key(const std::string& p_certificate_id, OCTETSTRING& p_private_key) const;
int get_public_keys(const std::string& p_certificate_id, OCTETSTRING& p_public_key_x, OCTETSTRING& p_public_key_y) const;
int get_public_comp_key(const std::string& p_certificate_id, OCTETSTRING& p_public_comp_key, INTEGER& p_comp_mode) const;
......
#include "EtsiTs103097Module.hh"
#include "sha256.hh"
#include "sha384.hh"
#include "security_db_record.hh"
security_db_record::security_db_record(
......@@ -16,7 +18,14 @@ security_db_record::security_db_record(
const std::vector<unsigned char>& p_pu_enc_key_x,
const std::vector<unsigned char>& p_pu_enc_key_y,
const bool p_to_be_saved
): _algorithm{ec_elliptic_curves::nist_p_256}, _certificate_id(p_certificate_id), _certificate(p_certificate), _hashed_id_issuer(p_hashed_id_issuer), _hashed_id(p_hashed_id), _pr_key(p_pr_key), _pu_key_x(p_pu_key_x), _pu_key_y(p_pu_key_y), _pu_comp_key(p_pu_comp_key), _pr_enc_key(p_pr_enc_key), _pu_enc_key_x(p_pu_enc_key_x), _pu_enc_key_y(p_pu_enc_key_y), _to_be_saved(p_to_be_saved), _decoded_certificate(static_cast<IEEE1609dot2::CertificateBase*>(p_decoded_certificate.clone())) {
): _algorithm{ec_elliptic_curves::nist_p_256}, _certificate_id(p_certificate_id), _certificate(p_certificate), _hashed_id_issuer(p_hashed_id_issuer), _hash(), _hashed_id(p_hashed_id), _pr_key(p_pr_key), _pu_key_x(p_pu_key_x), _pu_key_y(p_pu_key_y), _pu_comp_key(p_pu_comp_key), _pr_enc_key(p_pr_enc_key), _pu_enc_key_x(p_pu_enc_key_x), _pu_enc_key_y(p_pu_enc_key_y), _to_be_saved(p_to_be_saved), _decoded_certificate(static_cast<IEEE1609dot2::CertificateBase*>(p_decoded_certificate.clone())) {
if (p_pr_key.size() == 32) {
sha256 sha;
sha.generate(_certificate, _hash);
} else {
sha384 sha;
sha.generate(_certificate, _hash);
}
}
const IEEE1609dot2::CertificateBase& security_db_record::decoded_certificate() const {
......
......@@ -16,9 +16,10 @@ namespace IEEE1609dot2 {
class security_db_record {
ec_elliptic_curves _algorithm;
std::string _certificate_id; /*!< certificate storage*/
std::vector<unsigned char> _certificate; /*!< Certificate storage */
std::vector<unsigned char> _hashed_id_issuer; /*!< Certificate hash id 8 storage */
std::string _certificate_id; /*!< Certificate storage*/
std::vector<unsigned char> _certificate; /*!< COER storage */
std::vector<unsigned char> _hashed_id_issuer; /*!< Hash id 8 of the issuer certificate */
std::vector<unsigned char> _hash; /*!< Certificate hash storage */
std::vector<unsigned char> _hashed_id; /*!< Certificate hash id 8 storage */
std::vector<unsigned char> _pr_key; /*!< Private key storage */
std::vector<unsigned char> _pu_key_x; /*!< Public key X-coordinate storage */
......@@ -34,7 +35,7 @@ public: /*! \publicsection */
/*!
* \brief Default private ctor
*/
explicit security_db_record(): _algorithm{ec_elliptic_curves::nist_p_256}, _certificate_id(), _certificate(), _hashed_id_issuer(), _hashed_id(), _pr_key(), _pu_key_x(), _pu_key_y(), _pu_comp_key(), _pr_enc_key(), _pu_enc_key_x(), _pu_enc_key_y(), _to_be_saved(false), _decoded_certificate(nullptr) { };
explicit security_db_record(): _algorithm{ec_elliptic_curves::nist_p_256}, _certificate_id(), _certificate(), _hashed_id_issuer(), _hash(), _hashed_id(), _pr_key(), _pu_key_x(), _pu_key_y(), _pu_comp_key(), _pr_enc_key(), _pu_enc_key_x(), _pu_enc_key_y(), _to_be_saved(false), _decoded_certificate(nullptr) { };
security_db_record(const std::string& p_certificate_id, const std::vector<unsigned char>& p_certificate, const IEEE1609dot2::CertificateBase& p_decoded_certificate, const std::vector<unsigned char>& p_hashed_id_issuer, const std::vector<unsigned char>& p_hashed_id, const std::vector<unsigned char>& p_pr_key, const std::vector<unsigned char>& p_pu_key_x, const std::vector<unsigned char>& p_pu_key_y, const std::vector<unsigned char>& p_pu_comp_key, const std::vector<unsigned char>& p_pr_enc_key, const std::vector<unsigned char>& p_pu_enc_key_x, const std::vector<unsigned char>& p_pu_enc_key_y, const bool p_to_be_saved = true);
/*!
......@@ -47,6 +48,7 @@ public: /*! \publicsection */
inline const std::string& certificate_id() const { return _certificate_id; };
inline const std::vector<unsigned char>& certificate() const { return _certificate; };
inline const std::vector<unsigned char>& hashed_id() const { return _hashed_id; };
inline const std::vector<unsigned char>& hash() const { return _hash; };
inline const std::vector<unsigned char>& issuer() const { return _hashed_id_issuer; };
inline const std::vector<unsigned char>& private_key() const { return _pr_key; };
inline const std::vector<unsigned char>& public_key_x() const { return _pu_key_x; };
......
......@@ -253,37 +253,37 @@ int security_ecc::generate() {
return -1;
}
BIGNUM x, y, compressed_y;
BIGNUM x, y;
::BN_init(&x);
::BN_init(&y);
::BN_init(&compressed_y);
const EC_POINT* ec_point = EC_KEY_get0_public_key(_ec_key);
const BIGNUM* p;
//do {
int result = 0;
switch (_elliptic_curve) {
case ec_elliptic_curves::nist_p_256: // Use primary
// No break;
case ec_elliptic_curves::brainpool_p_256_r1:
// No break;
case ec_elliptic_curves::brainpool_p_384_r1:
result = ::EC_POINT_get_affine_coordinates_GFp(_ec_group, ec_point, &x, &y, _bn_ctx); // Use primer on elliptic curve
break;
default: // Use binary
result = ::EC_POINT_get_affine_coordinates_GF2m(_ec_group, ec_point, &x, &y, _bn_ctx);
} // End of 'switch' statement
if (result == 0) {
loggers::get_instance().error("security_ecc::generate: Failed to get coordinates");
return -1;
}
p = ::EC_KEY_get0_private_key(_ec_key);
// } while ((BN_num_bytes(p) == 0) || ((BN_num_bytes(p) % 2) == 1));
int result = 0;
int size = 0;
switch (_elliptic_curve) {
case ec_elliptic_curves::nist_p_256: // Use primary
// No break;
case ec_elliptic_curves::brainpool_p_256_r1:
size = 32;
result = ::EC_POINT_get_affine_coordinates_GFp(_ec_group, ec_point, &x, &y, _bn_ctx); // Use primer on elliptic curve
break;
case ec_elliptic_curves::brainpool_p_384_r1:
size = 48;
result = ::EC_POINT_get_affine_coordinates_GFp(_ec_group, ec_point, &x, &y, _bn_ctx); // Use primer on elliptic curve
break;
default: // Use binary
result = ::EC_POINT_get_affine_coordinates_GF2m(_ec_group, ec_point, &x, &y, _bn_ctx);
} // End of 'switch' statement
if (result == 0) {
loggers::get_instance().error("security_ecc::generate: Failed to get coordinates");
return -1;
}
const BIGNUM* p = ::EC_KEY_get0_private_key(_ec_key);
_pri_key.resize(BN_num_bytes(p));
_pri_key.resize(size);
::BN_bn2bin(p, _pri_key.data());
_pub_key_x.resize(BN_num_bytes(&x));
_pub_key_x.resize(size);
::BN_bn2bin(&x, _pub_key_x.data());
_pub_key_y.resize(BN_num_bytes(&y));
_pub_key_y.resize(size);
::BN_bn2bin(&y, _pub_key_y.data());
// Compressed
......@@ -300,7 +300,6 @@ int security_ecc::generate() {
_pub_key_compressed_mode = ((_pub_key_compressed[0] & 0x01) == 0x00) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1;
_pub_key_compressed.erase(_pub_key_compressed.begin());
}
loggers::get_instance().log("security_ecc::generate: _pri_key size=%d", _pri_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate: _pri_key=", _pri_key.data(), _pri_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate: _pub_key_x=", _pub_key_x.data(), _pub_key_x.size());
loggers::get_instance().log_to_hexa("security_ecc::generate: _pub_key_y=", _pub_key_y.data(), _pub_key_y.size());
......@@ -311,15 +310,15 @@ int security_ecc::generate() {
}
int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_recipients_public_key_x, const std::vector<unsigned char>& p_recipients_public_key_y) {
loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key");
loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key (1)");
// Sanity checks
if (_pri_key.size() == 0) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Key shall be generated");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Key shall be generated");
return -1;
}
if ((_pub_key_x.size() == 0) || (_pub_key_y.size() == 0)) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Keys shall be generated");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Keys shall be generated");
return -1;
}
_encryption_algotithm = p_enc_algorithm;
......@@ -339,7 +338,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
tag_length = 16;
break;
default:
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Unsupported encryption algorithm");
return -1;
} // End of 'switch' statement
unsigned int k_length;
......@@ -353,65 +352,65 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
k_length = 48;
break;
default:
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Unsupported encryption algorithm");
return -1;
} // End of 'switch' statement
// Convert the peer public encryption key to an EC point
// Convert the ephemeral public encryption keys to an EC point
EC_POINT *ec_point = nullptr;
bin_to_ec_point(p_recipients_public_key_x, p_recipients_public_key_y, &ec_point);
// Generate the shared secret key
int result = ::ECDH_compute_key(_secret_key.data(), _secret_key.size(), ec_point, _ec_key, NULL);
if (result == -1) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to generate shared secret key");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Failed to generate shared secret key");
::EC_POINT_free(ec_point);
return -1;
}
::EC_POINT_free(ec_point);
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _secret_key: ", _secret_key.data(), _secret_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): _secret_key: ", _secret_key.data(), _secret_key.size());
// Derive the shared secret key
std::vector<unsigned char> k_enc(nonce_length + sym_key_length + tag_length, 0x00);
std::vector<unsigned char> k_mac(k_length + k_length, 0x00);
std::vector<unsigned char> digest(k_enc.size() + k_mac.size(), 0x00);
loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key: k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key (1): k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
if (PKCS5_PBKDF2_HMAC((const char*)_secret_key.data(), _secret_key.size(), NULL, 0, 2000, EVP_sha256(), digest.size(), digest.data()) != 1) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive shared secret key");
return -1;
}
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: digest: ", digest.data(), digest.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): digest: ", digest.data(), digest.size());
// Extract AES 128 parameters
_nonce.resize(nonce_length);
std::copy(digest.begin(), digest.begin() + _nonce.size(), _nonce.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _nonce: ", _nonce.data(), _nonce.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): _nonce: ", _nonce.data(), _nonce.size());
_sym_key.resize(sym_key_length);
std::copy(digest.begin() + _nonce.size(), digest.begin() + _nonce.size() + _sym_key.size(), _sym_key.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _sym_key: ", _sym_key.data(), _sym_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): _sym_key: ", _sym_key.data(), _sym_key.size());
_tag.resize(tag_length);
std::copy(digest.begin() + _nonce.size() + _sym_key.size(), digest.begin() + _nonce.size() + _sym_key.size() + _tag.size(), _tag.begin()); // TODO Useless???
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _tag: ", _tag.data(), _tag.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): _tag: ", _tag.data(), _tag.size());
// Extract the HMAC key
std::vector<unsigned char> hmac_secret(k_length + k_length, 0x00);
std::copy(digest.data() + nonce_length + sym_key_length + tag_length, digest.data() + nonce_length + sym_key_length + tag_length + 2 * k_length, hmac_secret.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: hmac_secret: ", hmac_secret.data(), hmac_secret.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): hmac_secret: ", hmac_secret.data(), hmac_secret.size());
// Encrypt the _sym_key
if (encrypt(encryption_algotithm::aes_128_ccm, _sym_key, _nonce, _sym_key, _enc_sym_key) == -1) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to encrypt key");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (1): Failed to encrypt key");
return -1;
}
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Encrypted symmetric key: ", encrypted_symmetric_key().data(), encrypted_symmetric_key().size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (1): Encrypted symmetric key: ", encrypted_symmetric_key().data(), encrypted_symmetric_key().size());
return 0;
}
int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_ephemeral_public_key_x, const std::vector<unsigned char>& p_ephemeral_public_key_y, const std::vector<unsigned char>& p_enc_sym_key, const std::vector<unsigned char>& p_expected_nonce, const std::vector<unsigned char>& p_authentication_vector) {
loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key");
loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key (2)");
// Sanity checks
if (_pri_key.size() == 0) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Key shall be generated");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (2): Key shall be generated");
return -1;
}
_encryption_algotithm = p_enc_algorithm;
......@@ -434,7 +433,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
tag_length = 16;
break;
default:
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (2): Unsupported encryption algorithm");
return -1;
} // End of 'switch' statement
unsigned int k_length;
......@@ -448,7 +447,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
k_length = 48;
break;
default:
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (2): Unsupported encryption algorithm");
return -1;
} // End of 'switch' statement
......@@ -462,49 +461,49 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
return -1;
}
::EC_POINT_free(ec_point);
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _secret_key: ", _secret_key.data(), _secret_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): _secret_key: ", _secret_key.data(), _secret_key.size());
// Derive the shared secret key
std::vector<unsigned char> k_enc(nonce_length + sym_key_length + tag_length, 0x00);
std::vector<unsigned char> k_mac(k_length + k_length, 0x00);
std::vector<unsigned char> digest(k_enc.size() + k_mac.size(), 0x00);
loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key: k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key (2): k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
if (PKCS5_PBKDF2_HMAC((const char*)_secret_key.data(), _secret_key.size(), NULL, 0, 2000, EVP_sha256(), digest.size(), digest.data()) != 1) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive shared secret key");
return -1;
}
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: digest: ", digest.data(), digest.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): digest: ", digest.data(), digest.size());
// Extract AES 128 parameters
std::vector<unsigned char> nonce(nonce_length, 0x00);
std::copy(digest.begin(), digest.begin() + nonce.size(), nonce.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Generated nonce: ", nonce.data(), nonce.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): Generated nonce: ", nonce.data(), nonce.size());
std::vector<unsigned char> sym_key(sym_key_length, 0x00);
std::copy(digest.begin() + nonce.size(), digest.begin() + nonce.size() + sym_key.size(), sym_key.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: sym_key: ", sym_key.data(), sym_key.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): sym_key: ", sym_key.data(), sym_key.size());
std::vector<unsigned char> tag(tag_length, 0x00);
std::copy(digest.begin() + nonce.size() + sym_key.size(), digest.begin() + nonce.size() + sym_key.size() + tag.size(), tag.begin()); // TODO Useless???
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: tag: ", tag.data(), tag.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): tag: ", tag.data(), tag.size());
// Extract the HMAC key
std::vector<unsigned char> hmac_secret(k_length + k_length, 0x00);
std::copy(digest.data() + nonce_length + sym_key_length + tag_length, digest.data() + nonce_length + sym_key_length + tag_length + 2 * k_length, hmac_secret.begin());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: hmac_secret: ", hmac_secret.data(), hmac_secret.size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): hmac_secret: ", hmac_secret.data(), hmac_secret.size());
// Check if nonce vectors are valid
if (_nonce != nonce) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive nonce vector");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (2): Failed to derive nonce vector");
return -1;
}
// Decrypt the symmetric key
std::vector<unsigned char> skey;
if (decrypt(p_enc_algorithm, sym_key, nonce, p_authentication_vector, p_enc_sym_key, skey) == -1) {
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to decrypt key");
loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key (2): Failed to decrypt key");
return -1;
}
_sym_key = skey;
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Decrypted symmetric key: ", symmetric_encryption_key().data(), symmetric_encryption_key().size());
loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key (2): Decrypted symmetric key: ", symmetric_encryption_key().data(), symmetric_encryption_key().size());
return 0;
}
......
......@@ -106,6 +106,7 @@ public: /*! \publicsection */
int read_certificate(const CHARSTRING& p_certificate_id, OCTETSTRING& p_certificate) const;
int read_certificate_digest(const CHARSTRING& p_certificate_id, OCTETSTRING& p_digest) const;
int read_certificate_hash(const CHARSTRING& p_certificate_id, OCTETSTRING& p_hash) const;
int read_certificate_from_digest(const OCTETSTRING& p_digest, CHARSTRING& p_certificate_id) const;
int read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const;
int read_private_enc_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_enc_key) const;
......@@ -147,5 +148,7 @@ private:
int sign_ecdsa_nistp256(const OCTETSTRING& p_hash, IEEE1609dot2BaseTypes::Signature& p_signature, params& p_params);
int verify_sign_ecdsa_nistp256(const OCTETSTRING& p_hash, const IEEE1609dot2BaseTypes::Signature& p_signature, const std::string& p_certificate_id, params& p_params);
int extract_encryption_keys(const IEEE1609dot2::CertificateBase& p_cert, OCTETSTRING& p_public_enc_key_x, OCTETSTRING& p_public_enc_key_y);
int extract_verification_keys(const IEEE1609dot2::CertificateBase& p_cert, OCTETSTRING& p_public_key_x, OCTETSTRING& p_public_key_y, OCTETSTRING& p_public_comp_key, INTEGER& p_public_comp_key_mode);
int extract_encryption_keys(const IEEE1609dot2::CertificateBase& p_cert, OCTETSTRING& p_public_enc_key_x, OCTETSTRING& p_public_enc_key_y, OCTETSTRING& p_public_enc_comp_key, INTEGER& p_public_enc_comp_key_mode);
int extract_and_store_certificate(IEEE1609dot2::CertificateBase p_certificate);
}; // End of class security_services
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment