#include "pki_layer_factory.hh" #include "codec_stack_builder.hh" #include "loggers.hh" #include "base_time.hh" #include "registration.hh" #include "converter.hh" #include "security_services.hh" #include "pki_layer.hh" using namespace std; // Required for isnan() #include "LibItsPki_TypesAndValues.hh" #include "LibItsPki_TestSystem.hh" pki_layer::pki_layer(const std::string & p_type, const std::string & param) : t_layer(p_type), _params(), _etsi_ts102941_types_enrolment_inner_request(), _etsi_ts102941_types_enrolment_inner_response(), _etsi_ts102941_types_authorization_validation_request(), _etsi_ts102941_types_authorization_validation_response(), _codec(), _ac_set_security_data(nullptr) { 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::its_aid] = "2468"; _params[params::payload_type] = ""; _params[params::signature] = "NISTP-256"; // TODO Should be removed _params[params::encrypted_mode] = "1"; _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::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-Signed OCTETSTRING etsi_ts_103097_data; if (generate_inner_ec_request_signed_for_pop(inner_ec_request, etsi_ts_103097_data, _params) == -1) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to generate InnerExRequestSignedForPop"); return; } // Secured the EtsiTs102941Data layer OCTETSTRING etsi_ts_102941_data; if (sign_and_encrypt_payload(etsi_ts_103097_data, etsi_ts_102941_data, _params) == -1) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to secure Pki message"); return; } loggers::get_instance().log_msg("<<< pki_layer::sendMsg: ", etsi_ts_102941_data); 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); // Create the EtsiTs102941Data layer EtsiTs102941MessagesCa::EtsiTs102941Data etsi_ts_102941_data; etsi_ts_102941_data.content().enrolmentResponse() = p_inner_ec_response; loggers::get_instance().log_msg("pki_layer::sendMsg: InnerEcResponse: ", etsi_ts_102941_data); // Encode it OCTETSTRING etsi_ts_103097_data_enc; _codec_etsi_ts102941_data.encode(etsi_ts_102941_data, etsi_ts_103097_data_enc); if (!etsi_ts_103097_data_enc.is_bound()) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to encode InnerEcResponse"); } loggers::get_instance().log_msg("pki_layer::sendMsg: etsi_ts_103097_data_enc: ", etsi_ts_103097_data_enc); // Secured the EtsiTs102941Data layer OCTETSTRING secured_inner_ec_response; if (sign_and_encrypt_payload(etsi_ts_103097_data_enc, secured_inner_ec_response, p_param) == 0) { send_data(secured_inner_ec_response, _params); } loggers::get_instance().log_msg("<<< pki_layer::sendMsg: etsi_ts_102941_data:", secured_inner_ec_response); send_data(secured_inner_ec_response, _params); } void pki_layer::sendMsg(const EtsiTs102941TypesAuthorizationValidation::AuthorizationValidationRequest& p_authorization_validation_request, params& p_param) { loggers::get_instance().log_msg(">>> pki_layer::sendMsg: ", p_authorization_validation_request); // Sanity checks if (_ac_set_security_data.get() == nullptr) { loggers::get_instance().error("pki_layer::sendMsg: Security data missing"); return; } // Create the EtsiTs102941Data layer EtsiTs102941MessagesCa::EtsiTs102941Data etsi_ts_102941_data; etsi_ts_102941_data.content().authorizationValidationRequest() = p_authorization_validation_request; loggers::get_instance().log_msg("pki_layer::sendMsg: AuthorizationValidationRequest: ", etsi_ts_102941_data); // Encode it OCTETSTRING etsi_ts_103097_data_enc; _codec_etsi_ts102941_data.encode(etsi_ts_102941_data, etsi_ts_103097_data_enc); if (!etsi_ts_103097_data_enc.is_bound()) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to encode AuthorizationValidationRequest"); } loggers::get_instance().log_msg("pki_layer::sendMsg: etsi_ts_103097_data_enc: ", etsi_ts_103097_data_enc); // Secured the EtsiTs102941Data layer OCTETSTRING secured_authorization_validation_request; if (sign_and_encrypt_payload(etsi_ts_103097_data_enc, secured_authorization_validation_request, _params) == -1) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to secure Pki message"); return; } loggers::get_instance().log_msg("<<< pki_layer::sendMsg: generate_authorization_validation_request: ", secured_authorization_validation_request); send_data(secured_authorization_validation_request, _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); // 1. Extract EtsiTs102941Data or EtsiTs103097DataSigned OCTETSTRING unsecured_payload; if (decrypt_and_check_signature(data, unsecured_payload, _params) == -1) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to secure Pki message"); return; } loggers::get_instance().log_msg("pki_layer::receive_data: unsecured_payload=", unsecured_payload); // Try to extract EtsiTs102941Data EtsiTs102941MessagesCa::EtsiTs102941Data etsi_ts_102941_data; if (_codec_etsi_ts102941_data.decode(unsecured_payload, etsi_ts_102941_data) == -1) { // Try with EtsiTs103097Data-Signed IEEE1609dot2::Ieee1609Dot2Data etsi_ts_1609dot2_data; if (_codec.decode(unsecured_payload, etsi_ts_1609dot2_data) == -1) { loggers::get_instance().warning("pki_layer::sendMsg: Failed to decode unsecured payload"); return; } else { // Process EtsiTs103097Data-Signed loggers::get_instance().log_msg("pki_layer::receive_data: Process ", etsi_ts_1609dot2_data); } } else { // TODO Process EtsiTs102941Data loggers::get_instance().log_msg("pki_layer::receive_data: Process ", etsi_ts_102941_data); // Check protocol version if (etsi_ts_102941_data.version() != 1) { loggers::get_instance().warning("pki_layer::sendMsg: Wrong ETSI TS 102 941 protocol version, discard it!"); return; } if (etsi_ts_102941_data.content().ischosen(EtsiTs102941MessagesCa::EtsiTs102941DataContent::ALT_enrolmentResponse)) { // Pass it to the ports to_all_upper_ports(etsi_ts_102941_data.content().enrolmentResponse(), _params); } } // 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_103097_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(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()); IEEE1609dot2BaseTypes::Signature signature; 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"); return -1; } // Finalyse the EtsiTs103097Data-Signed IEEE1609dot2::SignerIdentifier signer; 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) EtsiTs102941MessagesCa::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); _codec.encode(ieee_1609dot2_data, p_etsi_ts_103097_data); if (!p_etsi_ts_103097_data.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: ", p_etsi_ts_103097_data); return 0; } 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, OCTETSTRING& p_unsecured_payload, 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 decrypt data"); return -1; } loggers::get_instance().log_msg("pki_layer::decrypt_and_check_signature: Decrypted playload=", os); // 2. Decode EtsiTs103097Data-Signed and check signature IEEE1609dot2::Ieee1609Dot2Data etsi_ts_1609dot2_data; if (security_services::get_instance().verify_and_extract_gn_payload(os, true, etsi_ts_1609dot2_data, p_unsecured_payload, p_params) == -1) { loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::decrypt_and_check_signature: Failed to verify EtsiTs103097Data-Signed data"); return -1; } loggers::get_instance().log_msg("pki_layer::decrypt_and_check_signature: EtsiTs103097Data-Signed=", etsi_ts_1609dot2_data); return 0; } pki_layer_factory pki_layer_factory::_f;