Newer
Older
#include <chrono>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include "security_services.hh"
#include "EtsiTs103097Codec_ToBeSignedData.hh"
#include "EtsiTs103097Codec_Data.hh"
#include "sha256.hh"
#include "sha384.hh"
#include "ec_keys.hh"
#include "Params.hh"
#include "loggers.hh"
#include "converter.hh"
security_services * security_services::instance = nullptr;
security_services::security_services() : _ec_keys(nullptr), _security_cache(new security_cache), _security_db(nullptr), _last_generation_time(0), _unknown_certificate(), _latitude(0), _longitude(0), _elevation(0) {
loggers::get_instance().log(">>> security_services::security_services");
} // End of ctor
int security_services::setup(Params& p_params) { // FIXME Rename this method
loggers::get_instance().log("security_services::setup");
p_params.log();
_security_db.reset(new security_db(p_params[Params::sec_db_path]));
if (_security_db.get() == nullptr) { // Memory allocation issue
return -1;
}
return 0;
}
int security_services::store_certificate(const CHARSTRING& p_cert_id, const OCTETSTRING& p_cert, const OCTETSTRING& p_private_key, const OCTETSTRING& p_public_key_x, const OCTETSTRING& p_public_key_y, const OCTETSTRING& p_hashid8, const OCTETSTRING& p_issuer) {
loggers::get_instance().log_msg(">>> security_services::store_certificate: ", p_cert_id);
// Sanity checks
if (_security_db.get() == nullptr) { // Setup not called
loggers::get_instance().warning("security_services::store_certificate: Not initialized");
return -1;
}
return _security_db.get()->store_certificate(p_cert_id, p_cert, p_private_key, p_public_key_x, p_public_key_y, p_hashid8, p_issuer);
}
int security_services::verify_and_extract_gn_payload(const OCTETSTRING& p_secured_gn_payload, const bool p_verify, OCTETSTRING& p_unsecured_gn_payload, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::verify_and_extract_gn_payload: ", p_secured_gn_payload);
// Sanity checks
if (p_secured_gn_payload.lengthof() == 0) {
return -1;
}
// Decode the secured message (OER encoding)
IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data;
EtsiTs103097Codec_Data codec;
codec.decode(p_secured_gn_payload, ieee_1609dot2_data, &p_params);
loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Unbound value, discard it");
return -1;
}
if (p_verify && ((unsigned int)(int)ieee_1609dot2_data.protocolVersion() != security_services::ProtocolVersion)) {
loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Wrong version protocol, discard it");
return -1;
return process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_gn_payload, p_params);
} // End of method verify_and_extract_gn_payload
int security_services::process_ieee_1609_dot2_content(const IEEE1609dot2::Ieee1609Dot2Content& p_ieee_1609_dot2_content, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_content: ", p_ieee_1609_dot2_content);
if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_unsecuredData)) { // Unsecured packet, End of recursivity
p_unsecured_payload = p_ieee_1609_dot2_content.unsecuredData();
} else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_signedData)) {
const IEEE1609dot2::SignedData& signedData = p_ieee_1609_dot2_content.signedData();
if (process_ieee_1609_dot2_signed_data(signedData, p_verify, p_unsecured_payload, p_params) != 0) {
return -1;
}
} else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_encryptedData)) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_content: Unsupported IEEE 1609.2 Content, discard it");
return -1;
} else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_signedCertificateRequest)) {
// TODO Set Certificate re-transmission flag and reset timer
loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Set Certificate re-transmission flag and reset timer");
return 0;
} else { // Shall never be reached
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_content: Undefined IEEE 1609.2 Content, discard it");
loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_content: ", p_unsecured_payload);
return 0;
} // End of method process_ieee_1609_dot2_content
int security_services::process_ieee_1609_dot2_signed_data(const IEEE1609dot2::SignedData& p_signed_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_signed_data: ", p_signed_data);
// Check and extract unsecured payload
if (p_signed_data.tbsData().payload().data().is_present()) {
// Check protocol version
const OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data>& v = dynamic_cast<const OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data>& >(p_signed_data.tbsData().payload().data());
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: SignedDataPayload.data = ", v);
const IEEE1609dot2::Ieee1609Dot2Data& ieee_1609dot2_data = static_cast<const IEEE1609dot2::Ieee1609Dot2Data&>(*v.get_opt_value());
if (p_verify && ((unsigned int)(int)ieee_1609dot2_data.protocolVersion() != security_services::ProtocolVersion)) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Wrong version protocol, discard it");
return -1;
}
if (process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_payload, p_params) != 0) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to process SignedData, discard it");
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
return -1;
}
} else if (p_signed_data.tbsData().payload().extDataHash().is_present()) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported extDataHash, discard it");
return -1;
} else { // Shall not be reached
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported SignedDataPayload, discard it");
return -1;
}
// Encode the ToBeSignedData
EtsiTs103097Codec_ToBeSignedData tbs_data_codec;
OCTETSTRING os;
tbs_data_codec.encode(p_signed_data.tbsData(), os);
if (os.lengthof() == 0) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to encode ToBeSignedData");
return -1;
}
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: encoded tbs_data = ", os);
// Calculate the hash according to the hashId
OCTETSTRING hashed_data;
int result = -1;
if (p_signed_data.hashId() == IEEE1609dot2BaseTypes::HashAlgorithm::sha256) {
result = hash_sha256(os, hashed_data);
} else {
result = hash_sha384(os, hashed_data);
}
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: hashed_data = ", hashed_data);
if (result != 0) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to create hash");
return -1;
}
// Retrieve certificate identifier
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: signer = ", p_signed_data.signer());
std::string certificate_id;
result = -1;
if (p_signed_data.signer().ischosen(IEEE1609dot2::SignerIdentifier::ALT_digest)) {
// Retrieve the certificate identifier from digest
loggers::get_instance().log("security_services::process_ieee_1609_dot2_signed_data: Retrieve the certificate identifier from digest");
result = _security_db.get()->get_certificate_id(p_signed_data.signer().digest(), certificate_id);
if (result == -1) {
// Check in the cache
if (_security_cache.get()->get_certificate_id(p_signed_data.signer().digest(), certificate_id) == -1) {
loggers::get_instance().log("security_services::process_ieee_1609_dot2_signed_data: Unknown certificate, request it");
// Unknown certificate, request it
const OCTETSTRING& os = p_signed_data.signer().digest();
_unknown_certificate.resize(3);
const unsigned char* p = static_cast<const unsigned char*>(os) + os.lengthof() - 3;
for (int i = 0; i < 3; i++) {
_unknown_certificate[i] = *(p + i);
} // End of 'for' statement
loggers::get_instance().log_to_hexa("security_services::process_ieee_1609_dot2_signed_data: HashedId3: ", _unknown_certificate.data(), _unknown_certificate.size());
}
}
} else if (p_signed_data.signer().ischosen(IEEE1609dot2::SignerIdentifier::ALT_certificate)) {
IEEE1609dot2::CertificateBase cert = p_signed_data.signer().certificate()[0];
// TODO Verify signature
/* Encode the ToBeSignedCertificate
EtsiTs103097Codec_ToBeSignedData tbs_cert;
OCTETSTRING os;
tbs_cert.encode(cert.toBeSigned(), os);
if (os.lengthof() == 0) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to encode ToBeSignedCertificate");
return -1;
}
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: encoded ToBeSignedCertificate = ", os);
// Calculate the hash according to the hashId
OCTETSTRING hashed_data;
int result = -1;
if (p_signed_data.hashId() == IEEE1609dot2BaseTypes::HashAlgorithm::sha256) {
result = hash_sha256(os, hashed_data);
} else {
result = hash_sha384(os, hashed_data);
}*/
// TODO Verify signature
if (cert.issuer().ischosen(IEEE1609dot2::IssuerIdentifier::ALT_sha256AndDigest)) {
result = _security_db.get()->get_certificate_id_by_issuer(cert.issuer().sha256AndDigest(), certificate_id);
if (result == -1) {
if (_security_cache.get()->get_certificate_id_by_issuer(cert.issuer().sha256AndDigest(), certificate_id) == -1) {
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: Store new certificate in cache: ", cert);
// TODO Add it into the cache
// certificate_id = ;
// _security_cache.get()->store_certificate();
}
}
} else if (cert.issuer().ischosen(IEEE1609dot2::IssuerIdentifier::ALT_sha384AndDigest)) {
result = _security_db.get()->get_certificate_id_by_issuer(cert.issuer().sha384AndDigest(), certificate_id);
if (result == -1) {
if (_security_cache.get()->get_certificate_id_by_issuer(cert.issuer().sha384AndDigest(), certificate_id) == -1) {
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: Store new certificate in cache: ", cert);
// TODO Add it into the cache
// certificate_id = ;
// _security_cache.get()->store_certificate();
}
}
}
else {
loggers::get_instance().error("security_services::process_ieee_1609_dot2_signed_data: Unsupported certificate issuer");
return -1;
}
} else {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported SignerIdentifier");
return -1;
}
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Certificate not found for the specified signer, it will be requested");
loggers::get_instance().log("security_services::process_ieee_1609_dot2_signed_data: certificate id = '%s'", certificate_id.c_str());
// Verify the signature of the ToBeSignedData
loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: signature = ", p_signed_data.signature__());
result = -1;
if (p_signed_data.signature__().ischosen(IEEE1609dot2BaseTypes::Signature::ALT_ecdsaNistP256Signature)) {
result = verify_sign_ecdsa_nistp256(hashed_data, p_signed_data.signature__(), certificate_id, p_params);
} else {
// TODO
loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO");
}
if (result != 0) {
loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to verify signature");
return -1;
}
loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_signed_data: ", p_unsecured_payload);
return 0;
} // End of method process_ieee_1609_dot2_signed_data
int security_services::process_ieee_1609_dot2_encrypted_data(const IEEE1609dot2::EncryptedData& p_encrypted_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_encrypted_data: ", p_encrypted_data);
//loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_encrypted_data: ", p_unsecured_payload);
} // End of method process_ieee_1609_dot2_encrypted_data
int security_services::secure_gn_payload(const OCTETSTRING& p_unsecured_gn_payload, OCTETSTRING& p_secured_gn_payload, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::secure_gn_payload: ", p_unsecured_gn_payload);
// Set unsecured data
IEEE1609dot2::Ieee1609Dot2Content unsecured_data_content;
unsecured_data_content.unsecuredData() = p_unsecured_gn_payload;
IEEE1609dot2::Ieee1609Dot2Data unsecured_data(ProtocolVersion, unsecured_data_content);
// Set hash algorithm
IEEE1609dot2BaseTypes::HashAlgorithm hashId(IEEE1609dot2BaseTypes::HashAlgorithm::sha256);
if (p_params[Params::hash].compare("SHA-384") == 0) {
hashId = IEEE1609dot2BaseTypes::HashAlgorithm::sha384;
}
// Set SignedDataPayload
IEEE1609dot2::SignedDataPayload payload;
payload.data() = unsecured_data;
payload.extDataHash().set_to_omit();
IEEE1609dot2::HeaderInfo header_info;
header_info.psid() = converter::get_instance().string_to_int(p_params[Params::its_aid]);
header_info.expiryTime().set_to_omit();
header_info.generationLocation().set_to_omit();
header_info.p2pcdLearningRequest().set_to_omit();
header_info.missingCrlIdentifier().set_to_omit();
header_info.encryptionKey().set_to_omit();
Params::const_iterator it = p_params.find(Params::payload_type);
if (it != p_params.cend()) {
loggers::get_instance().log("security_services::secure_gn_payload: Payload type: %s", it->second.c_str());
OPTIONAL<IEEE1609dot2BaseTypes::ThreeDLocation> location(IEEE1609dot2BaseTypes::ThreeDLocation(_latitude, _longitude, _elevation));
loggers::get_instance().log_msg("security_services::secure_gn_payload: generationLocation: ", location);
header_info.generationLocation() = location;
loggers::get_instance().log_msg("security_services::secure_gn_payload: generationLocation: ", header_info.generationLocation());
} else if (it->second.compare("2") == 0) { // CAM
// Noting to do
} else {
// Noting to do
}
} else { // Process it as a GeoNetworking payload
loggers::get_instance().log("security_services::secure_gn_payload: Payload type not set");
// Noting to do
}
unsigned long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - 1072911600000L; // TODO Add method such as its_tme() & its_time_mod() beacuse it is used also in LibItsCommon_externals
INTEGER i;
i.set_long_long_val((unsigned int)ms);
header_info.generationTime() = OPTIONAL<INTEGER>(i);
// Check if a certificate shall be requested
if (_unknown_certificate.size() == 3) { // HashedId3
IEEE1609dot2BaseTypes::SequenceOfHashedId3 s;
s[0] = OCTETSTRING(_unknown_certificate.size(), _unknown_certificate.data());
header_info.inlineP2pcdRequest() = OPTIONAL<IEEE1609dot2BaseTypes::SequenceOfHashedId3>(s);
_unknown_certificate.clear();
} else {
header_info.inlineP2pcdRequest().set_to_omit();
}
header_info.requestedCertificate().set_to_omit();
IEEE1609dot2::ToBeSignedData tbs_data;
tbs_data.payload() = payload;
tbs_data.headerInfo() = header_info;
loggers::get_instance().log_msg("security_services::secure_gn_payload: tbs_data = ", tbs_data);
// Sign the ToBeSignedData data structure
IEEE1609dot2BaseTypes::Signature signature;
if (sign_tbs_data(tbs_data, hashId, signature, p_params) != 0) {
loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
return -1;
}
IEEE1609dot2::SignerIdentifier signer;
loggers::get_instance().log("security_services::secure_gn_payload: ms = %d - _last_generation_time = %d - ms - _last_generation_time = %d", (unsigned int)ms, _last_generation_time, (unsigned int)(ms - _last_generation_time));
std::string certificate_id = p_params[Params::certificate] + "_AT";
loggers::get_instance().log("security_services::secure_gn_payload: certificate_id = %s", certificate_id.c_str());
if ((unsigned int)(ms - _last_generation_time) >= 1000 * 0.95) { // Need to add certificate
IEEE1609dot2::CertificateBase cert;
if (_security_db->get_certificate(certificate_id, cert) != 0) {
loggers::get_instance().warning("security_services:secure_gn_payload: Failed to secure payload");
return -1;
}
IEEE1609dot2::SequenceOfCertificate sequenceOfCertificate;
sequenceOfCertificate[0] = cert;
signer.certificate() = sequenceOfCertificate;
// Reset send certificate timer
_last_generation_time = ms;
} else {
if (_security_db->get_hashed_id(certificate_id, digest) != 0) {
loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
return -1;
}
signer.digest() = digest;
}
IEEE1609dot2::SignedData signed_data(
hashId,
tbs_data,
signer,
signature
);
loggers::get_instance().log_msg("security_services::secure_gn_payload: signed_data = ", signed_data);
IEEE1609dot2::Ieee1609Dot2Content ieee_dot2_content;
ieee_dot2_content.signedData() = signed_data;
IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data(
security_services::ProtocolVersion,
ieee_dot2_content
);
loggers::get_instance().log_msg("security_services::secure_gn_payload: ieee_1609dot2_data = ", ieee_1609dot2_data);
EtsiTs103097Codec_Data codec;
codec.encode(ieee_1609dot2_data, p_secured_gn_payload);
if (!p_secured_gn_payload.is_bound()) {
loggers::get_instance().warning("security_services::secure_gn_payload: Failed to encode Ieee1609Dot2Data");
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
return -1;
}
return 0;
}
int security_services::sign_tbs_data(const IEEE1609dot2::ToBeSignedData& p_tbs_data, const IEEE1609dot2BaseTypes::HashAlgorithm& p_hashAlgorithm, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::sign_tbs_data: ", p_tbs_data);
// Encode the ToBeSignedData
EtsiTs103097Codec_ToBeSignedData tbs_data_codec;
OCTETSTRING os;
tbs_data_codec.encode(p_tbs_data, os);
if (os.lengthof() == 0) {
loggers::get_instance().warning("security_services::sign_tbs_data: Failed to encode ToBeSignedData");
return -1;
}
loggers::get_instance().log_msg("security_services::sign_tbs_data: encoded tbs_data = ", os);
// Hash ToBeSignedData
OCTETSTRING hashed_data;
int result = -1;
if (p_hashAlgorithm == IEEE1609dot2BaseTypes::HashAlgorithm::sha256) {
result = hash_sha256(os, hashed_data);
} else {
result = hash_sha384(os, hashed_data);
}
loggers::get_instance().log_msg("security_services::sign_tbs_data: encoded hashed_data = ", hashed_data);
if (result != 0) {
loggers::get_instance().warning("security_services::sign_tbs_data: Failed to create hash");
return -1;
}
// Sign ToBeSignedData
result = -1;
loggers::get_instance().log("security_services::sign_tbs_data: encoded Params::signature = '%s'", p_params[Params::signature].c_str());
loggers::get_instance().log("security_services::sign_tbs_data: encoded Params::certificate = '%s'", p_params[Params::certificate].c_str());
if (p_params[Params::signature].compare("NISTP-256") == 0) {
result = sign_ecdsa_nistp256(hashed_data, p_signature, p_params);
} else if (p_params[Params::signature].compare("BP-256") == 0) {
//result = sign_ecdsa_brainpoolp256(hashed_data, p_signature, p_params);
loggers::get_instance().error("security_services::sign_tbs_data: TODO");
result = -1;
} else if (p_params[Params::signature].compare("BP-384") == 0) {
//result = sign_ecdsa_brainpoolp256(hashed_data, p_signature, p_params);
loggers::get_instance().error("security_services::sign_tbs_data: TODO");
result = -1;
} else {
loggers::get_instance().error("security_services::sign_tbs_data: Unsupported signature algorithm");
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
if (result != 0) {
loggers::get_instance().warning("security_services::sign_tbs_data: Failed to sign payload");
return -1;
}
return 0;
}
int security_services::hash_sha256(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data) {
loggers::get_instance().log_msg(">>> security_services::hash_sha256: ", p_data);
sha256 hash;
std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p_data), p_data.lengthof() + static_cast<const unsigned char *>(p_data));
std::vector<unsigned char> hashData;
hash.generate(tbh, hashData);
p_hash_data = OCTETSTRING(hashData.size(), hashData.data());
return 0;
}
int security_services::hash_sha384(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data) {
loggers::get_instance().log_msg(">>> security_services::hash_sha384: ", p_data);
sha384 hash;
std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p_data), p_data.lengthof() + static_cast<const unsigned char *>(p_data));
std::vector<unsigned char> hashData;
hash.generate(tbh, hashData);
p_hash_data = OCTETSTRING(hashData.size(), hashData.data());
return 0;
}
int security_services::sign_ecdsa_nistp256(const OCTETSTRING& p_hash, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::sign_ecdsa_nistp256: ", p_hash);
std::string certificate_id = p_params[Params::certificate] + "_AT"; // FIXME Specified strictly the naming of the certificate files
loggers::get_instance().log("security_services::sign_ecdsa_nistp256: encoded certificate_id = '%s'", certificate_id.c_str());
if (_security_db->get_private_key(certificate_id, pkey) != 0) {
loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to get private key");
return -1;
}
std::vector<unsigned char> private_key(static_cast<const unsigned char *>(pkey), static_cast<const unsigned char *>(pkey) + pkey.lengthof());
OCTETSTRING public_key_x;
OCTETSTRING public_key_y;
if (_security_db->get_public_keys(certificate_id, public_key_x, public_key_y) != 0) {
loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to get public keys");
return -1;
}
std::vector<unsigned char> hashed_data(static_cast<const unsigned char *>(p_hash), static_cast<const unsigned char *>(p_hash) + p_hash.lengthof());
ec_keys k(ec_elliptic_curves::nist_p_256, private_key);
std::vector<unsigned char> r_sig;
std::vector<unsigned char> s_sig;
if (k.sign(hashed_data, r_sig, s_sig) != 0) {
loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to sign payload");
return -1;
}
IEEE1609dot2BaseTypes::EccP256CurvePoint ep;
ep.x__only() = OCTETSTRING(r_sig.size(), r_sig.data());
p_signature.ecdsaNistP256Signature() = IEEE1609dot2BaseTypes::EcdsaP256Signature(
ep,
);
loggers::get_instance().log_msg("security_services::sign_ecdsa_nistp256: signature = ", p_signature);
return 0;
}
int security_services::verify_sign_ecdsa_nistp256(const OCTETSTRING& p_hash, const IEEE1609dot2BaseTypes::Signature& p_signature, const std::string& p_certificate_id, Params& p_params) {
loggers::get_instance().log_msg(">>> security_services::verify_sign_ecdsa_nistp256: ", p_hash);
OCTETSTRING public_key_x;
OCTETSTRING public_key_y;
if (_security_db->get_public_keys(p_certificate_id, public_key_x, public_key_y) != 0) {
loggers::get_instance().warning("security_services::verify_sign_ecdsa_nistp256: Failed to get public keys");
return -1;
}
std::vector<unsigned char> hashData(static_cast<const unsigned char *>(p_hash), static_cast<const unsigned char *>(p_hash) + p_hash.lengthof());
OCTETSTRING os;
if (p_signature.ecdsaNistP256Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_x__only)) {
os = p_signature.ecdsaNistP256Signature().rSig().x__only() + p_signature.ecdsaNistP256Signature().sSig();
} else if (p_signature.ecdsaNistP256Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
os = p_signature.ecdsaNistP256Signature().rSig().compressed__y__0() + p_signature.ecdsaNistP256Signature().sSig();
} else if (p_signature.ecdsaNistP256Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
os = p_signature.ecdsaNistP256Signature().rSig().compressed__y__1() + p_signature.ecdsaNistP256Signature().sSig();
} else if (p_signature.ecdsaNistP256Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
os = p_signature.ecdsaNistP256Signature().rSig().uncompressedP256().x() + p_signature.ecdsaNistP256Signature().rSig().uncompressedP256().y() + p_signature.ecdsaNistP256Signature().sSig();
} else {
loggers::get_instance().warning("security_services::verify_sign_ecdsa_nistp256: Invalid curve point");
return -1;
}
std::vector<unsigned char> signature(static_cast<const unsigned char *>(os), static_cast<const unsigned char *>(os) + os.lengthof());
std::vector<unsigned char> key_x(static_cast<const unsigned char *>(public_key_x), static_cast<const unsigned char *>(public_key_x) + public_key_x.lengthof());
std::vector<unsigned char> key_y(static_cast<const unsigned char *>(public_key_y), static_cast<const unsigned char *>(public_key_y) + public_key_y.lengthof());
ec_keys k(ec_elliptic_curves::nist_p_256, key_x, key_y);
if (k.sign_verif(hashData, signature) == 0) {
return 0;
}