Newer
Older
#include "pki_layer_factory.hh"
#include "codec_stack_builder.hh"
#include "loggers.hh"
#include "security_services.hh"
pki_layer::pki_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsPki__TestSystem::PkiPort>(p_type), _params(), _etsi_ts102941_types_enrolment_inner_request(), _etsi_ts102941_types_enrolment_inner_response(), _codec()
{
loggers::get_instance().log(">>> pki_layer::pki_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
// Sanity checks
params::const_iterator it = _params.find(params::certificate);
if (it == _params.cend()) {
_params[params::certificate] = "CERT_TS_A_EA";
}
it = _params.find(params::peer_certificate);
if (it == _params.cend()) {
_params[params::peer_certificate] = "CERT_IUT_A_EA";
_params[params::signature] = "NISTP-256"; // TODO Should be removed
_params[params::hash] = "SHA-256"; // TODO Should be removed
// Register this object for AdapterControlPort
loggers::get_instance().log("pki_layer::pki_layer: Register %s/%p", p_type.c_str(), this);
registration<pki_layer>::get_instance().add_item(p_type, this);
}
void pki_layer::sendMsg(const EtsiTs102941TypesEnrolment::InnerEcRequest& p_inner_ec_request, params& p_param) {
loggers::get_instance().log_msg(">>> pki_layer::sendMsg: ", p_inner_ec_request);
// Sanity checks
if (_ac_set_security_data.get() == nullptr) {
loggers::get_instance().error("pki_layer::sendMsg: Security data missing");
return;
}
OCTETSTRING inner_ec_request;
_etsi_ts102941_types_enrolment_inner_request.encode(p_inner_ec_request, inner_ec_request);
// Build the EtsiTs103097Data-Encrypted
if (generate_inner_ec_request_signed_for_pop(inner_ec_request, etsi_ts_102941_data, _params) == -1) {
loggers::get_instance().warning("pki_layer::sendMsg: Failed to generate InnerExRequestSignedForPop");
return;
send_data(etsi_ts_102941_data, _params);
void pki_layer::sendMsg(const EtsiTs102941TypesEnrolment::InnerEcResponse& p_inner_ec_response, params& p_param) {
loggers::get_instance().log_msg(">>> pki_layer::sendMsg: ", p_inner_ec_response);
_etsi_ts102941_types_enrolment_inner_response.encode(p_inner_ec_response, data);
if (sign_and_encrypt_payload(data, secured_data, p_param) == 0) {
send_data(data, _params);
}
}
void pki_layer::send_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg(">>> pki_layer::send_data: ", data);
send_to_all_layers(data, params);
}
void pki_layer::receive_data(OCTETSTRING& data, params& params)
{
loggers::get_instance().log_msg(">>> pki_layer::receive_data: ", data);
IEEE1609dot2::Ieee1609Dot2Data etsi_ts_1609dot2_data;
if (decrypt_and_check_signature(data, etsi_ts_1609dot2_data, _params) == -1) {
loggers::get_instance().warning("pki_layer::sendMsg: Failed to secure Pki message");
return;
}
// Pass it to the ports
//to_all_upper_ports(pki_message, params);
}
void pki_layer::set_pki_keys(const LibItsPki__TypesAndValues::AcSetSecurityData& p_ac_set_security_data) {
loggers::get_instance().log_msg(">>> pki_layer::set_pki_keys: ", p_ac_set_security_data);
_ac_set_security_data.reset(new LibItsPki__TypesAndValues::AcSetSecurityData(p_ac_set_security_data));
loggers::get_instance().log_msg("pki_layer::set_pki_keys: New data", *_ac_set_security_data);
_params[params::certificate] = p_ac_set_security_data.certificateId();
_params[params::peer_certificate] = p_ac_set_security_data.peer__certificateId();
int pki_layer::generate_inner_ec_request_signed_for_pop(const OCTETSTRING& p_inner_ec_request, OCTETSTRING& p_etsi_ts_102941_data, params& p_params) {
loggers::get_instance().log_msg(">>> pki_layer::generate_inner_ec_request_signed_for_pop: ", p_inner_ec_request);
// Re-configure default parameters
params p(p_params);
p[params::peer_certificate] = p[params::certificate]; // ETSI TS 102 941 Clause 6.2.3.2.1 Enrolment request
// Set unsecured data
IEEE1609dot2::Ieee1609Dot2Content unsecured_data_content;
unsecured_data_content.unsecuredData() = p_inner_ec_request;
IEEE1609dot2::Ieee1609Dot2Data unsecured_data(security_services::get_instance().get_protocol_version(), unsecured_data_content);
// Set hash algorithm
IEEE1609dot2BaseTypes::HashAlgorithm hashId(IEEE1609dot2BaseTypes::HashAlgorithm::sha256);
if (p[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::its_aid]);
unsigned long long ms = base_time::get_instance().get_its_current_time();
INTEGER i;
i.set_long_long_val((unsigned int)ms);
header_info.generationTime() = OPTIONAL<INTEGER>(i);
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();
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("pki_layer::generate_inner_ec_request_signed_for_pop: tbs_data = ", tbs_data);
// Sign the ToBeSignedData data structure using the private key of the requested certificate
loggers::get_instance().log_msg("pki_layer::generate_inner_ec_request_signed_for_pop: Private key = ", _ac_set_security_data->private__key());
if (security_services::get_instance().sign_tbs_data(tbs_data, hashId, _ac_set_security_data->private__key(), signature, p) != 0) {
loggers::get_instance().warning("pki_layer::generate_inner_ec_request_signed_for_pop: Failed to secure payload");
}
// Finalyse the EtsiTs103097Data-Signed
signer.self__() = ASN_NULL_VALUE;
IEEE1609dot2::SignedData signed_data(hashId, tbs_data, signer, signature);
loggers::get_instance().log_msg("pki_layer::generate_inner_ec_request_signed_for_pop: signed_data = ", signed_data);
IEEE1609dot2::Ieee1609Dot2Content ieee_dot2_content;
ieee_dot2_content.signedData() = signed_data;
IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data(pki_layer::ProtocolVersion, ieee_dot2_content);
loggers::get_instance().log_msg("pki_layer::generate_inner_ec_request_signed_for_pop: ieee_1609dot2_data = ", ieee_1609dot2_data);
// Create the EtsiTs102941Data layer (InnerEcRequestSignedForPop)
EtsiTs102941MessagesItss::EtsiTs102941Data etsi_ts_102941_data;
etsi_ts_102941_data.content().enrolmentRequest() = ieee_1609dot2_data;
loggers::get_instance().log_msg("pki_layer::generate_inner_ec_request_signed_for_pop: InnerEcRequestSignedForPop: ", etsi_ts_102941_data);
OCTETSTRING os;
_codec.encode(ieee_1609dot2_data, os);
if (!os.is_bound()) {
loggers::get_instance().warning("pki_layer::generate_inner_ec_request_signed_for_pop: Failed to encode InnerEcRequestSignedForPop");
return -1;
}
loggers::get_instance().log_msg("pki_layer::generate_inner_ec_request_signed_for_pop: ", os);
// Secured the EtsiTs102941Data layer
if (sign_and_encrypt_payload(os, p_etsi_ts_102941_data, p) == -1) {
loggers::get_instance().warning("pki_layer::generate_inner_ec_request_signed_for_pop: Failed to secure Pki message");
loggers::get_instance().log_msg("<<< pki_layer::generate_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data);
int pki_layer::sign_and_encrypt_payload(const OCTETSTRING& p_etsi_ts_102941_data, OCTETSTRING& p_secured_data, params& p_params) {
loggers::get_instance().log_msg(">>> pki_layer::sign_and_encrypt_payload: ", p_etsi_ts_102941_data);
// 1. Signed the data
OCTETSTRING signed_data;
if (security_services::get_instance().sign_payload(p_etsi_ts_102941_data, signed_data, p_params) == -1) {
loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::encode: Failed to sign data");
return -1;
loggers::get_instance().log_msg("pki_layer::sign_and_encrypt_payload: signed_data=", signed_data);
// 2. Encrypt the signed packet
if (security_services::get_instance().encrypt_gn_payload(signed_data, p_secured_data, p_params) == -1) {
loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::sign_and_encrypt_payload: Failed to encrypt data");
return -1;
}
loggers::get_instance().log_msg("<<< http_etsi_ieee1609dot2_codec::sign_and_encrypt_payload: ", p_secured_data);
return 0;
}
int pki_layer::decrypt_and_check_signature(const OCTETSTRING& p_signed_and_encrypted_data, IEEE1609dot2::Ieee1609Dot2Data& p_etsi_ts_1609dot2_data, params& p_params) {
loggers::get_instance().log_msg(">>> pki_layer::decrypt_and_check_signature: ", p_signed_and_encrypted_data);
// 1. Decrypt the Pki message
OCTETSTRING os;
if (security_services::get_instance().decrypt_gn_payload(p_signed_and_encrypted_data, os, p_params) == -1) {
loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::decrypt_and_check_signature: Failed to encrypt data");
}
pki_layer_factory pki_layer_factory::_f;