Commit 6a8275a7 authored by vagrant's avatar vagrant
Browse files

Merge branch 'STF525' of https://forge.etsi.org/gitlab/ITS/ITS into STF525

parents cacaaca8 214bddfe
......@@ -853,57 +853,113 @@ namespace LibItsSecurity__Functions
return message;
}
OCTETSTRING fx__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode, OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
OCTETSTRING fx__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode,OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce, const BOOLEAN& p__use__hardcoded__values) {
loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage);
loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__recipientsPublicKeyCompressed: ", p__recipientsPublicKeyCompressed);
loggers::get_instance().log(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__compressedMode: %d", static_cast<int>(p__compressedMode));
// 1. Generate new ephemeral Private/Public keys
security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1);
if (ec.generate() == -1) {
loggers::get_instance().warning(": Failed to generate ephemeral keys");
return OCTETSTRING(0, nullptr);
loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__salt: ", p__salt);
loggers::get_instance().log(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__use__hardcoded__values: %x", static_cast<const boolean>(p__use__hardcoded__values));
// 1. Generate new Private/Public Ephemeral key
std::unique_ptr<security_ecc> ec;
if (!static_cast<const boolean>(p__use__hardcoded__values)) {
ec.reset(new security_ecc(ec_elliptic_curves::brainpool_p_256_r1));
if (ec->generate() == -1) {
loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate ephemeral keys");
return OCTETSTRING(0, nullptr);
}
} else {
ec.reset(new security_ecc(ec_elliptic_curves::brainpool_p_256_r1, str2oct("0722B39ABC7B6C5301CA0408F454F81553D7FE59F492DBF385B6B6D1F81E0F68"))); // Hardcoded private key
}
// 2. Generate and derive shared secret
// 2. Generate and derive shared secret based on recipient's private keys
security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, p__recipientsPublicKeyCompressed, (static_cast<int>(p__compressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), OCTETSTRING(0, nullptr)) == -1) {
if (static_cast<const boolean>(p__use__hardcoded__values)) { // Set AES encryption key to an harcoded value
ec->symmetric_encryption_key(str2oct("5A4E63B247C714644E85CAC49BD26C81"));
}
if (ec->generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate and derive secret key");
return OCTETSTRING(0, nullptr);
}
// Set the AES symmetric key
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: AES symmetric key: ", ec.symmetric_encryption_key());
p__aes__sym__key = ec.symmetric_encryption_key();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: AES symmetric key: ", ec->symmetric_encryption_key());
p__aes__sym__key = ec->symmetric_encryption_key();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
// Set the encrypted symmetric key
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: Symmetric encryption key: ", ec.symmetric_encryption_key());
p__encrypted__sym__key = ec.encrypted_symmetric_key();
loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: Encrypted symmetric key: ", ec->encrypted_symmetric_key());
p__encrypted__sym__key = ec->encrypted_symmetric_key();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
// Set the tag of the symmetric key encryption
p__authentication__vector = ec.tag();
p__authentication__vector = ec->tag();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
// Set ephemeral public keys
p__publicEphemeralKeyCompressed = ec.public_key_compressed();
p__publicEphemeralKeyCompressed = ec->public_key_compressed();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: Ephemeral public compressed key: ", p__publicEphemeralKeyCompressed);
p__ephemeralCompressedMode = (ec.public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
p__ephemeralCompressedMode = (ec->public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
loggers::get_instance().log("fx__encryptWithEciesBrainpoolp256WithSha256: Ephemeral public compressed mode: %d: ", p__ephemeralCompressedMode);
// 3. Retrieve AES 128 parameters
p__nonce = ec.nonce();
p__nonce = ec->nonce();
loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
OCTETSTRING enc_symm_key = ec.symmetric_encryption_key();
loggers::get_instance().log_msg(": enc_symm_key: ", enc_symm_key);
// 4. Encrypt the data using AES-128 CCM
OCTETSTRING enc_message;
if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
if (ec->encrypt(encryption_algotithm::aes_128_ccm, ec->symmetric_encryption_key(), ec->nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to encrypt message");
return OCTETSTRING(0, nullptr);
}
enc_message += ec.tag();
enc_message += ec->tag();
loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: enc message||Tag: ", enc_message);
return enc_message;
}
/**
* @desc Test function for ECIES BRAINPOOL P-256r1 Encryption with SHA-256
* @remark For the purpose of testing, the content of p__toBeEncryptedSecuredMessage is the AES 128 symmetric key to be encrypted
*/
OCTETSTRING fx__test__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__privateEphemeralKey, const OCTETSTRING& p__recipientPublicKeyX, const OCTETSTRING& p__recipientPublicKeyY, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
// 1. Generate new ephemeral Private/Public keys
security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1, p__privateEphemeralKey);
p__publicEphemeralKeyX = ec.public_key_x();
p__publicEphemeralKeyY = ec.public_key_y();
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Vx=", p__publicEphemeralKeyX);
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Vy=", p__publicEphemeralKeyY);
// 2. Generate and derive shared secret
security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, p__recipientPublicKeyX, p__recipientPublicKeyY);
ec.symmetric_encryption_key(p__toBeEncryptedSecuredMessage);
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: ", ec.encrypted_symmetric_key());
if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
loggers::get_instance().warning("fx__test__encryptWithEciesBrainpoolp256WithSha256: Failed to generate and derive secret key");
return OCTETSTRING(0, nullptr);
}
// Set the AES symmetric key
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: AES symmetric key: ", ec.symmetric_encryption_key());
p__aes__sym__key = ec.symmetric_encryption_key();
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
// Set the encrypted symmetric key
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Encrypted symmetric key: ", ec.encrypted_symmetric_key());
p__encrypted__sym__key = ec.encrypted_symmetric_key();
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
// Set the tag of the symmetric key encryption
p__authentication__vector = ec.tag();
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
// 3. Retrieve AES 128 parameters
p__nonce = ec.nonce();
loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
// 4. Encrypt the data using AES-128 CCM
OCTETSTRING enc_message;
if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
loggers::get_instance().warning("fx__test__encryptWithEciesBrainpoolp256WithSha256: Failed to encrypt message");
return OCTETSTRING(0, nullptr);
}
enc_message += ec.tag();
loggers::get_instance().log_to_hexa("fx__test__encryptWithEciesBrainpoolp256WithSha256: enc message||Tag: ", enc_message);
return enc_message;
}
OCTETSTRING fx__decryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyCompressed, const INTEGER& p__ephemeralCompressedMode, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce) {
loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__privateEncKey: ", p__privateEncKey);
......@@ -1168,7 +1224,8 @@ namespace LibItsSecurity__Functions
BOOLEAN fx__readCertificateFromDigest(
const OCTETSTRING& p__digest,
CHARSTRING& p__certificateId) {
CHARSTRING& p__certificateId
) {
loggers::get_instance().log_msg(">>> fx__readCertificateFromDigest: ", p__digest);
if (security_services::get_instance().read_certificate_from_digest(p__digest, p__certificateId) == -1) {
......@@ -1179,6 +1236,20 @@ namespace LibItsSecurity__Functions
return TRUE;
}
BOOLEAN fx__readCertificateFromHashedId3(
const OCTETSTRING& p__digest,
CHARSTRING& p__certificateId
) {
loggers::get_instance().log_msg(">>> fx__readCertificateFromHashedId3: ", p__digest);
if (security_services::get_instance().read_certificate_from_hashed_id3(p__digest, p__certificateId) == -1) {
return FALSE;
}
loggers::get_instance().log_msg("fx__readCertificateFromHashedId3: ", p__certificateId);
return TRUE;
}
/**
* \brief Read the specified certificate digest
* \param p_certificate_id the certificate identifier
......@@ -1205,9 +1276,9 @@ namespace LibItsSecurity__Functions
* \return true on success, false otherwise
*/
BOOLEAN fx__readCertificateHash(
const CHARSTRING& p__certificateId,
OCTETSTRING& p__hash
) {
const CHARSTRING& p__certificateId,
OCTETSTRING& p__hash
) {
loggers::get_instance().log(">>> fx__readCertificateHash: '%s'", static_cast<const char*>(p__certificateId));
if (security_services::get_instance().read_certificate_hash(p__certificateId, p__hash) == -1) {
......
......@@ -45,16 +45,16 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
const unsigned char* p = static_cast<const unsigned char *>(data);
const commsignia_layer::c2p_recv* r = (const commsignia_layer::c2p_recv*)p;
//loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r->version);
//loggers::get_instance().log("commsignia_layer::receive_data: timestamp1=%08x", ntohl(r->timestamp_sec));
//loggers::get_instance().log("commsignia_layer::receive_data: timestamp2=%08x", ntohl(r->timestamp_msec));
//loggers::get_instance().log("commsignia_layer::receive_data: timestamp2=%08x", ntohl(r->timestamp_msec));
//loggers::get_instance().log("commsignia_layer::receive_data: antenna=%02x", r->antenna);
//loggers::get_instance().log("commsignia_layer::receive_data: rssi_ant2=%02x", r->rssi_ant2);
//loggers::get_instance().log("commsignia_layer::receive_data: noise_ant1=%02x", r->noise_ant1);
//loggers::get_instance().log("commsignia_layer::receive_data: noise_ant2=%02x", r->noise_ant2);
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r->version);
loggers::get_instance().log("commsignia_layer::receive_data: timestamp1=%08x", ntohl(r->timestamp_sec));
loggers::get_instance().log("commsignia_layer::receive_data: timestamp2=%08x", ntohl(r->timestamp_msec));
loggers::get_instance().log("commsignia_layer::receive_data: timestamp2=%08x", ntohl(r->timestamp_msec));
loggers::get_instance().log("commsignia_layer::receive_data: antenna=%02x", r->antenna);
loggers::get_instance().log("commsignia_layer::receive_data: rssi_ant2=%02x", r->rssi_ant2);
loggers::get_instance().log("commsignia_layer::receive_data: noise_ant1=%02x", r->noise_ant1);
loggers::get_instance().log("commsignia_layer::receive_data: noise_ant2=%02x", r->noise_ant2);
// Filtering on antenna index
//loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r->antenna, static_cast<unsigned char>(std::strtoul(_params[params::interface_id].c_str(), NULL, 10)));
loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r->antenna, static_cast<unsigned char>(std::strtoul(_params[params::interface_id].c_str(), NULL, 10)));
if (r->antenna != static_cast<unsigned char>(std::strtoul(_params[params::interface_id].c_str(), NULL, 10))) {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong antenna id");
......
......@@ -138,13 +138,13 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
p_encoding_buffer.put_cs(int2str(p_request.version__minor()));
p_encoding_buffer.put_cs("\r\n");
// Encode headers excepeted the Content-length
// Encode headers excepeted the Content-Length
const LibItsHttp__TypesAndValues::HeaderLines& headers = p_request.header();
std::string content_type;
for (int i = 0; i < headers.size_of(); i++) {
const LibItsHttp__TypesAndValues::HeaderLine& header = headers[i];
loggers::get_instance().log_msg("http_codec::encode_request: Processing header ", header.header__name());
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-length") == 0) { // Skip it, processed later
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Length") == 0) { // Skip it, processed later
loggers::get_instance().log("http_codec::encode_request: Skip it");
continue;
} else {
......@@ -155,8 +155,8 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
const LibItsHttp__TypesAndValues::charstring__list& v = dynamic_cast<const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list> &>(o);
if (v.size_of() > 0) {
loggers::get_instance().log_msg("http_codec::encode_request: Processing value ", v[0]);
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-type") == 0) { // Store it for HTTP body payload encoding
loggers::get_instance().log("http_codec::encode_request: Storing Content-type");
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Type") == 0) { // Store it for HTTP body payload encoding
loggers::get_instance().log("http_codec::encode_request: Storing Content-Yype");
int j = 0;
while (j < v.size_of()) {
content_type += v[j++];
......@@ -196,10 +196,10 @@ int http_codec::encode_request(const LibItsHttp__TypesAndValues::Request& p_requ
_ec.is_content_length_present = 0x00;
}
// Encode Content-length header
p_encoding_buffer.put_cs("Content-length: ");
// Encode Content-Length header
p_encoding_buffer.put_cs("Content-Length: ");
if (_ec.length != 0) {
loggers::get_instance().log("http_codec::encode_request: Content-length: %s", static_cast<const char*>(int2str(_ec.length + 2/*Stand for the last CRLF*/)));
loggers::get_instance().log("http_codec::encode_request: Content-Length: %s", static_cast<const char*>(int2str(_ec.length + 2/*Stand for the last CRLF*/)));
p_encoding_buffer.put_cs(static_cast<const char*>(int2str(_ec.length + 2/*Stand for the last CRLF*/)));
_ec.is_content_length_present = 0x01;
} else {
......@@ -236,7 +236,7 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
}
p_encoding_buffer.put_cs("\r\n");
// Encode headers excepeted the Content-length
// Encode headers excepeted the Content-Length
const LibItsHttp__TypesAndValues::HeaderLines& headers = p_response.header();
std::string content_type;
for (int i = 0; i < headers.size_of(); i++) {
......@@ -252,7 +252,7 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
const LibItsHttp__TypesAndValues::charstring__list& v = dynamic_cast<const OPTIONAL<LibItsHttp__TypesAndValues::charstring__list> &>(o);
if (v.size_of() > 0) {
loggers::get_instance().log_msg("http_codec::encode_response: Processing value ", v[0]);
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-type") == 0) { // Store it for HTTP body payload encoding
if (std::string(static_cast<const char*>(header.header__name())).compare("Content-Type") == 0) { // Store it for HTTP body payload encoding
int j = 1;
while (j < v.size_of()) {
content_type += v[j++];
......@@ -292,7 +292,7 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
_ec.is_content_length_present = 0x00;
}
// Encode Content-length header
// Encode Content-Length header
if (_ec.length != 0) {
p_encoding_buffer.put_cs(int2str(_ec.length + 2/*Stand for the last CRLF*/));
_ec.is_content_length_present = 0x01;
......@@ -300,7 +300,7 @@ int http_codec::encode_response (const LibItsHttp__TypesAndValues::Response& p_r
p_encoding_buffer.put_cs("0");
_ec.is_content_length_present = 0x00;
}
loggers::get_instance().log("http_codec::encode_response: Content-length: %d - %x", _ec.length, _ec.is_content_length_present);
loggers::get_instance().log("http_codec::encode_response: Content-Length: %d - %x", _ec.length, _ec.is_content_length_present);
p_encoding_buffer.put_cs("\r\n");
p_encoding_buffer.put_cs("\r\n");
......@@ -370,6 +370,7 @@ int http_codec::decode_header(CHARSTRING& header_line, LibItsHttp__TypesAndValue
} else if (m[1].str().compare("Transfer-Encoding") == 0) {
if (m[2].str().find("chunked") != std::string::npos) {
_dc.chunked = true;
loggers::get_instance().log("http_codec::decode_header: decoded Transfer-Encoding %x", _dc.chunked);
}
}
......@@ -431,7 +432,7 @@ int http_codec::encode_body(const LibItsHttp__MessageBodyTypes::HttpMessageBody&
} else {
std::map<std::string, std::unique_ptr<codec<Record_Type, Record_Type> > >::const_iterator it;
bool processed = false;
loggers::get_instance().log("http_codec::encode_body: Content-type:'%s'", p_content_type.c_str());
loggers::get_instance().log("http_codec::encode_body: Content-Type:'%s'", p_content_type.c_str());
if (p_content_type.find("held") != std::string::npos) {
it = _codecs.find("held"); // TODO Use params
if (it != _codecs.cend()) {
......@@ -515,26 +516,45 @@ int http_codec::decode_body(TTCN_Buffer& decoding_buffer, LibItsHttp__MessageBod
}
loggers::get_instance().log("http_codec::decode_body: counter=%d", counter);
body = OCTETSTRING(body.lengthof() - counter, static_cast<const unsigned char*>(body));
if (_dc.chunked) {
// Extract the size of the chunk <chunk size>\r[\n]
if (_dc.chunked){
counter = 0;
while (counter < body.lengthof()) {
if ((body[counter].get_octet() == '\r') || (body[counter].get_octet() == '\n')) {
break;
}
counter += 1;
} // End of 'while' statement
loggers::get_instance().log("http_codec::decode_body: Chunked: counter=%d", counter);
if (counter < body.lengthof()) { // Skip additional \n
OCTETSTRING os(counter - 1, static_cast<const unsigned char*>(body));
loggers::get_instance().log_msg("http_codec::decode_body: os: ", os);
int len = oct2int(os);
loggers::get_instance().log("http_codec::decode_body: Chunk len: %d", len);
if (body[counter].get_octet() == '\n') {
int prev = 0;
OCTETSTRING os(0, nullptr);
do {
while (counter < body.lengthof()) { // Extract the size of the chunk <chunk size>\r[\n]
if ((body[counter].get_octet() == '\r') || (body[counter].get_octet() == '\n')) {
break;
}
counter += 1;
} // End of 'while' statement
loggers::get_instance().log("http_codec::decode_body: Chunked(0): prev = %d, counter=%d / %d", prev, counter, body.lengthof());
if (counter < body.lengthof()) {
int idx = counter - prev;
OCTETSTRING trunk(idx, static_cast<const unsigned char*>(body));
loggers::get_instance().log_msg("http_codec::decode_body: trunk: ", trunk);
std::string str((const char*)static_cast<const unsigned char*>(trunk), idx);
loggers::get_instance().log("http_codec::decode_body: str: '%s'", str.c_str());
int len = std::stoi(str, nullptr, 16);//converter::get_instance().string_to_int(str);
loggers::get_instance().log("http_codec::decode_body: Chunk len: %d", len);
while (counter < body.lengthof() && ((body[counter].get_octet() == '\r') || (body[counter].get_octet() == '\n'))) { // Skip additional \n
counter += 1;
} // End of 'while' statement
if (counter < body.lengthof()) {
loggers::get_instance().log("http_codec::decode_body: Chunked (1): prev = %d, counter=%d / %d", prev, counter, body.lengthof());
os += OCTETSTRING(len, counter + static_cast<const unsigned char*>(body));
loggers::get_instance().log_msg("http_codec::decode_body: os=", os);
counter += len;
loggers::get_instance().log("http_codec::decode_body: Chunked: %02x %02x %02x", body[counter].get_octet(), body[counter + 1].get_octet(), body[counter + 2].get_octet());
loggers::get_instance().log("http_codec::decode_body: Chunked (2): prev = %d, counter=%d / %d", prev, counter, body.lengthof());
while (counter < body.lengthof() && ((body[counter].get_octet() == '\r') || (body[counter].get_octet() == '\n'))) { // Skip additional \n
counter += 1;
} // End of 'while' statement
prev = counter;
loggers::get_instance().log("http_codec::decode_body: Chunked (3): prev = %d, counter=%d / %d", prev, counter, body.lengthof());
}
}
body = OCTETSTRING(len, counter + static_cast<const unsigned char*>(body));
}
} while (counter < body.lengthof()); // Process next chunk if any
body = os;
}
loggers::get_instance().log_msg("http_codec::decode_body: Finalised body=", body);
// Check if HTTP message body contains binary characters
......
......@@ -149,21 +149,23 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
p_files.erase(it);
// Load private key file
OCTETSTRING private_key;
p = p.replace_extension(_privateKeyExt);
loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching private keys '%s'", p.string().c_str());
is.open(p, ios::in | ios::binary);
if (!is.is_open()) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Failed to open Private key");
return -1;
}
int size = std::experimental::filesystem::file_size(p);
if ((size != 32) && (size != 48)) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Private key size is incorrect for '%s'", key.c_str());
return -1;
private_key = OCTETSTRING(0, nullptr);
} else {
int size = std::experimental::filesystem::file_size(p);
if ((size != 32) && (size != 48)) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Private key size is incorrect for '%s'", key.c_str());
return -1;
}
private_key = int2oct(0, size);
is.read((char *)static_cast<const unsigned char*>(private_key), private_key.lengthof());
is.close();
}
OCTETSTRING private_key = int2oct(0, size);
is.read((char *)static_cast<const unsigned char*>(private_key), private_key.lengthof());
is.close();
// Load private encryption key file if present
OCTETSTRING private_enc_key;
......@@ -174,7 +176,7 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Failed to open Private encryption key file");
private_enc_key = OCTETSTRING(0, nullptr);
} else {
size = std::experimental::filesystem::file_size(p);
int size = std::experimental::filesystem::file_size(p);
if (size != 32) { // IEEE Std 1609.2 2017: NistP256 or BrainpoolP256r1
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Private encryption key size is incorrect for '%s'", key.c_str());
return -1;
......
......@@ -23,8 +23,8 @@ using namespace std; // Required for isnan()
#include "loggers.hh"
bool security_cache_comp::operator()(const OCTETSTRING& p_lhs, const OCTETSTRING& p_rhs) const {
loggers::get_instance().log_msg(">>> security_cache_comp::operator(): p_lhs= ", p_lhs);
loggers::get_instance().log_msg(">>> security_cache_comp::operator(): p_rhs= ", p_rhs);
//loggers::get_instance().log_msg(">>> security_cache_comp::operator(): p_lhs= ", p_lhs);
//loggers::get_instance().log_msg(">>> security_cache_comp::operator(): p_rhs= ", p_rhs);
unsigned char* first1 = (unsigned char*)static_cast<const unsigned char*>(p_lhs);
unsigned char* first2 = (unsigned char*)static_cast<const unsigned char*>(p_rhs);
unsigned char* last1 = p_lhs.lengthof() + (unsigned char*)static_cast<const unsigned char*>(p_lhs);
......@@ -59,7 +59,7 @@ int security_cache::clear() {
return 0;
} // End of clear method
int security_cache::get_certificate_id(const OCTETSTRING& p_hashed_id8, std::string& p_certifcate_id) const {
int security_cache::get_certificate_id(const OCTETSTRING& p_hashed_id8, std::string& p_certificate_id) const {
loggers::get_instance().log_msg(">>> security_cache::get_certificate_id: ", p_hashed_id8);
std::map<OCTETSTRING, std::string>::const_iterator it = _hashed_id8s.find(p_hashed_id8);
......@@ -67,10 +67,10 @@ int security_cache::get_certificate_id(const OCTETSTRING& p_hashed_id8, std::str
//std::map<std::vector<unsigned char>, std::string>::const_iterator it = _hashed_id8s.find(v);
if (it == _hashed_id8s.cend()) {
dump();
p_certifcate_id = "";
p_certificate_id = "";
return -1;
}
p_certifcate_id = it->second;
p_certificate_id = it->second;
return 0;
}
......@@ -91,7 +91,7 @@ int security_cache::get_certificate(const std::string& p_certificate_id, OCTETST
int security_cache::get_certificate(const std::string& p_certificate_id, IEEE1609dot2::CertificateBase& p_certificate) const {
loggers::get_instance().log(">>> security_cache::get_certificate: '%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_certificate: record not found");
......@@ -102,6 +102,65 @@ int security_cache::get_certificate(const std::string& p_certificate_id, IEEE160
return 0;
}
int security_cache::get_certificate(const OCTETSTRING& p_hashed_id3, IEEE1609dot2::CertificateBase& p_certificate) const {
loggers::get_instance().log_msg(">>> security_cache::get_certificate: ", p_hashed_id3);
std::map<OCTETSTRING, std::string, security_cache_comp>::const_iterator s;
for (s = _hashed_id8s.cbegin(); s != _hashed_id8s.cend(); ++s) {
if (
(p_hashed_id3[2] == (s->first)[(s->first).lengthof() - 1]) &&
(p_hashed_id3[1] == (s->first)[(s->first).lengthof() - 2]) &&
(p_hashed_id3[0] == (s->first)[(s->first).lengthof() - 3])
) {
break;
}
} // End of 'for' statement
if (s == _hashed_id8s.cend()) {
loggers::get_instance().warning("security_cache::get_certificate: hashedId3 does not match");
return -1;
}
/*TODO std::map<OCTETSTRING, std::string, security_cache_comp>::const_iterator s = std::find_if(
_hashed_id8s.cbegin(),
_hashed_id8s.cend(),
hashed_id_matching
);*/
std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(s->second);
if (it == _certificates.cend()) {
loggers::get_instance().warning("security_cache::get_certificate: record not found");
return -1;
}
p_certificate = it->second.get()->decoded_certificate();
return 0;
}
int security_cache::get_certificate_hashed_id3(const OCTETSTRING& p_hashed_id3, std::string& p_certificate_id) const {
loggers::get_instance().log_msg(">>> security_cache::get_certificate_hashed_id3: ", p_hashed_id3);
std::map<OCTETSTRING, std::string, security_cache_comp>::const_iterator s;
for (s = _hashed_id8s.cbegin(); s != _hashed_id8s.cend(); ++s) {
if (
(p_hashed_id3[2] == (s->first)[(s->first).lengthof() - 1]) &&
(p_hashed_id3[1] == (s->first)[(s->first).lengthof() - 2]) &&
(p_hashed_id3[0] == (s->first)[(s->first).lengthof() - 3])
) {
break;
}
} // End of 'for' statement
if (s == _hashed_id8s.cend()) {
loggers::get_instance().warning("security_cache::get_certificate_hashed_id3: hashedId3 does not match");
return -1;
}
/*TODO std::map<OCTETSTRING, std::string, security_cache_comp>::const_iterator s = std::find_if(
_hashed_id8s.cbegin(),
_hashed_id8s.cend(),
hashed_id_matching
);*/
p_certificate_id = s->second;
return 0;
}
int security_cache::get_issuer(const std::string& p_certificate_id, OCTETSTRING& p_hashed_id_issuer) const {
loggers::get_instance().log(">>> security_cache::get_issuer: '%s'", p_certificate_id.c_str());
......
......@@ -52,6 +52,8 @@ public: /*! \publicsection */
int get_certificate_id(const OCTETSTRING& p_hashed_id8, std::string& p_certificate_id) const;
int get_certificate(const std::string& p_certificate_id, OCTETSTRING& p_certificate) const;
int get_certificate(const std::string& p_certificate_id, IEEE1609dot2::CertificateBase& p_certificate) const;
int get_certificate(const OCTETSTRING& p_hashed_id3, IEEE1609dot2::CertificateBase& p_certificate) const;
int get_certificate_hashed_id3(const OCTETSTRING& p_hashed_id3, std::string& p_certificate_id) 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;
......
......@@ -23,7 +23,7 @@ using namespace std; // Required for isnan()
security_services * security_services::instance = nullptr;
security_services::security_services() : _setup_done{false}, _ec_keys_enc(nullptr), _security_cache(new security_cache), _security_db(nullptr), _last_generation_time(0), _unknown_certificate(0, nullptr), _latitude(0), _longitude(0), _elevation(0) {
security_services::security_services() : _setup_done{false}, _ec_keys_enc(nullptr), _security_cache(new security_cache), _security_db(nullptr), _last_generation_time(0), _unknown_certificate(0, nullptr), _requested_certificate(), _latitude(0), _longitude(0), _elevation(0) {
loggers::get_instance().log(">>> security_services::security_services");
} // End of ctor
......@@ -176,8 +176,13 @@ int security_services::process_ieee_1609_dot2_signed_data(const IEEE1609dot2::Si
// Check request certificate
if (header_info.inlineP2pcdRequest().is_present()) {
loggers::get_instance().error("security_services::process_ieee_1609_dot2_signed_data: inlineP2pcdRequest not supported yet");
// TODO
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: inlineP2pcdRequest: ", header_info.inlineP2pcdRequest());
const IEEE1609dot2BaseTypes::SequenceOfHashedId3& s = static_cast<const IEEE1609dot2BaseTypes::SequenceOfHashedId3&>(*header_info.inlineP2pcdRequest().get_opt_value());
_requested_certificate.clear();
for (int i = 0; i < s.lengthof(); i++) {
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: Add requested certificate= ", s[i]);
_requested_certificate.push_back(s[i]);
} // End of 'for' statement
}
// Check requested certificate
......@@ -505,8 +510,15 @@ int security_services::sign_payload(const OCTETSTRING& p_unsecured_gn_payload, O
} else {
header_info.inlineP2pcdRequest().set_to_omit();
}
header_info.requestedCertificate().set_to_omit();
if (_requested_certificate.size() != 0) {
IEEE1609dot2::CertificateBase c;
const IEEE1609dot2BaseTypes::HashedId3& hashed_id3 = _requested_certificate[0];
_security_db->get_certificate(hashed_id3, c);
header_info.requestedCertificate() = OPTIONAL<IEEE1609dot2::CertificateBase>(c);
} else {
header_info.requestedCertificate().set_to_omit();
}
IEEE1609dot2::ToBeSignedData tbs_data;
tbs_data.payload() = payload;