/** * @author ETSI / STF544 * @version $Url$ * $Id$ * @desc Module containing functions for ITS PKI ATS * @copyright ETSI Copyright Notification * No part may be reproduced except as authorized by written permission. * The copyright and the foregoing restriction extend to reproduction in all media. * All rights reserved. * */ module LibItsPki_Functions { // LibCommon import from LibCommon_Time all; import from LibCommon_VerdictControl all; import from LibCommon_Sync all; import from LibCommon_BasicTypesAndValues all; import from LibCommon_DataStrings all; // LibHelpers import from LibHelpers_Functions all; // LibIts import from Ieee1609Dot2BaseTypes language "ASN.1:1997" all; import from Ieee1609Dot2 language "ASN.1:1997" all; import from EtsiTs102941BaseTypes language "ASN.1:1997" all; import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all; import from EtsiTs102941TypesAuthorization language "ASN.1:1997" all; import from EtsiTs102941TypesAuthorizationValidation language "ASN.1:1997" all; import from EtsiTs102941MessagesCa language "ASN.1:1997" all; import from EtsiTs102941TrustLists language "ASN.1:1997" all; import from EtsiTs103097Module language "ASN.1:1997" all; import from Ieee1609Dot2Dot1EeRaInterface language "ASN.1:1997" all; import from Ieee1609Dot2Dot1AcaRaInterface language "ASN.1:1997" all; import from Ieee1609Dot2Dot1Acpc language "ASN.1:1997" all; import from ETSI_ITS_CDD language "ASN.1:1997" all; import from CAM_PDU_Descriptions language "ASN.1:1997" all; // LibItsCommon import from LibItsCommon_TypesAndValues all; import from LibItsCommon_Functions all; import from LibItsCommon_ASN1_NamedNumbers all; import from LibItsCommon_Pixits all; // LibItsGeoNetworking import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_TestSystem all; import from LibItsGeoNetworking_Pixits all; // LibItsSecurity import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pics all; import from LibItsSecurity_Pixits all; import from LibItsSecurity_TestSystem all; // LibHttp import from LibHttp_TypesAndValues all; import from LibHttp_Templates all; import from LibHttp_Functions all; import from LibHttp_TestSystem all; import from LibHttp_Pics all; // LibHttp import from LibHttp_BinaryTemplates all; // LibItsPki import from LibItsPki_TypesAndValues all; import from LibItsPki_Templates all; import from LibItsPki_Pics all; import from LibItsPki_Pixits all; import from LibItsPki_TestSystem all; group pkiConfigurationFunctions { function f_cfMtcUp01( out ItsPkiItss p_itss, out ItsPkiHttp p_pki ) runs on ItsMtc { p_itss := ItsPkiItss.create("ITS-S") alive; p_pki := ItsPkiHttp.create("PKI") alive; connect(self:syncPort, mtc:syncPort); connect(p_itss:syncPort, self:syncPort); connect(p_pki:syncPort, self:syncPort); connect(p_pki:infoPort, p_itss:infoPort); } // End of function f_cfMtcUp01 function f_cfMtcUp02( out ItsPkiHttp p_itss, out ItsPkiHttp p_ea ) runs on ServerSyncComp { p_itss := ItsPkiItss.create("ITS-S") alive; p_ea := ItsPkiHttp.create("EA") alive; connect(self:syncPort, mtc:syncPort); connect(p_itss:syncPort, self:syncPort); connect(p_ea:syncPort, self:syncPort); } // End of function f_cfMtcUp02 function f_cfMtcUp03( out ItsPkiHttp p_itss, out ItsPkiHttp p_tlm ) runs on ServerSyncComp { p_itss := ItsPkiItss.create("ITS-S") alive; p_tlm := ItsPkiHttp.create("TLM") alive; connect(self:syncPort, mtc:syncPort); connect(p_itss:syncPort, self:syncPort); connect(p_tlm:syncPort, self:syncPort); } // End of function f_cfMtcUp03 function f_cfMtcUp04( out ItsPkiHttp p_itss, out ItsPkiHttp p_dc ) runs on ServerSyncComp { p_itss := ItsPkiItss.create("ITS-S") alive; p_dc := ItsPkiHttp.create("DC") alive; connect(self:syncPort, mtc:syncPort); connect(p_itss:syncPort, self:syncPort); connect(p_dc:syncPort, self:syncPort); } // End of function f_cfMtcUp04 /** * @desc Setups default configuration * @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT */ function f_cfHttpUp( in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant in charstring p_aa_certificate_id := "CERT_TS_A_AA" ) runs on ItsPkiHttp system ItsPkiHttpSystem { if (PICS_MULTIPLE_END_POINT == false) { map(self:httpPort, system:httpPort); } else { map(self:httpEcPort, system:httpEcPort); map(self:httpAtVPort, system:httpAtVPort); map(self:httpAtPort, system:httpAtPort); } f_connect4SelfOrClientSync(); f_initialiseSecuredMode(p_ea_certificate_id, p_aa_certificate_id); // TODO To be removed??? // TODO Duplicate code, use a function // Setup EA certificate shared with PKI EA entity f_readCertificate(p_ea_certificate_id, vc_eaCertificate); f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8); f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash); f_getCertificateHash256(p_ea_certificate_id, vc_eaWholeHash256); log("f_cfHttpUp: vc_eaPrivateKey= ", vc_eaPrivateKey); log("f_cfHttpUp: vc_eaPrivateEncKey= ", vc_eaPrivateEncKey); log("f_cfHttpUp: vc_eaHashedId8= ", vc_eaHashedId8); log("f_cfHttpUp: vc_eaWholeHash= ", vc_eaWholeHash); log("f_cfHttpUp: vc_eaWholeHash256= ", vc_eaWholeHash256); // Setup AA certificate shared with PKI AA entity f_readCertificate(p_aa_certificate_id, vc_aaCertificate); f_readSigningKey(p_aa_certificate_id, vc_aaPrivateKey); // Required for AuthorizationValidation request f_readEncryptingKey(p_aa_certificate_id, vc_aaPrivateEncKey); f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8); f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash); f_getCertificateHash256(p_aa_certificate_id, vc_aaWholeHash256); log("f_cfHttpUp: vc_aaPrivateKey= ", vc_aaPrivateKey); log("f_cfHttpUp: vc_aaPrivateEncKey= ", vc_aaPrivateEncKey); log("f_cfHttpUp: vc_aaHashedId8= ", vc_aaHashedId8); log("f_cfHttpUp: vc_aaWholeHash= ", vc_aaWholeHash); log("f_cfHttpUp: vc_aaWholeHash256= ", vc_aaWholeHash256); // Storage of enrolment keys in case of re-enrolment vc_ec_keys_counter := 0; vc_ec_counter := 0; vc_ec_private_keys := {}; vc_ec_public_compressed_key := {}; vc_ec_compressed_modes := {}; vc_ec_hashed_id8 := {}; vc_ec_certificates := {}; if (PICS_MULTIPLE_END_POINT == false) { activate(a_default_pki_http()); } else { activate(a_default_pki_http_ec()); activate(a_default_pki_http_atv()); activate(a_default_pki_http_at()); } } // End of function f_cfHttpUp /** * @desc Setups default configuration */ function f_cfHttpUp_ca() runs on ItsPkiHttp system ItsPkiHttpSystem { // FIXME Rename into f_cfHttpUp_rca_dc if (PICS_MULTIPLE_END_POINT == false) { map(self:httpPort, system:httpPort); } else { map(self:httpCaPort, system:httpCaPort); } f_connect4SelfOrClientSync(); f_initialiseSecuredMode(); if (PICS_MULTIPLE_END_POINT == false) { activate(a_default_pki_http()); } else { activate(a_default_pki_http_ca()); } } // End of function f_cfHttpUp_ca /** * @desc Setups default configuration */ function f_cfHttpUp_tlm() runs on ItsPkiHttp system ItsPkiHttpSystem { // FIXME Rename into f_cfHttpUp_cpoc if (PICS_MULTIPLE_END_POINT == false) { map(self:httpPort, system:httpPort); } else { map(self:httpTlmPort, system:httpTlmPort); } f_connect4SelfOrClientSync(); f_initialiseSecuredMode(); if (PICS_MULTIPLE_END_POINT == false) { activate(a_default_pki_http()); } else { activate(a_default_pki_http_tlm()); } } // End of function f_cfHttpUp_tlm /** * @desc Setups default configuration * @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT */ function f_cfHttpUp_itss( in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant in charstring p_aa_certificate_id := "CERT_TS_A_AA" ) runs on ItsPkiHttp system ItsPkiHttpSystem { if (PICS_MULTIPLE_END_POINT == false) { map(self:httpPort, system:httpPort); } else { map(self:httpEcPort, system:httpEcPort); map(self:httpAtPort, system:httpAtPort); } f_initialiseSecuredMode(p_ea_certificate_id, p_aa_certificate_id); // TODO To be removed??? // TODO Duplicate code, use a function // Setup EA certificate shared with PKI EA entity f_readCertificate(p_ea_certificate_id, vc_eaCertificate); f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8); f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash); f_getCertificateHash256(p_ea_certificate_id, vc_eaWholeHash256); log("f_cfHttpUp_itss: vc_eaPrivateKey= ", vc_eaPrivateKey); log("f_cfHttpUp_itss: vc_eaPrivateEncKey= ", vc_eaPrivateEncKey); log("f_cfHttpUp_itss: vc_eaHashedId8= ", vc_eaHashedId8); log("f_cfHttpUp_itss: vc_eaWholeHash= ", vc_eaWholeHash); log("f_cfHttpUp: vc_eaWholeHash256= ", vc_eaWholeHash256); // Setup AA certificate shared with PKI AA entity f_readCertificate(p_aa_certificate_id, vc_aaCertificate); f_readSigningKey(p_aa_certificate_id, vc_aaPrivateKey); // Required for AuthorizationValidation request f_readEncryptingKey(p_aa_certificate_id, vc_aaPrivateEncKey); f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8); f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash); f_getCertificateHash256(p_aa_certificate_id, vc_aaWholeHash256); log("f_cfHttpUp_itss: vc_aaPrivateKey= ", vc_aaPrivateKey); log("f_cfHttpUp_itss: vc_aaPrivateEncKey= ", vc_aaPrivateEncKey); log("f_cfHttpUp_itss: vc_aaHashedId8= ", vc_aaHashedId8); log("f_cfHttpUp_itss: vc_aaWholeHash= ", vc_aaWholeHash); log("f_cfHttpUp: vc_eaWholeHash256= ", vc_aaWholeHash256); // Storage of enrolment keys in case of re-enrolment vc_ec_keys_counter := 0; vc_ec_counter := 0; vc_ec_private_keys := {}; vc_ec_public_compressed_key := {}; vc_ec_compressed_modes := {}; vc_ec_hashed_id8 := {}; vc_ec_certificates := {}; if (PICS_MULTIPLE_END_POINT == false) { activate(a_default_pki_http()); } else { activate(a_default_pki_http_at()); } } // End of function f_cfHttpUp_itss /** * @desc Setups default configuration * @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT */ function f_cfHttpUp_ea( in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant in charstring p_aa_certificate_id := "CERT_TS_A_AA" ) runs on ItsPkiHttp system ItsPkiHttpSystem { if (PICS_MULTIPLE_END_POINT == false) { map(self:httpPort, system:httpPort); } else { map(self:httpAtVPort, system:httpAtVPort); } f_initialiseSecuredMode(p_ea_certificate_id, p_aa_certificate_id); // TODO To be removed??? // TODO Duplicate code, use a function // Setup EA certificate shared with PKI EA entity f_readCertificate(p_ea_certificate_id, vc_eaCertificate); f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8); f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash); f_getCertificateHash256(p_aa_certificate_id, vc_eaWholeHash256); log("f_cfHttpUp_ea: vc_eaPrivateKey= ", vc_eaPrivateKey); log("f_cfHttpUp_ea: vc_eaPrivateEncKey= ", vc_eaPrivateEncKey); log("f_cfHttpUp_ea: vc_eaHashedId8= ", vc_eaHashedId8); log("f_cfHttpUp_ea: vc_eaWholeHash= ", vc_eaWholeHash); log("f_cfHttpUp: vc_aaWholeHash256= ", vc_eaWholeHash256); // Setup AA certificate shared with PKI AA entity f_readCertificate(p_aa_certificate_id, vc_aaCertificate); f_readSigningKey(p_aa_certificate_id, vc_aaPrivateKey); // Required for AuthorizationValidation request f_readEncryptingKey(p_aa_certificate_id, vc_aaPrivateEncKey); f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8); f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash); f_getCertificateHash256(p_aa_certificate_id, vc_aaWholeHash256); log("f_cfHttpUp_ea: vc_aaPrivateKey= ", vc_aaPrivateKey); log("f_cfHttpUp_ea: vc_aaPrivateEncKey= ", vc_aaPrivateEncKey); log("f_cfHttpUp_ea: vc_aaHashedId8= ", vc_aaHashedId8); log("f_cfHttpUp_ea: vc_aaWholeHash= ", vc_aaWholeHash); log("f_cfHttpUp: vc_aaWholeHash256= ", vc_aaWholeHash256); // Storage of enrolment keys in case of re-enrolment vc_ec_keys_counter := 0; vc_ec_counter := 0; vc_ec_private_keys := {}; vc_ec_public_compressed_key := {}; vc_ec_compressed_modes := {}; vc_ec_hashed_id8 := {}; vc_ec_certificates := {}; if (PICS_MULTIPLE_END_POINT == false) { activate(a_default_pki_http()); } else { activate(a_default_pki_http_atv()); activate(a_default_pki_http_at()); } } // End of function f_cfHttpUp_ea function f_cfUp_itss() runs on ItsPkiItss system ItsPkiItssSystem { map(self:geoNetworkingPort, system:geoNetworkingPort); map(self:utPort, system:utPort); //map(self:acPort, system:acPort); f_initializeState(); // activate(a_default_pki()); TOTO Defualt from geoNet } // End of function f_cfUp_itss /** * @desc Deletes default configuration */ function f_cfMtcDown01( inout ItsPkiItss p_itss, inout ItsPkiHttp p_pki ) runs on ItsMtc { disconnect(self:syncPort, mtc:syncPort); disconnect(p_itss:syncPort, self:syncPort); disconnect(p_pki:syncPort, self:syncPort); disconnect(p_pki:infoPort, p_itss:infoPort); p_itss.done; p_pki.done; } function f_cfMtcDown02( inout ItsPkiHttp p_itss, inout ItsPkiHttp p_ea ) runs on ServerSyncComp { disconnect(self:syncPort, mtc:syncPort); disconnect(p_itss:syncPort, self:syncPort); disconnect(p_ea:syncPort, self:syncPort); p_itss.done; p_ea.done; } function f_cfMtcDown03( inout ItsPkiHttp p_itss, inout ItsPkiHttp p_tlm ) runs on ServerSyncComp { disconnect(self:syncPort, mtc:syncPort); disconnect(p_itss:syncPort, self:syncPort); disconnect(p_tlm:syncPort, self:syncPort); p_itss.done; p_tlm.done; } function f_cfMtcDown04( inout ItsPkiHttp p_itss, inout ItsPkiHttp p_dc ) runs on ServerSyncComp { disconnect(self:syncPort, mtc:syncPort); disconnect(p_itss:syncPort, self:syncPort); disconnect(p_dc:syncPort, self:syncPort); p_itss.done; p_dc.done; } /** * @desc Deletes default configuration */ function f_cfHttpDown() runs on ItsPkiHttp { if (PICS_MULTIPLE_END_POINT == false) { unmap(self:httpPort, system:httpPort); } else { unmap(self:httpEcPort, system:httpEcPort); unmap(self:httpAtVPort, system:httpAtVPort); unmap(self:httpAtPort, system:httpAtPort); } f_disconnect4SelfOrClientSync(); f_uninitialiseSecuredMode(); } // End of function f_cfHttpDown /** * @desc Deletes default configuration */ function f_cfHttpDown_ca() runs on ItsPkiHttp { if (PICS_MULTIPLE_END_POINT == false) { unmap(self:httpPort, system:httpPort); } else { unmap(self:httpCaPort, system:httpCaPort); } f_disconnect4SelfOrClientSync(); f_uninitialiseSecuredMode(); } // End of function f_cfHttpDown_ca /** * @desc Deletes default configuration */ function f_cfHttpDown_tlm() runs on ItsPkiHttp { if (PICS_MULTIPLE_END_POINT == false) { unmap(self:httpPort, system:httpPort); } else { unmap(self:httpTlmPort, system:httpTlmPort); } f_disconnect4SelfOrClientSync(); f_uninitialiseSecuredMode(); } // End of function f_cfHttpDown_tlm /** * @desc Deletes default configuration */ function f_cfHttpDown_itss() runs on ItsPkiHttp { if (PICS_MULTIPLE_END_POINT == false) { unmap(self:httpPort, system:httpPort); } else { unmap(self:httpEcPort, system:httpEcPort); unmap(self:httpAtPort, system:httpAtPort); } f_disconnect4SelfOrClientSync(); f_uninitialiseSecuredMode(); } // End of function f_cfHttpDown_itss /** * @desc Deletes default configuration */ function f_cfHttpDown_ea() runs on ItsPkiHttp { if (PICS_MULTIPLE_END_POINT == false) { unmap(self:httpPort, system:httpPort); } else { unmap(self:httpAtVPort, system:httpAtVPort); } f_disconnect4SelfOrClientSync(); f_uninitialiseSecuredMode(); } // End of function f_cfHttpDown_ea /** * @desc Deletes default configuration */ function f_cfDown_itss() runs on ItsPkiItss system ItsPkiItssSystem { unmap(self:geoNetworkingPort, system:geoNetworkingPort); unmap(self:utPort, system:utPort); //unmap(self:acPort, system:acPort); } // End of function f_cfDown /** * @desc Initialise secure mode if required */ function f_initialiseSecuredMode( in charstring p_certificate_id := "CERT_TS_A_EA", // TODO Use a constant in charstring p_peerCertificateId := "CERT_IUT_A_EA" ) runs on ItsSecurityBaseComponent { if(not(f_loadCertificates(PX_IUT_SEC_CONFIG_NAME))) { log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); setverdict(inconc); stop; } } // End of function f_initialiseSecuredMode() function f_uninitialiseSecuredMode() runs on ItsSecurityBaseComponent { f_unloadCertificates(); } // End of function f_uninitialiseSecuredMode() function f_initializeState() runs on ItsPkiItss { var Oct8 v_hashedId8ToBeUsed; log(">>> f_initializeState: vc_hashedId8ToBeUsed= ", vc_hashedId8ToBeUsed); v_hashedId8ToBeUsed := f_setupIutCertificate(vc_hashedId8ToBeUsed); log("f_initializeState: v_hashedId8ToBeUsed= ", v_hashedId8ToBeUsed); f_utInitializeIut(UtPkiInitialize: { v_hashedId8ToBeUsed } ); f_sleep(PX_NEIGHBOUR_DISCOVERY_DELAY); // f_acLoadScenario(p_scenario); // f_acStartScenario(); } } // End of pkiConfigurationFunctions group ut_port { function f_utInitializeIut(template (value) UtPkiInitialize p_init) runs on ItsPkiItss { utPort.send(p_init); tc_wait.start; alt { [] utPort.receive(UtPkiResults: { utPkiInitializeResult := true }) { tc_wait.stop; log("*** f_utInitializeIut: INFO: IUT initialized ***"); } [] utPort.receive { tc_wait.stop; log("*** f_utInitializeIut: INFO: IUT could not be initialized ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_utInitializeIut: INFO: IUT could not be initialized in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } } // End of function f_utInitializeIut function f_sendUtTriggerEnrolmentRequestPrimitive( in octetstring p_canonical_id := ''O, in Oct1 p_enc_algorithm := '00'O, in octetstring p_private_key := ''O, in octetstring p_public_key_compressed := ''O, in integer p_compressed_mode := 0, in boolean p_check_result := true ) runs on ItsPkiItss { var TriggerEnrolmentRequest v_ut_trigger_enrolment_request; var octetstring v_compressed_public_key; if (p_compressed_mode == 2) { // TODO v_compressed_public_key := int2oct(p_compressed_mode, 1) & p_public_key_compressed? v_compressed_public_key := '02'O & p_public_key_compressed; } else { v_compressed_public_key := '03'O & p_public_key_compressed; } utPort.clear; v_ut_trigger_enrolment_request := { p_canonical_id, p_enc_algorithm, p_private_key, v_compressed_public_key }; utPort.send(UtPkiTrigger: { triggerEnrolmentRequest := v_ut_trigger_enrolment_request }); tc_ac.start(20.0); alt { [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { tc_ac.stop; } [] utPort.receive(UtPkiResults: { utPkiTriggerResult := false }) { tc_ac.stop; log("*** f_sendUtTriggerEnrolmentRequestPrimitive: ERROR: Unsuccessful trugger result received in UT port. Stop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] utPort.receive { log("*** f_sendUtTriggerEnrolmentRequestPrimitive: INFO: Unexpected message received in UT Port. Keep waiting. ***"); repeat; } [] tc_ac.timeout { if(p_check_result){ log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); }else{ log("*** f_sendAcPkiPrimitive: INFO: Timeout while waiting for adapter control event result. Assume OK. ***"); } } } // End of 'alt' statement } // End of function f_sendUtTriggerEnrolmentRequestPrimitive function f_sendUtTriggerAuthorizationRequestPrimitive( in octetstring p_canonical_id := ''O, in Oct1 p_enc_algorithm := '00'O, in octetstring p_private_key := ''O, in octetstring p_public_key_compressed := ''O, in integer p_compressed_mode := 0 ) runs on ItsPkiItss { var TriggerAuthorizationRequest v_ut_trigger_enrolment_request; var octetstring v_compressed_public_key; if (p_compressed_mode == 2) { // TODO v_compressed_public_key := int2oct(p_compressed_mode, 1) & p_public_key_compressed? v_compressed_public_key := '02'O & p_public_key_compressed; } else { v_compressed_public_key := '03'O & p_public_key_compressed; } v_ut_trigger_enrolment_request := { p_canonical_id, p_enc_algorithm, p_private_key, v_compressed_public_key }; utPort.send(UtPkiTrigger: { triggerAuthorizationRequest := v_ut_trigger_enrolment_request }); tc_ac.start; alt { [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { tc_ac.stop; } [] utPort.receive(UtPkiResults: { utPkiTriggerResult := false }) { tc_ac.stop; log("*** f_sendUtTriggerAuthorizationRequestPrimitive: ERROR: Received unexpected message ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] utPort.receive(UtPkiTriggerInd:?) { log("*** f_sendUtTriggerAuthorizationRequestPrimitive: INFO: Received UtPkiTriggerInd message ***"); repeat; } [] tc_ac.timeout { log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } // End of 'alt' statement } // End of function f_sendUtTriggerAuthorizationRequestPrimitive function f_sendUtTriggerUpdateEctl(template (value) charstring p_ectl_uri) runs on ItsPkiItss { utPort.send(UtPkiTrigger: { triggerUpdateEctl := { ectl_uri := p_ectl_uri } }); tc_wait.start; alt { [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { tc_wait.stop; log("*** f_sendUtTriggerUpdateEctl: INFO: IUT has updated ECTL ***"); } [] utPort.receive { tc_wait.stop; log("*** f_sendUtTriggerUpdateEctl: INFO: IUT could not update ECTL ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_sendUtTriggerUpdateEctl: INFO: IUT could not update ECTL in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } } // End of function f_sendUtTriggerUpdateEctl function f_sendUtTriggerRequestForTlmCtl(template (value) charstring p_tlm_ctl_uri) runs on ItsPkiItss { utPort.send(UtPkiTrigger: { triggerRequestForTlmCtl := { tlm_ctl_uri := p_tlm_ctl_uri } }); tc_wait.start; alt { [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { tc_wait.stop; log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT has updated ECTL ***"); } [] utPort.receive { tc_wait.stop; log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT could not update ECTL ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT could not update ECTL in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } } // End of function f_sendUtTriggerRequestForTlmCtl function f_sendUtTriggerRequestForRcaCtl(template (value) charstring p_tlm_ctl_uri) runs on ItsPkiItss { utPort.send(UtPkiTrigger: { triggerRequestForRcaCtl := { tlm_ctl_uri := p_tlm_ctl_uri } }); tc_wait.start; alt { [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { tc_wait.stop; log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT has updated ECTL ***"); } [] utPort.receive { tc_wait.stop; log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT could not update ECTL ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT could not update ECTL in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } } // End of function f_sendUtTriggerRequestForRcaCtl } // End of group ut_port group helpers { function f_decode_EccP256CurvePoint( in octetstring buf, out EccP256CurvePoint p ) runs on ItsPkiHttp return boolean { var integer ptype := oct2int(buf[0] and4b '7F'O); if(lengthof(buf) == 33){ if (ptype == 0) {p.x_only := substr(buf, 1, 32);} else if (ptype == 2) {p.compressed_y_0 := substr(buf, 1, 32);} else if (ptype == 3) {p.compressed_y_1 := substr(buf, 1, 32);} else { log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); return false; } }else if(lengthof(buf) == 65){ if (ptype == 4) { p.uncompressedP256.x := substr(buf, 1, 32); p.uncompressedP256.y := substr(buf, 33, 32); }else{ log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); return false; } }else{ log("f_decode_EccP256CurvePoint: wrong buffer length ", lengthof(buf)); return false; } return true; } function f_decode_EccP384CurvePoint( in octetstring buf, out EccP384CurvePoint p ) runs on ItsPkiHttp return boolean { var integer ptype := oct2int(buf[0] and4b '7F'O); if(lengthof(buf) == 49){ if (ptype == 0) {p.x_only := substr(buf, 1, 48);} else if (ptype == 2) {p.compressed_y_0 := substr(buf, 1, 48);} else if (ptype == 3) {p.compressed_y_1 := substr(buf, 1, 48);} else { log("f_decode_EccP384CurvePoint: unsupported value for point type ", ptype); return false; } }else if(lengthof(buf) == 97){ if (ptype == 4) { p.uncompressedP384.x := substr(buf, 1, 48); p.uncompressedP384.y := substr(buf, 49, 48); }else{ log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); return false; } }else{ log("f_decode_EccP256CurvePoint: wrong buffer length ",lengthof(buf)); return false; } return true; } function f_get_canonical_itss_key( out PublicVerificationKey p_key ) runs on ItsPkiHttp return boolean { log("f_get_canonical_itss_key: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { return f_decode_EccP256CurvePoint(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, p_key.ecdsaNistP256); } else if (PX_VE_ALG == e_brainpool_p256_r1) { return f_decode_EccP256CurvePoint(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, p_key.ecdsaNistP256); } else if (PX_VE_ALG == e_brainpool_p384_r1) { return f_decode_EccP384CurvePoint(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, p_key.ecdsaNistP256); } return false; } function f_generate_key_pair( out octetstring p_private_key, out octetstring p_public_key_x, out octetstring p_public_key_y, out octetstring p_public_key_compressed, out integer p_compressed_mode ) return boolean { log(">>> f_generate_key_pair: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { f_generate_key_pair_nistp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (PX_VE_ALG == e_brainpool_p256_r1) { f_generate_key_pair_brainpoolp256r1(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (PX_VE_ALG == e_sm2_p256) { f_generate_key_pair_sm2p256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (PX_VE_ALG == e_brainpool_p384_r1) { f_generate_key_pair_brainpoolp384r1(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (PX_VE_ALG == e_nist_p384) { f_generate_key_pair_nistp384(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else { // error return false; } log("<<< f_generate_key_pair: p_compressed_mode=", p_compressed_mode); return true; } function f_generate_key_pair_for_encryption( in SignAlgorithm p_algorithm, out octetstring p_private_key, out octetstring p_public_key_x, out octetstring p_public_key_y, out octetstring p_public_key_compressed, out integer p_compressed_mode ) return boolean { if (p_algorithm == e_nist_p256) { f_generate_key_pair_nistp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (p_algorithm == e_brainpool_p256_r1) { f_generate_key_pair_brainpoolp256r1(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else if (p_algorithm == e_sm2_p256) { f_generate_key_pair_sm2p256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode); } else { // error return false; } return true; } // End of function f_generate_key_pair_for_encryption function f_http_restart( in charstring p_content_text ) runs on ItsPkiHttp { if (not(PICS_MULTIPLE_END_POINT)) { log("f_http_restart: restart httpPort"); httpPort.stop; httpPort.start; } else { log("f_http_restart: restart httpPort with contentType ", p_content_text); select(p_content_text){ case ("inner_ec_request"){ httpEcPort.stop; httpEcPort.start; } case ("inner_atv_request"){ httpAtVPort.stop; httpAtVPort.start; } } } } // End of function f_http_restart function f_http_send( in Headers p_headers, in template (value) HttpMessage p_http_message ) runs on ItsPkiHttp { log(">>> f_http_send: ", p_http_message); if (not(PICS_MULTIPLE_END_POINT)) { httpPort.send(p_http_message); } else { var charstring_list v_content_text; f_get_header(p_headers, c_header_content_text, v_content_text); if (not(isvalue(v_content_text))) { log("f_http_send: Failed to send message: header not found: ", c_header_content_text); return; } if (v_content_text == { "inner_ec_request" }) { log("f_http_send: Send on EC end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpEcPort.send(p_http_message); } else if (v_content_text == { "inner_atv_request" }) { log("f_http_send: Send on ATV end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_ATV }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpAtVPort.send(p_http_message); } else if (v_content_text == { "inner_atv_response" }) { log("f_http_send: Send on ATV end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_ATV }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpAtVPort.send(p_http_message); } else if (v_content_text == { "inner_at_request" }) { log("f_http_send: Send on AT end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_AT }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpAtPort.send(p_http_message); } else if (v_content_text == { "bfk_auth_request" }) { log("f_http_send: Send on EC end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpEcPort.send(p_http_message); } else if (v_content_text == { "bfk_cert_request" }) { log("f_http_send: Send on AT end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_AT }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpEcPort.send(p_http_message); } else if (v_content_text == { "bfk_at_download_request" }) { log("f_http_send: Send on EC end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpEcPort.send(p_http_message); } else if (v_content_text == { "ca_request" }) { log("f_http_send: Send on CA end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_CA }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpCaPort.send(p_http_message); } else if (v_content_text == { "ca_response" }) { log("f_http_send: Send on CA end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_CA }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpCaPort.send(p_http_message); } else if (v_content_text == { "tlm_request" }) { log("f_http_send: Send on TLM end point"); f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_TLM }, p_headers); if (ischosen(p_http_message.request)) { p_http_message.request.header := p_headers; } else { p_http_message.response.header := p_headers; } httpTlmPort.send(p_http_message); } else { log("f_http_send: Invalid header value: ", v_content_text); } } } // End of function f_http_send function f_generate_key_tag( in octetstring p_public_key_compressed, in integer p_compressed_key_mode, in octetstring p_public_compressed_enc_key, in integer p_compressed_enc_key_mode, out octetstring p_encoded_tag ) return boolean { // Local variables var PublicVerificationKey v_verification_tag; var PublicEncryptionKey v_encryption_tag; log(">>> f_generate_key_tag: p_public_key_compressed=", p_public_key_compressed); log(">>> f_generate_key_tag: p_public_compressed_enc_key=", p_public_compressed_enc_key); if (PX_VE_ALG == e_nist_p256) { if (p_compressed_key_mode == 0) { v_verification_tag.ecdsaNistP256.compressed_y_0 := p_public_key_compressed; } else { v_verification_tag.ecdsaNistP256.compressed_y_1 := p_public_key_compressed; } } else if (PX_VE_ALG == e_brainpool_p256_r1) { if (p_compressed_key_mode == 0) { v_verification_tag.ecdsaBrainpoolP256r1.compressed_y_0 := p_public_key_compressed; } else { v_verification_tag.ecdsaBrainpoolP256r1.compressed_y_1 := p_public_key_compressed; } } else if (PX_VE_ALG == e_brainpool_p384_r1) { if (p_compressed_key_mode == 0) { v_verification_tag.ecdsaBrainpoolP384r1.compressed_y_0 := p_public_key_compressed; } else { v_verification_tag.ecdsaBrainpoolP384r1.compressed_y_1 := p_public_key_compressed; } } else if (PX_VE_ALG == e_nist_p384) { if (p_compressed_key_mode == 0) { v_verification_tag.ecdsaNistP384.compressed_y_0 := p_public_key_compressed; } else { v_verification_tag.ecdsaNistP384.compressed_y_1 := p_public_key_compressed; } } else if (PX_VE_ALG == e_sm2_p256) { if (p_compressed_key_mode == 0) { v_verification_tag.ecsigSm2.compressed_y_0 := p_public_key_compressed; } else { v_verification_tag.ecsigSm2.compressed_y_1 := p_public_key_compressed; } } else { log("f_generate_key_tag: Failed to generate HMAC tag"); return false; } log("f_generate_key_tag: v_verification_tag= ", v_verification_tag); p_encoded_tag := bit2oct(encvalue(v_verification_tag)); if (PX_INCLUDE_ENCRYPTION_KEYS) { v_encryption_tag.supportedSymmAlg := aes128Ccm; if (PX_EC_ALG_FOR_EC_SIGN == e_nist_p256) { if (p_compressed_enc_key_mode == 0) { v_encryption_tag.publicKey.eciesNistP256.compressed_y_0 := p_public_compressed_enc_key; } else { v_encryption_tag.publicKey.eciesNistP256.compressed_y_1 := p_public_compressed_enc_key; } } else if (PX_EC_ALG_FOR_EC_SIGN == e_brainpool_p256_r1) { if (p_compressed_enc_key_mode == 0) { v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_0 := p_public_compressed_enc_key; } else { v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_1 := p_public_compressed_enc_key; } } else if (PX_EC_ALG_FOR_EC_SIGN == e_sm2_p256) { // FIXME FSCOM if (p_compressed_enc_key_mode == 0) { v_encryption_tag.publicKey.ecencSm2.compressed_y_0 := p_public_compressed_enc_key; } else { v_encryption_tag.publicKey.ecencSm2.compressed_y_1 := p_public_compressed_enc_key; } } else { log("f_generate_key_tag: Failed to generate HMAC tag (enc)"); return false; } log("f_generate_key_tag: v_encryption_tag= ", v_encryption_tag); p_encoded_tag := p_encoded_tag & bit2oct(encvalue(v_encryption_tag)); } return true; } // End of function f_generate_key_tag } // End of group helpers group http { // TODO Split into EnnerEc, Authorization, AuthorizationValidation and bfk function f_http_build_inner_ec_request( // TODO Cleanup parameters out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp { var InnerEcRequest v_inner_ec_request; var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var boolean v_result; log(">>> f_http_build_inner_ec_request"); log ("f_http_build_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter); log ("f_http_build_inner_ec_request: vc_ec_private_keys: ", vc_ec_private_keys); log ("f_http_build_inner_ec_request: vc_ec_counter: ", vc_ec_counter); if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) { log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequest ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log ("f_http_build_inner_ec_request: ==> EC verification private key: ", p_private_key); log ("f_http_build_inner_ec_request: ==> EC verification public compressed key: ", p_public_key_compressed); log ("f_http_build_inner_ec_request: ==> EC verification public compressed mode: ", p_compressed_mode); // Store enrolment keys for re-enrolment vc_ec_private_keys[vc_ec_keys_counter] := p_private_key; vc_ec_public_compressed_key[vc_ec_keys_counter] := p_public_key_compressed; vc_ec_compressed_modes[vc_ec_keys_counter] := p_compressed_mode; vc_ec_keys_counter := vc_ec_keys_counter + 1; // Generate InnerEcRequestSignedForPoP if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) { log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("f_http_build_inner_ec_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop); // Secure InnerEcRequestSignedForPoP message if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("f_http_build_inner_ec_request: Public encryption key: ", v_public_enc_key); log("f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("f_http_build_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter); if ((PICS_SECPKI_REENROLMENT == false) or (vc_ec_keys_counter == 1)) { // This is the first enrolment, we used Factory keys var octetstring v_private_key; if (PX_VE_ALG == e_nist_p256) { v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY; } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY; } else if (PX_VE_ALG == e_sm2_p256) { v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY; } else if (PX_VE_ALG == e_nist_p384) { v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY; } else { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY; } v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); } else { // We use last valid EC certificate // TODO Retrieve EC certificate from the first enrolment instead of PX log("f_http_build_inner_ec_request: v_ec_private_key: ", vc_ec_private_keys[vc_ec_keys_counter - 1]); log("f_http_build_inner_ec_request: v_ec_public_compressed_key: ", vc_ec_public_compressed_key[vc_ec_keys_counter - 1]); log("f_http_build_inner_ec_request: v_ec_compressed_modes: ", vc_ec_compressed_modes[vc_ec_keys_counter - 1]); log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]); v_result := f_build_pki_secured_request_message_signed_with_pop(vc_ec_private_keys[vc_ec_keys_counter - 1], valueof(m_signerIdentifier_digest(vc_ec_hashed_id8[vc_ec_keys_counter - 1])), vc_ec_hashed_id8[vc_ec_keys_counter - 1]/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); } if (v_result == false) { log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } else { log("f_http_build_inner_ec_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_inner_ec_request: p_request_hash= ", p_request_hash); } } // End of function f_http_build_inner_ec_request function f_http_build_inner_ec_request_with_wrong_parameters( // TODO Cleanup parameters in SequenceOfPsidSsp p_appPermissions, in octetstring p_canonical_id := PICS_ITS_S_CANONICAL_ID, in Time32 p_start, in Duration p_duration, in boolean p_alter_private_key := false, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp { var InnerEcRequest v_inner_ec_request; var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var boolean v_result; log(">>> f_http_build_inner_ec_request_with_wrong_parameters"); if (f_generate_inner_ec_request_with_wrong_parameters(p_appPermissions, p_canonical_id, p_start, p_duration, p_alter_private_key, p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) { log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequest ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification private key: ", p_private_key); log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed key: ", p_public_key_compressed); log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed mode: ", p_compressed_mode); // Generate InnerEcRequestSignedForPoP if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) { log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("f_http_build_inner_ec_request_with_wrong_parameters: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop); // Secure InnerEcRequestSignedForPoP message if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Non canonical EA certificate ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("f_http_build_inner_ec_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key); log("f_http_build_inner_ec_request_with_wrong_parameters: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. var octetstring v_private_key; if (PX_VE_ALG == e_nist_p256) { v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY; } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY; } else if (PX_VE_ALG == e_sm2_p256) { v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY; } else if (PX_VE_ALG == e_nist_p384) { v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY; } else { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY; } v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); if (v_result == false) { log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } else { log("f_http_build_inner_ec_request_with_wrong_parameters: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_inner_ec_request_with_wrong_parameters: p_request_hash= ", p_request_hash); } } // End of function f_http_build_inner_ec_request_with_wrong_parameters function f_http_build_invalid_enrolment_request( out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp { var InnerEcRequest v_inner_ec_request; var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var boolean v_ret_code; var octetstring v_private_key; if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) { log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequest ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log ("f_http_build_invalid_enrolment_request: EC verification private key: ", p_private_key); log ("f_http_build_invalid_enrolment_request: EC verification public compressed key: ", p_public_key_compressed); log ("f_http_build_invalid_enrolment_request: EC verification public compressed mode: ", p_compressed_mode); // Generate InnerEcRequestSignedForPoP if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) { log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("f_http_build_invalid_enrolment_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop); // Modify signature to get an error if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature)) { v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1])); } else if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) { v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1])); } else { v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1])); } // Secure InnerEcRequestSignedForPoP message if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_invalid_enrolment_request: ERROR: Non canonical EA certificate ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("*** f_http_build_invalid_enrolment_request: Public encryption key: ", v_public_enc_key); log("*** f_http_build_invalid_enrolment_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. if (PX_VE_ALG == e_nist_p256) { v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY; } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY; } else if (PX_VE_ALG == e_sm2_p256) { v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY; } else if (PX_VE_ALG == e_nist_p384) { v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY; } else { v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY; } v_ret_code := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); if (v_ret_code == false) { log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); f_selfOrClientSyncAndVerdict("error", e_error); } log("*** f_http_build_invalid_enrolment_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data); } // End of function f_http_build_invalid_enrolment_request function f_http_build_inner_ec_response( in template (omit) InnerEcRequest p_inner_ec_request := omit, in EnrolmentResponseCode p_responseCode := ok, in Oct16 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out EtsiTs103097Certificate p_ec_certificate, out HashedId8 p_ec_certificate_hashed_id8, out InnerEcResponse p_inner_ec_response, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var boolean p_result := false; log(">>> f_http_build_inner_ec_response: p_inner_ec_request= ", p_inner_ec_request); log(">>> f_http_build_inner_ec_response: p_responseCode= ", p_responseCode); log(">>> f_http_build_inner_ec_response: p_request_hash= ", p_request_hash); log(">>> f_http_build_inner_ec_response: p_private_key= ", p_private_key); log(">>> f_http_build_inner_ec_response: p_digest= ", p_digest); log(">>> f_http_build_inner_ec_response: p_aes_sym_key= ", p_aes_sym_key); // Check expectred response if (p_responseCode != ok) { p_inner_ec_response := valueof( m_innerEcResponse_ko( p_request_hash, p_responseCode ) ); p_result := true; } else { // Generate the certificate if (f_generate_ec_certificate_for_inner_ec_response(valueof(p_inner_ec_request), p_private_key, p_digest, p_ec_certificate, p_ec_certificate_hashed_id8) == false) { log("f_http_build_inner_ec_response: Failed to generate the certificate"); p_inner_ec_response := valueof( m_innerEcResponse_ko( p_request_hash, incompleterequest ) ); } else { p_inner_ec_response := valueof( m_innerEcResponse_ok( p_request_hash, p_ec_certificate ) ); } } // Secure the response log("f_http_build_inner_ec_response: p_inner_ec_response= ", p_inner_ec_response); v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_ec_response(p_inner_ec_response))); v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_inner_ec_response: Failed to generate the certificate"); p_inner_ec_response := valueof( m_innerEcResponse_ko( p_request_hash, deniedrequest ) ); } else { p_result := true; } return p_result; } // End of function f_http_build_inner_ec_response function f_http_build_error_ec_response( in EnrolmentResponseCode p_responseCode := ok, in Oct16 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var boolean p_result := false; var InnerEcResponse v_inner_ec_response; // Check expectred response if (p_responseCode == ok) { return false; } v_inner_ec_response := valueof( m_innerEcResponse_ko( p_request_hash, p_responseCode ) ); // Secure the response log("f_http_build_error_ec_response: p_inner_ec_response= ", v_inner_ec_response); v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_ec_response(v_inner_ec_response))); v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_inner_ec_response: Failed to generate the certificate"); return false; } return true; } // End of function f_http_build_error_ec_response function f_http_build_authorization_request( in Certificate p_ec_certificate, // Enrolment credentials certificate in octetstring p_ec_private_key, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_key_mode, out octetstring p_private_enc_key, out octetstring p_public_compressed_enc_key, out integer p_compressed_enc_key_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring v_public_enc_key_x; var octetstring v_public_enc_key_y; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var InnerAtRequest v_inner_at_request; var Ieee1609Dot2Data v_inner_at_request_data; var InnerAtRequest v_authorization_request; var bitstring v_authorization_request_msg; // Generate the InnerAtRequest if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) { log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationRequest ***"); return false; } log("f_http_build_authorization_request: v_inner_at_request= ", v_inner_at_request); // Secure InnerAtRequest message if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_authorization_request: ERROR: Non canonical AA certificate ***"); return false; } log("*** f_http_build_authorization_request: Public encryption key: ", v_public_enc_key); log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("*** f_http_build_authorization_request: p_salt: ", p_salt); if (PICS_PKI_AUTH_POP) { if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***"); return false; } } else { // Only encryption of EtsiTs102941Data/InnerAtRequest log("*** f_http_build_authorization_request: POP signature not applied"); if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***"); return false; } } log("<<< f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("<<< f_http_build_authorization_request: DEBUG: p_request_hash= ", p_request_hash); return true; } // End of function f_http_build_authorization_request function f_http_build_authorization_request_with_wrong_private_key( in Certificate p_ec_certificate, // Enrolment credentials certificate in octetstring p_ec_private_key, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_key_mode, out octetstring p_private_enc_key, out octetstring p_public_compressed_enc_key, out integer p_compressed_enc_key_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring v_public_enc_key_x; var octetstring v_public_enc_key_y; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var InnerAtRequest v_inner_at_request; var Ieee1609Dot2Data v_inner_at_request_data; var InnerAtRequest v_authorization_request; var bitstring v_authorization_request_msg; // Generate the InnerAtRequest if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) { log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate AuthorizationRequest ***"); return false; } log("f_http_build_authorization_request_with_wrong_private_key: v_inner_at_request= ", v_inner_at_request); // Secure InnerAtRequest message /*** Use the wrong private key ***/ if (f_extract_enc_key(vc_eaCertificate/*Insted of vc_aaCertificate/*/, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Non canonical EA certificate ***"); return false; } log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key: ", v_public_enc_key); log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("*** f_http_build_authorization_request_with_wrong_private_key: p_salt: ", p_salt); if (PICS_PKI_AUTH_POP) { if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***"); return false; } } else { // Only encryption of EtsiTs102941Data/InnerAtRequest log("*** f_http_build_authorization_request_with_wrong_private_key: POP signature not applied"); if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***"); return false; } } log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_request_hash= ", p_request_hash); return true; } // End of function f_http_build_authorization_request_with_wrong_private_key function f_http_build_authorization_request_with_wrong_parameters( in Certificate p_ec_certificate, // Enrolment credentials certificate in octetstring p_ec_private_key, in boolean p_alter_pop_signature := false, in boolean p_alter_hmac := false, in boolean p_alter_signer_digest := false, in boolean p_alter_pks_recipient := false, in boolean p_alter_enc_key := false, in boolean p_alter_ea_id := false, in template (omit) Time32 p_start := omit, in template (omit) Duration p_duration := omit, in template (omit) Time64 p_generation_time := omit, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_key_mode, out octetstring p_private_enc_key, out octetstring p_public_compressed_enc_key, out integer p_compressed_enc_key_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring v_public_enc_key_x; var octetstring v_public_enc_key_y; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var InnerAtRequest v_inner_at_request; var Ieee1609Dot2Data v_inner_at_request_data; var InnerAtRequest v_authorization_request; var bitstring v_authorization_request_msg; var boolean v_ret_code; // Generate the InnerAtRequest if (p_alter_ea_id == true) { var HashedId8 v_ea_hashed_id8 := vc_eaHashedId8; v_ea_hashed_id8[0] := 'bb'O; v_ea_hashed_id8[1] := 'cc'O; log("f_http_build_authorization_request_with_wrong_parameters: Altered eaId= ", v_ea_hashed_id8); v_ret_code := f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, v_ea_hashed_id8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request); } else { v_ret_code := f_generate_inner_at_request_with_wrong_parameters(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_alter_hmac, p_alter_signer_digest, p_start, p_duration, p_generation_time, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request); } if (v_ret_code == false) { log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate AuthorizationRequest ***"); return false; } log("f_http_build_authorization_request_with_wrong_parameters: v_inner_at_request= ", v_inner_at_request); // Secure InnerAtRequest message if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Non canonical AA certificate ***"); return false; } log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key); log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("*** f_http_build_authorization_request_with_wrong_parameters: p_salt: ", p_salt); if (PICS_PKI_AUTH_POP) { if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_alter_pop_signature, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***"); return false; } } else { // Only encryption of EtsiTs102941Data/InnerAtRequest log("*** f_http_build_authorization_request_with_wrong_parameters: POP signature not applied"); if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***"); return false; } } log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); if (p_alter_enc_key == true) { /*** Alter encryption key to prevent decryption ***/ if (ischosen(p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256)) { p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[1] := 'aa'O; p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[2] := 'bb'O; } else { p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[1] := 'aa'O; p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[2] := 'bb'O; } log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered enc key= ", p_ieee1609dot2_signed_and_encrypted_data); } if (p_alter_pks_recipient == true) { p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].pskRecipInfo := int2oct(314259265, 8); // NOT equal to the HashedId8 of the certificate CERT_AA log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered pskRecipInfo= ", p_ieee1609dot2_signed_and_encrypted_data); } log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_request_hash= ", p_request_hash); return true; } // End of function f_http_build_authorization_request_with_wrong_parameters function f_http_build_authorization_response( in template (omit) InnerAtRequest p_inner_at_request := omit, in AuthorizationResponseCode p_responseCode := ok, in Oct16 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out InnerAtResponse p_inner_at_response, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var EtsiTs103097Certificate v_at_certificate; var boolean v_result := false; log(">>> f_http_build_authorization_response: p_inner_at_request= ", p_inner_at_request); log(">>> f_http_build_authorization_response: p_responseCode= ", p_responseCode); log(">>> f_http_build_authorization_response: p_request_hash= ", p_request_hash); log(">>> f_http_build_authorization_response: p_private_key= ", p_private_key); log(">>> f_http_build_authorization_response: p_digest= ", p_digest); log(">>> f_http_build_authorization_response: p_aes_sym_key= ", p_aes_sym_key); // Check expectred response if (p_responseCode != ok) { p_inner_at_response := valueof( m_innerAtResponse_ko( p_request_hash, p_responseCode ) ); v_result := true; } else { // Generate the certificate if (f_generate_at_certificate_for_inner_at_response(valueof(p_inner_at_request), p_private_key, p_digest, v_at_certificate) == false) { log("f_http_build_authorization_response: Failed to generate the certificate"); p_inner_at_response := valueof( m_innerAtResponse_ko( p_request_hash, its_aa_incompleterequest ) ); } else { p_inner_at_response := valueof( m_innerAtResponse_ok( p_request_hash, v_at_certificate ) ); } } // Secure the response log("f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response); v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_at_response(p_inner_at_response))); v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_authorization_response: Failed to generate the certificate"); p_inner_at_response := valueof( m_innerAtResponse_ko( p_request_hash, its_aa_deniedpermissions ) ); } else { v_result := true; } log("<<< f_http_build_authorization_response: v_result= ", v_result); log("<<< f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response); return v_result; } // End of function f_http_build_authorization_response function f_http_build_authorization_validation_request( in InnerAtRequest p_inner_at_request, in octetstring p_public_key_compressed, in integer p_compressed_key_mode, in octetstring p_private_enc_key, in octetstring p_public_compressed_enc_key, in integer p_compressed_enc_key_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var AuthorizationValidationRequest v_authorization_validation_request; var bitstring v_authorization_validation_request_msg; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; log(">>> f_http_build_authorization_validation_request"); // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest; // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature; // Secure the InnerAtRequest message if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("f_http_build_authorization_validation_request: Non canonical EA certificate"); return false; } log("f_http_build_authorization_validation_request: Public encryption key: ", v_public_enc_key); log("f_http_build_authorization_validation_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("f_http_build_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8); log("f_http_build_authorization_validation_request: p_salt: ", p_salt); if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("f_http_build_authorization_validation_request: Failed to generate Authorization Request"); return false; } log("f_http_build_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_authorization_validation_request: p_request_hash= ", p_request_hash); return true; } // End of function f_http_build_authorization_validation_request function f_http_build_invalid_authorization_validation_request( in InnerAtRequest p_inner_at_request, in octetstring p_public_key_compressed, in integer p_compressed_key_mode, in octetstring p_private_enc_key, in octetstring p_public_compressed_enc_key, in integer p_compressed_enc_key_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var AuthorizationValidationRequest v_authorization_validation_request; var bitstring v_authorization_validation_request_msg; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; log(">>> f_http_build_invalid_authorization_validation_request"); // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest; // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature; // Secure the InnerAtRequest message if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("f_http_build_invalid_authorization_validation_request: Non canonical EA certificate"); return false; } log("f_http_build_invalid_authorization_validation_request: Public encryption key: ", v_public_enc_key); log("f_http_build_invalid_authorization_validation_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("f_http_build_invalid_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8); log("f_http_build_invalid_authorization_validation_request: p_salt: ", p_salt); if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, true, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("f_http_build_invalid_authorization_validation_request: Failed to generate Authorization Request"); return false; } log("f_http_build_invalid_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_invalid_authorization_validation_request: p_request_hash= ", p_request_hash); return true; } // End of function f_http_build_invalid_authorization_validation_request function f_http_build_authorization_validation_response( in SharedAtRequest p_shared_at_request, in AuthorizationValidationResponseCode p_responseCode := ok, in Oct16 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out AuthorizationValidationResponse p_authorization_validation_response, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var boolean v_result := false; log(">>> f_http_build_authorization_validation_response: p_shared_at_request= ", p_shared_at_request); log(">>> f_http_build_authorization_validation_response: p_responseCode= ", p_responseCode); log(">>> f_http_build_authorization_validation_response: p_request_hash= ", p_request_hash); log(">>> f_http_build_authorization_validation_response: p_private_key= ", p_private_key); log(">>> f_http_build_authorization_validation_response: p_digest= ", p_digest); log(">>> f_http_build_authorization_validation_response: p_aes_sym_key= ", p_aes_sym_key); // Check expectred response if (p_responseCode != ok) { p_authorization_validation_response := valueof( m_authorizationValidationResponse_ko( p_request_hash, p_responseCode ) ); v_result := true; } else { p_authorization_validation_response := valueof(m_authorizationValidationResponse_ok( p_request_hash, p_shared_at_request.requestedSubjectAttributes ) ); } log("f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response); // Encapsulte authorization validation response into EtsiTs102941Data v_msg := bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_response(p_authorization_validation_response))); // Secure the response v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_authorization_validation_response: Failed to generate the certificate"); p_authorization_validation_response := valueof( m_authorizationValidationResponse_ko( p_request_hash, deniedpermissions ) ); } else { v_result := true; } log("<<< f_http_build_authorization_validation_response: v_result= ", v_result); log("<<< f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response); return v_result; } // End of function f_http_build_authorization_validation_response function f_http_build_butterfly_authorization_request_message( // TODO Cleanup parameters in Oct32 p_private_key_ec, in HashedId8 p_ec_cert_hashed_id8, out octetstring p_caterpillar_private_key, out octetstring p_caterpillar_public_key_compressed, out integer p_caterpillar_compressed_mode, out octetstring p_caterpillar_enc_private_key, out octetstring p_caterpillar_enc_public_key_compressed, out integer p_caterpillar_enc_compressed_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash, out EeRaCertRequest p_ee_ra_cert_request ) runs on ItsPkiHttp return boolean { var Ieee1609Dot2Data v_ee_ra_cert_request_signed; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var boolean v_result; log(">>> f_http_build_butterfly_authorization_request_message: p_private_key_ec: ", p_private_key_ec); log(">>> f_http_build_butterfly_authorization_request_message: p_ec_cert_hashed_id8: ", p_ec_cert_hashed_id8); // Generate EeRaCertRequest if (f_generate_ee_ra_cert_request(p_caterpillar_private_key, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode, p_caterpillar_enc_private_key, p_caterpillar_enc_public_key_compressed, p_caterpillar_enc_compressed_mode, p_ee_ra_cert_request) == false) { log("*** f_http_build_butterfly_authorization_request_message: ERROR: Failed to generate InnerEcRequest ***"); return false; } log ("f_http_build_butterfly_authorization_request_message: p_ee_ra_cert_request: ", p_ee_ra_cert_request); // Secure EeRaCertRequest if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_butterfly_authorization_request_message: ERROR: Non canonical EA certificate ***"); return false; } log("f_http_build_butterfly_authorization_request_message: Public encryption key: ", v_public_enc_key); log("f_http_build_butterfly_authorization_request_message: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. v_result := f_build_pki_secured_request_message_signed_with_pop(p_private_key_ec, valueof(m_signerIdentifier_digest(p_ec_cert_hashed_id8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_cert_request(p_ee_ra_cert_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); if (v_result == false) { log("*** f_http_build_butterfly_authorization_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); return false; } else { log("f_http_build_butterfly_authorization_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_butterfly_authorization_request_message: p_request_hash= ", p_request_hash); } return true; } // End of function f_http_build_butterfly_authorization_request_message function f_http_build_butterfly_authorization_response_message( in EeRaCertRequest p_ee_ra_cert_request, in HashedId8 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out RaEeCertInfo p_ra_ee_cert_info, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) runs on ItsPkiHttp return boolean { var bitstring v_msg_bit; var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var boolean v_result := false; log(">>> f_http_build_butterfly_authorization_response_message: p_ee_ra_cert_request= ", p_ee_ra_cert_request); log(">>> f_http_build_butterfly_authorization_response_message: p_request_hash= ", p_request_hash); log(">>> f_http_build_butterfly_authorization_response_message: p_private_key= ", p_private_key); log(">>> f_http_build_butterfly_authorization_response_message: p_digest= ", p_digest); log(">>> f_http_build_butterfly_authorization_response_message: p_aes_sym_key= ", p_aes_sym_key); // Generate EeRaCertRequest if (f_generate_ra_ee_cert_info(p_ee_ra_cert_request, p_request_hash, p_ra_ee_cert_info) == false) { log("*** f_http_build_butterfly_authorization_response_message: ERROR: Failed to generate InnerEcRequest ***"); return v_result; } log ("f_http_build_butterfly_authorization_response_message: p_ra_ee_cert_info: ", p_ra_ee_cert_info); // Secure the response v_msg := bit2oct(encvalue(m_etsiTs102941Data_ra_ee_cert_info(p_ra_ee_cert_info))); v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_butterfly_authorization_response_message: Failed to generate the certificate"); return v_result; } else { v_result := true; } log("<<< f_http_build_butterfly_authorization_response_message: v_result= ", v_result); return v_result; } // End of function f_http_build_butterfly_authorization_response_message function f_http_build_butterfly_cert_request( in EeRaCertRequest p_ee_ra_cert_request, in octetstring p_private_key := ''O, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out RaAcaCertRequest p_ra_aca_cert_request, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { // Local variables var Ieee1609Dot2Data v_ra_aca_cert_request_signed; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var boolean v_result; log(">>> f_http_build_butterfly_cert_request: p_ee_ra_cert_request= ", p_ee_ra_cert_request); log(">>> f_http_build_butterfly_cert_request: p_private_key= ", p_private_key); p_ra_aca_cert_request := valueof( m_ra_aca_cert_request( p_ee_ra_cert_request.generationTime, p_ee_ra_cert_request.type_, '00000000'B, // FIXME What does it mean? ETSI TS 102 941 V2.1.1 (2021-10) Figure 27 Bullet 1 dash #3 p_ee_ra_cert_request.tbsCert, -, omit // FIXME Shall be the cocoon key that shall be derived by the EA ETSI TS 102 941 V2.1.1 (2021-10) Figure 27 Bullet 1 dash #4 )); log("f_http_build_butterfly_cert_request: p_ra_aca_cert_request= ", p_ra_aca_cert_request); // Secure RaAcaCertRequest if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_butterfly_cert_request: ERROR: Non canonical EA certificate ***"); return false; } log("f_http_build_butterfly_cert_request: Public encryption key: ", v_public_enc_key); log("f_http_build_butterfly_cert_request: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. v_result := f_build_pki_secured_request_message_signed_with_pop(vc_eaPrivateKey, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ra_aca_cert_request(p_ra_aca_cert_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); if (v_result == false) { log("*** f_http_build_butterfly_cert_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); return false; } else { log("f_http_build_butterfly_cert_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_butterfly_cert_request: p_request_hash= ", p_request_hash); } return true; } // End of function f_http_build_butterfly_cert_request function f_http_build_butterfly_cert_response( in HashedId8 p_request_hash, in octetstring p_private_key := ''O, in octetstring p_digest := ''O, in Oct16 p_aes_sym_key, out AcaRaCertResponse p_aca_ra_cert_response, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) runs on ItsPkiHttp return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct12 v_nonce; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var boolean v_result := false; log(">>> f_http_build_butterfly_cert_response: p_request_hash= ", p_request_hash); log(">>> f_http_build_butterfly_cert_response: p_private_key= ", p_private_key); log(">>> f_http_build_butterfly_cert_response: p_digest= ", p_digest); log(">>> f_http_build_butterfly_cert_response: p_aes_sym_key= ", p_aes_sym_key); p_aca_ra_cert_response := valueof( m_ra_aca_cert_response( f_getCurrentTimeUtc(), p_request_hash, m_aca_response_plain(m_etsiTs103097Data_unsecured(''O)) // FIXME FSCOM )); // Secure the response log("f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response); v_msg := bit2oct(encvalue(m_etsiTs102941Data_aca_ra_cert_response(p_aca_ra_cert_response))); v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) if (f_build_pki_secured_response_message(p_private_key, valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, v_msg, p_aes_sym_key, v_nonce, p_ieee1609dot2_signed_and_encrypted_data ) == false) { log("f_http_build_butterfly_cert_response: Failed to generate the certificate"); } else { v_result := true; } log("<<< f_http_build_butterfly_cert_response: v_result= ", v_result); log("<<< f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response); return v_result; } // End of function f_http_build_butterfly_cert_response function f_http_build_butterfly_at_download_request_message( in charstring p_filename, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp return boolean { var EeRaDownloadRequest v_ee_ra_download_request; var Ieee1609Dot2Data v_ee_ra_download_request_signed; var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var octetstring v_private_key; var boolean v_result; log(">>> f_http_build_butterfly_at_download_request_message: p_filename: ", p_filename); // Generate EeRaDownloadRequest if (f_generate_ee_ra_download_request(p_filename, v_ee_ra_download_request) == false) { log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequest ***"); return false; } log ("f_http_build_butterfly_at_download_request_message: v_ee_ra_download_request: ", v_ee_ra_download_request); // Secure EeRaDownloadRequest if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { log("*** f_http_build_butterfly_at_download_request_message: ERROR: Non canonical EA certificate ***"); return false; } log("f_http_build_butterfly_at_download_request_message: Public encryption key: ", v_public_enc_key); log("f_http_build_butterfly_at_download_request_message: Public encryption key comp: ", v_compressed_enc_key_mode); p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("f_http_build_butterfly_at_download_request_message: vc_ec_keys_counter: ", vc_ec_keys_counter); log("f_http_build_butterfly_at_download_request_message: vc_ec_private_keys: ", vc_ec_private_keys); log("f_http_build_butterfly_at_download_request_message: vc_ec_cert_hashed_id8: ", vc_ec_hashed_id8); v_result := f_build_pki_secured_request_message_signed_with_pop(vc_ec_private_keys[vc_ec_keys_counter - 1], valueof(m_signerIdentifier_digest(vc_ec_hashed_id8[vc_ec_keys_counter - 1])), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_download_request(v_ee_ra_download_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); if (v_result == false) { log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); return false; } else { log("f_http_build_butterfly_at_download_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data); log("f_http_build_butterfly_at_download_request_message: p_request_hash= ", p_request_hash); } return true; } // End of function f_http_build_butterfly_at_download_request_message function f_http_build_dc_request( // TODO Cleanup parameters in charstring p_ea_certificate_id, in charstring p_aa_certificate_id, in charstring p_rca_certificate_id, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out octetstring p_salt, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct32 p_request_hash ) runs on ItsPkiHttp { } // End of function } // End of group http group generate_certificates { function f_generate_ec_certificate( out octetstring p_private_key, out Certificate p_ec_certificate ) return boolean { var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring p_public_key_compressed; var integer p_compressed_mode; var EccP256CurvePoint v_ecc_p256_curve_point; var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(36, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM })), valueof(m_appPermissions(37, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_DENM })) }; var template (value) EtsiTs103097Certificate v_cert; var bitstring v_tbs; var Oct32 v_sig; var bitstring v_enc_msg; var PublicVerificationKey v_public_verification_key; log(">>> f_generate_ec_certificate"); log("f_generate_ec_certificate: PX_EC_ALG_FOR_EC=", PX_EC_ALG_FOR_EC); log("f_generate_ec_certificate: PX_VE_ALG=", PX_VE_ALG); // Generate verification keys for the certificate if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) { log("f_generate_ec_certificate: Failed to generate verification key"); return false; } if (p_compressed_mode == 0) { v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed)); } else { v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed)); } if (PX_EC_ALG_FOR_EC == e_nist_p256) { v_public_verification_key := valueof( m_publicVerificationKey_ecdsaNistP256( v_ecc_p256_curve_point )); } else if (PX_EC_ALG_FOR_EC == e_nist_p384) { // FIXME FSCOM // v_public_verification_key := valueof( // m_publicVerificationKey_ecdsaNistP384( // v_ecc_p384_curve_point // )); } else if (PX_EC_ALG_FOR_EC == e_brainpool_p256_r1) { v_public_verification_key := valueof( m_publicVerificationKey_ecdsaBrainpoolP256r1( v_ecc_p256_curve_point )); } else if (PX_EC_ALG_FOR_EC == e_brainpool_p384_r1) { // FIXME FSCOM // v_public_verification_key := valueof( // m_publicVerificationKey_ecdsaBrainpoolP384r1( // v_ecc_p384_curve_point // )); } else if (PX_EC_ALG_FOR_EC == e_sm2_p256) { // FIXME FSCOM } else { log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx"); return false; } v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(f_hashWithSha256('616263'O))), m_toBeSignedCertificate_at( v_appPermissions, m_verificationKeyIndicator_verificationKey( v_public_verification_key ), m_validityPeriod( f_getCurrentTime() / 1000, m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ) ); // Encode it ==> Get octetstring v_tbs := encvalue(v_cert.toBeSigned); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key); if (PX_VE_ALG == e_nist_p256) { v_cert.signature_ := m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { // FIXME FSCOM v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_nist_p384) { v_cert.signature_ := m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ); } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ); } log("f_generate_ec_certificate: v_cert= ", v_cert); p_ec_certificate := valueof(v_cert); return true; } // End of function f_generate_ec_certificate function f_generate_ec_certificate_for_inner_ec_response( in InnerEcRequest p_inner_ec_request, in octetstring p_private_key, in octetstring p_digest, out EtsiTs103097Certificate p_ec_certificate, out HashedId8 p_ec_certificate_hashed_id8 ) return boolean { var CertificateId v_certificate_id; var EtsiTs103097Certificate v_cert; var IssuerIdentifier v_issuer; var bitstring v_tbs; var octetstring v_sig; var ValidityPeriod v_valPeriod; log(">>> f_generate_ec_certificate_for_inner_ec_response: p_inner_ec_request: ", p_inner_ec_request); log(">>> f_generate_ec_certificate_for_inner_ec_response: p_digest: ", p_digest); v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384 if (not(ispresent(p_inner_ec_request.requestedSubjectAttributes.id))) { v_certificate_id := { none_ := NULL }; } else { v_certificate_id := p_inner_ec_request.requestedSubjectAttributes.id; } if (ispresent(p_inner_ec_request.requestedSubjectAttributes.validityPeriod)) { v_valPeriod := p_inner_ec_request.requestedSubjectAttributes.validityPeriod; } else { v_valPeriod := valueof(m_validityPeriod(f_getCurrentTime() / 1000, m_duration_in_hours(24))); } v_cert := valueof( m_etsiTs103097Certificate( v_issuer, m_toBeSignedCertificate_ec( v_certificate_id, p_inner_ec_request.requestedSubjectAttributes.appPermissions, m_verificationKeyIndicator_verificationKey( p_inner_ec_request.publicKeys.verificationKey ), v_valPeriod, p_inner_ec_request.requestedSubjectAttributes.region, p_inner_ec_request.requestedSubjectAttributes.assuranceLevel, p_inner_ec_request.publicKeys.encryptionKey ) ) ); // Encode it ==> Get octetstring v_tbs := encvalue(v_cert.toBeSigned); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key); if (PX_VE_ALG == e_nist_p256) { v_cert.signature_ := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } else if (PX_VE_ALG == e_nist_p384) { v_cert.signature_ := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } p_ec_certificate := valueof(v_cert); // Encode it and calculate HashedId8 v_tbs := encvalue(p_ec_certificate); p_ec_certificate_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(bit2oct(v_tbs))); log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate= ", p_ec_certificate); log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate_hashed_id8= ", p_ec_certificate_hashed_id8); return true; } // End of function f_generate_ec_certificate_for_inner_ec_response function f_generate_at_certificate_for_inner_at_response( in InnerAtRequest p_inner_at_request, in octetstring p_private_key, in octetstring p_digest, out EtsiTs103097Certificate p_at_certificate ) return boolean { var EtsiTs103097Certificate v_cert; var IssuerIdentifier v_issuer; var bitstring v_tbs; var octetstring v_sig; v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384 v_cert := valueof( m_etsiTs103097Certificate( v_issuer, m_toBeSignedCertificate_at( p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions, m_verificationKeyIndicator_verificationKey( p_inner_at_request.publicKeys.verificationKey ), p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.region, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.assuranceLevel, p_inner_at_request.publicKeys.encryptionKey ) ) ); // Encode it ==> Get octetstring v_tbs := encvalue(v_cert.toBeSigned); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key); log("f_generate_at_certificate_for_inner_at_response: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { v_cert.signature_ := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } else if (PX_VE_ALG == e_nist_p384) { v_cert.signature_ := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } p_at_certificate := valueof(v_cert); log("f_generate_at_certificate_for_inner_at_response: p_at_certificate= ", p_at_certificate); return true; } // End of function f_generate_at_certificate_for_inner_at_response function f_generate_at_certificate_for_authorization_response( in InnerAtRequest p_inner_at_request, in octetstring p_private_key, in octetstring p_digest, out EtsiTs103097Certificate p_at_certificate ) return boolean { var EtsiTs103097Certificate v_cert; var IssuerIdentifier v_issuer; var bitstring v_tbs; var octetstring v_sig; log(">>> f_generate_at_certificate_for_authorization_response"); v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384 v_cert := valueof( m_etsiTs103097Certificate( v_issuer, m_toBeSignedCertificate_ec( p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.id, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions, m_verificationKeyIndicator_verificationKey( p_inner_at_request.publicKeys.verificationKey ), p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.region, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.assuranceLevel, p_inner_at_request.publicKeys.encryptionKey ) ) ); // Encode it ==> Get octetstring v_tbs := encvalue(v_cert.toBeSigned); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key); if (PX_VE_ALG == e_nist_p256) { v_cert.signature_ := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_cert.signature_ := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } else if (PX_VE_ALG == e_nist_p384) { v_cert.signature_ := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) ) ); } p_at_certificate := valueof(v_cert); log("f_generate_at_certificate_for_authorization_response: p_at_certificate= ", p_at_certificate); return true; } // End of function f_generate_at_certificate_for_authorization_response } // End of group generate_certificates group inner_ec_xxx { function f_generate_inner_ec_request( out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out InnerEcRequest p_inner_ec_request ) runs on ItsPkiHttp return boolean { // Local variables var Oct32 v_public_key_x; var Oct32 v_public_key_y; var PublicVerificationKey v_public_verification_key; log (">>> f_generate_inner_ec_request"); log("f_generate_inner_ec_request: PX_VE_ALG=", PX_VE_ALG); // Generate keys for the certificate to be requested if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) { log ("f_generate_inner_ec_request: failed to generate keys"); return false; } // Build the Proof of Possession InnerEcRequest if (PX_VE_ALG == e_nist_p256) { var EccP256CurvePoint v_eccP256_curve_point; if (p_compressed_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)); } else if (PX_VE_ALG == e_brainpool_p256_r1) { var EccP256CurvePoint v_eccP256_curve_point; if (p_compressed_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point)); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else { var EccP384CurvePoint v_eccP384_curve_point; if (p_compressed_mode == 0) { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(p_public_key_compressed)); } else { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(p_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point)); } if (PICS_EC_SUBJECT_ATTRIBUT_ID) { p_inner_ec_request := valueof( m_innerEcRequest( PICS_ITS_S_CANONICAL_ID, m_publicKeys( v_public_verification_key ), m_certificateSubjectAttributes_id_name( oct2char(PICS_ITS_S_CANONICAL_ID) & int2str(f_getCurrentTime()), // ETSI TS 103 097 Clause 7.2.2 Enrolment credential { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, m_validityPeriod( f_getCurrentTime() / 1000, m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ) ) ); } else { p_inner_ec_request := valueof( m_innerEcRequest( PICS_ITS_S_CANONICAL_ID, m_publicKeys( v_public_verification_key ), m_certificateSubjectAttributes_id_omit( // ETSI TS 103 097 Clause 7.2.2 Enrolment credential { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, m_validityPeriod( f_getCurrentTime() / 1000, m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ) ) ); } // Remove geographical region (ETAS) if (not(PICS_EC_SUBJECT_ATTRIBUT_REGION)) { p_inner_ec_request.requestedSubjectAttributes.region := omit; } log("f_generate_inner_ec_request: PICS_SECPKI_REENROLMENT: ", PICS_SECPKI_REENROLMENT); log("f_generate_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter); if (PICS_SECPKI_REENROLMENT and (vc_ec_keys_counter > 0)) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential log("f_generate_inner_ec_request: This is a re-enrolment: vc_ec_keys_counter= ", vc_ec_keys_counter); log("f_generate_inner_ec_request: This is a re-enrolment: vc_ec_hashed_id8[vc_ec_keys_counter - 1]= ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]); p_inner_ec_request.itsId := vc_ec_hashed_id8[vc_ec_keys_counter - 1]; } log("<<< f_generate_inner_ec_request: ", p_inner_ec_request); return true; } // End of function f_generate_inner_ec_request function f_generate_inner_ec_request_with_wrong_parameters( in SequenceOfPsidSsp p_appPermissions, in octetstring p_canonical_id := PICS_ITS_S_CANONICAL_ID, in Time32 p_start, in Duration p_duration, in boolean p_alter_private_key := false, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_mode, out InnerEcRequest p_inner_ec_request ) runs on ItsPkiHttp return boolean { // Local variables var Oct32 v_public_key_x; var Oct32 v_public_key_y; var octetstring v_private_key; var octetstring v_public_key_compressed; var integer v_compressed_mode; var PublicVerificationKey v_public_verification_key; log (">>> f_generate_inner_ec_request_with_wrong_parameters"); // Generate keys for the certificate to be requested if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) { log ("f_generate_inner_ec_request_with_wrong_parameters: failed to generate keys"); return false; } if (p_alter_private_key == false) { v_private_key := p_private_key; v_public_key_compressed := p_public_key_compressed; v_compressed_mode := p_compressed_mode; } else { log ("f_generate_inner_ec_request_with_wrong_parameters: Alter verify private key"); if (f_generate_key_pair(v_private_key, v_public_key_x, v_public_key_y, v_public_key_compressed, v_compressed_mode) == false) { log ("f_generate_inner_ec_request_with_wrong_parameters: failed to generate keys"); return false; } } // Build the Proof of Possession InnerEcRequest log("f_generate_inner_ec_request_with_wrong_parameters: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { var EccP256CurvePoint v_eccP256_curve_point; if (v_compressed_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_compressed)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)); } else if (PX_VE_ALG == e_brainpool_p256_r1) { var EccP256CurvePoint v_eccP256_curve_point; if (v_compressed_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_compressed)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point)); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else { var EccP384CurvePoint v_eccP384_curve_point; if (v_compressed_mode == 0) { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_compressed)); } else { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_compressed)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point)); } if (PICS_EC_SUBJECT_ATTRIBUT_ID) { p_inner_ec_request := valueof( m_innerEcRequest( p_canonical_id, m_publicKeys( v_public_verification_key ), m_certificateSubjectAttributes_id_name( oct2char(PICS_ITS_S_CANONICAL_ID), p_appPermissions, // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs m_validityPeriod( p_start, p_duration ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ) ) ); } else { p_inner_ec_request := valueof( m_innerEcRequest( p_canonical_id, m_publicKeys( v_public_verification_key ), m_certificateSubjectAttributes_id_omit( // ETSI TS 103 097 Clause 7.2.2 Enrolment credential p_appPermissions, // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs m_validityPeriod( p_start, p_duration ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ) ) ); }// Remove geographical region (ETAS) if (not(PICS_EC_SUBJECT_ATTRIBUT_REGION)) { p_inner_ec_request.requestedSubjectAttributes.region := omit; } log("f_generate_inner_ec_request_with_wrong_parameters: ", p_inner_ec_request); return true; } // End of function f_generate_inner_ec_request_with_wrong_parameters function f_generate_inner_ec_request_signed_for_pop( in octetstring p_private_key, in InnerEcRequest p_inner_ec_request, out Ieee1609Dot2Data p_inner_ec_request_signed_for_pop ) runs on ItsPkiHttp return boolean { // Local variables var template (value) EccP256CurvePoint v_eccP256_curve_point; var octetstring v_encoded_inner_ec_request; var template (value) ToBeSignedData v_tbs; var octetstring v_tbs_signed; var Signature v_signature; // Encode it log("f_generate_inner_ec_request_signed_for_pop: encode ", p_inner_ec_request); v_encoded_inner_ec_request := bit2oct(encvalue(p_inner_ec_request)); // Signed the encoded InnerEcRequestSignedForPop v_tbs := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured( v_encoded_inner_ec_request ) ), m_headerInfo_inner_pki_request( -, (f_getCurrentTime() * 1000) //us ) ); // Signed the encoded InnerEcRequestSignedForPop log("f_generate_inner_ec_request_signed_for_pop: tbs= ", v_tbs); log("f_generate_inner_ec_request_signed_for_pop: tbs= ", bit2oct(encvalue(v_tbs))); v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key); // Finalyse signed InnerEcRequestSignedForPop if (PX_VE_ALG == e_nist_p256) { v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } else if (PX_VE_ALG == e_nist_p384) { v_signature := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } log("f_generate_inner_ec_request_signed_for_pop: v_signature= ", v_signature); p_inner_ec_request_signed_for_pop := valueof( m_etsiTs103097Data_signed( m_signedData( sha256, v_tbs, m_signerIdentifier_self, v_signature ) ) ); log("<<< f_generate_inner_ec_request_signed_for_pop: p_inner_ec_request_signed_for_pop= ", p_inner_ec_request_signed_for_pop); return true; } // End of function f_generate_inner_ec_request_signed_for_pop function f_verify_inner_ec_request_signed_for_pop( in EtsiTs102941Data p_etsi_ts_102941_data, out InnerEcRequest p_inner_ec_request ) return boolean { var bitstring v_msg_bit; log(">>> f_verify_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data); // 1. Decode content v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, p_inner_ec_request) != 0) { log("f_verify_inner_ec_request_signed_for_pop: Failed to decode InnerEcRequest"); return false; } else { log("f_verify_inner_ec_request_signed_for_pop: v_inner_ec_request= ", p_inner_ec_request); // 2. Verify the InnerEcRequestSignedForPop signature // TODO } return true; } // End of function f_verify_inner_ec_request_signed_for_pop function f_generate_inner_ec_response( in octetstring p_inner_ec_request_hash, in EtsiTs103097Certificate p_certificate, out InnerEcResponse p_inner_ec_response ) return boolean { // Local variables // Build the Proof of Possession InnerEcResponse p_inner_ec_response := valueof( m_innerEcResponse_ok( substr(p_inner_ec_request_hash, 0, 16), p_certificate ) ); return true; } // End of function f_generate_inner_ec_response } // End of group inner_ec_xxx group inner_at_xxx { function f_generate_inner_at_request( in Certificate p_aa_certificate, in SignAlgorithm p_enc_algo := PX_EC_ALG_FOR_EC_SIGN, in Oct8 p_aa_hashed_id8, in Certificate p_ea_certificate, in octetstring p_salt, in Oct8 p_ea_hashed_id8, in Certificate p_ec_certificate, in octetstring p_ec_private_key, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_key_mode, out octetstring p_private_enc_key, out octetstring p_public_compressed_enc_key, out integer p_compressed_enc_key_mode, out InnerAtRequest p_inner_at_request ) return boolean { // Local variables var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring v_public_enc_key_x; var octetstring v_public_enc_key_y; var bitstring v_enc_value; var octetstring v_ec_hash; var PublicVerificationKey v_public_verification_key; var BasePublicEncryptionKey v_public_encryption_key; var Oct8 v_ec_hashed_id8; var octetstring public_enc_key_x; var octetstring public_enc_key_y; var Oct32 v_hmac_key; var PublicVerificationKey v_verification_tag; var PublicEncryptionKey v_encryption_tag; var octetstring v_encoded_tag; var Oct16 v_key_tag; var octetstring v_hash_shared_at_request; var template (value) ToBeSignedData v_tbs; var octetstring v_tbs_signed; var Ieee1609Dot2Data v_signed_at_signature; var template (value) EccP256CurvePoint v_eccP256_curve_point; var HashAlgorithm v_hashId; var Signature v_signature; var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM })), valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM })) }; log(">>> f_generate_inner_at_request: p_enc_algo=", p_enc_algo); // Generate verification keys for the certificate to be requested if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) { log("f_generate_inner_at_request: Failed to generate verification key"); return false; } log ("f_generate_inner_at_request: AT verification private key: ", p_private_key); log ("f_generate_inner_at_request: AT verification public compressed key: ", p_public_key_compressed); log ("f_generate_inner_at_request: AT verification public compressed mode: ", p_compressed_key_mode); // Generate encryption keys for the certificate to be requested if (PX_INCLUDE_ENCRYPTION_KEYS) { if (f_generate_key_pair_for_encryption(p_enc_algo, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) { log("f_generate_inner_at_request: Failed to generate encryption key"); return false; } else { log ("f_generate_inner_at_request: AT encryption private key: ", p_private_enc_key); log ("f_generate_inner_at_request: AT encryption public compressed key: ", p_public_compressed_enc_key); log ("f_generate_inner_at_request: AT encryption public compressed mode: ", p_compressed_enc_key_mode); } } else { p_private_enc_key := ''O; v_public_enc_key_x := ''O; v_public_enc_key_y := ''O; p_public_compressed_enc_key := ''O; p_compressed_enc_key_mode := -1; } // Generate 32 octets length secret key v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12)); log("f_generate_inner_at_request: v_hmac_key= ", v_hmac_key); // Generate tag based on the concatenation of verification keys & encryption keys if (f_generate_key_tag(p_public_key_compressed, p_compressed_key_mode, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_encoded_tag) == false) { log("f_generate_inner_at_request: Failed to generate Key tag"); return false; } log("f_generate_inner_at_request: v_encoded_tag= ", v_encoded_tag); v_key_tag := substr( fx_hmac_sha256( // TODO Rename and use a wrapper function v_hmac_key, v_encoded_tag ), 0, 16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously log("f_generate_inner_at_request: v_key_tag= ", v_key_tag); // Build the SharedAtRequest p_inner_at_request.sharedAtRequest := valueof( m_shared_at_request( p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity v_key_tag, // Calculated keyTag valueof( m_certificate_subject_attributes( // FIXME Review subjectPermissions v_appPermissions, p_ec_certificate.toBeSigned.certRequestPermissions, -,//{ none_ := NULL },//p_ec_certificate.toBeSigned.id, p_ec_certificate.toBeSigned.validityPeriod, p_ec_certificate.toBeSigned.region, p_ec_certificate.toBeSigned.assuranceLevel ))) // Desired attributes ); // Calculate the hash of the SharedAtRequest v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest))); log("f_generate_inner_at_request: v_hash_shared_at_request= ", v_hash_shared_at_request); // Build the ETsiTs103097Data-SignedExternalPayload v_tbs := m_toBeSignedData( m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash m_headerInfo_inner_pki_request( // HeaderInfo -, (f_getCurrentTime()) * 1000) //us ); log("f_generate_inner_at_request: v_tbs= ", v_tbs); // Calculate the whole certificate SHA v_enc_value := encvalue(p_ec_certificate); if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384) or ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value)); v_ec_hashed_id8 := f_hashedId8FromSha384(v_ec_hash); } else { v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value)); v_ec_hashed_id8 := f_hashedId8FromSha256(v_ec_hash); } log("f_generate_inner_at_request: v_ec_hash= ", v_ec_hash); // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { v_hashId := sha384; v_tbs_signed := f_signWithEcdsaBrainpoolp384r1WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384)) { v_hashId := sha384; v_tbs_signed := f_signWithEcdsaNistp384WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } else { v_hashId := sha256; if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) { v_tbs_signed := f_signWithEcdsaBrainpoolp256r1WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else { // Error log("f_generate_inner_at_request: Failed to process signature"); return false; } } v_signed_at_signature := valueof( m_etsiTs103097Data_signed( m_signedData( v_hashId, v_tbs, m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is the hasheId8 of the EC certificate obtained from Enrolment request v_signature ) ) ); log("f_generate_inner_at_request: v_signed_at_signature= ", v_signed_at_signature); log("f_generate_inner_at_request: p_ea_certificate= ", p_ea_certificate); if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure var octetstring v_public_enc_key; var integer v_compressed_mode; var Oct12 v_nonce; var Oct16 v_authentication_vector; var Oct16 v_aes_sym_key; var Oct16 v_encrypted_sym_key; var HashedId8 v_recipientId; var octetstring v_public_compressed_ephemeral_key; var integer v_public_compressed_ephemeral_mode; var octetstring v_enc_signed_ec_signature; var EncryptedDataEncryptionKey v_encrypted_data_encryption_key; // Use EA certificate for the encryption if (p_enc_algo == e_nist_p256) { if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0; v_compressed_mode := 0; } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1; v_compressed_mode := 1; } else { log("f_generate_inner_at_request: Wrong NistP256 encryption variant"); return false; } v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce); if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, v_encrypted_sym_key, v_authentication_vector ))); } else if (p_enc_algo == e_brainpool_p256_r1) { if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0; v_compressed_mode := 0; } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1; v_compressed_mode := 1; } else { log("f_generate_inner_at_request: Wrong BrainpoolP256r1 encryption variant"); return false; } v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256r1WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce); if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesBrainpoolP256r1( m_evciesP256EncryptedKey( v_eccP256_curve_point, v_encrypted_sym_key, v_authentication_vector ))); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else { log("f_generate_inner_at_request: Wrong encryption variant"); return false; } log("f_generate_inner_at_request: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key); v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate log("f_generate_inner_at_request: v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) p_inner_at_request.ecSignature := valueof( m_ec_signature( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_certRecipInfo( m_pKRecipientInfo( v_recipientId, v_encrypted_data_encryption_key )) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( v_nonce, v_enc_signed_ec_signature ) ) ) ) ) ); } else if (p_enc_algo == e_sm2_p256) { // FIXME FSCOM } else { // Skip the encryption, alowed to be re-identified by the AA p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature)); } // Build the InnerAtRequest, EcSignature field is already set if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { if (p_compressed_key_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)); } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) { if (p_compressed_key_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point)); } else { var EccP384CurvePoint v_eccP384_curve_point; if (p_compressed_key_mode == 0) { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point)); } if (PX_INCLUDE_ENCRYPTION_KEYS) { var template (value) EccP256CurvePoint v_enc_eccP256_curve_point; if (p_compressed_enc_key_mode == 0) { v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x); } else { v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x); } if (p_enc_algo == e_nist_p256) { v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point)); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else { v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point)); } p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate m_publicKeys( v_public_verification_key, m_encryptionKey( // FIXME Encryption keys could be optional -, v_public_encryption_key ) ) ); } else { p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate m_publicKeys( v_public_verification_key ) ); } p_inner_at_request.hmacKey := v_hmac_key; log("f_generate_inner_at_request: p_inner_at_request= ", p_inner_at_request); return true; } // End of function f_generate_inner_at_request function f_generate_inner_at_request_with_wrong_parameters( in Certificate p_aa_certificate, in SignAlgorithm p_enc_algo := PX_EC_ALG_FOR_AT, in Oct8 p_aa_hashed_id8, in Certificate p_ea_certificate, in octetstring p_salt, in Oct8 p_ea_hashed_id8, in Certificate p_ec_certificate, in octetstring p_ec_private_key, in boolean p_alter_hmac := false, in boolean p_alter_signer_digest := false, in template (omit) Time32 p_start := omit, in template (omit) Duration p_duration := omit, in template (omit) Time64 p_generation_time := omit, out octetstring p_private_key, out octetstring p_public_key_compressed, out integer p_compressed_key_mode, out octetstring p_private_enc_key, out octetstring p_public_compressed_enc_key, out integer p_compressed_enc_key_mode, out InnerAtRequest p_inner_at_request ) return boolean { // Local variables var octetstring v_public_key_x; var octetstring v_public_key_y; var octetstring v_public_enc_key_x; var octetstring v_public_enc_key_y; var bitstring v_enc_value; var octetstring v_ec_hash; var PublicVerificationKey v_public_verification_key; var BasePublicEncryptionKey v_public_encryption_key; var Oct8 v_ec_hashed_id8; var octetstring public_enc_key_x; var octetstring public_enc_key_y; var Oct32 v_hmac_key; var PublicVerificationKey v_verification_tag; var PublicEncryptionKey v_encryption_tag; var octetstring v_encoded_tag; var Oct16 v_key_tag; var octetstring v_hash_shared_at_request; var template (value) ToBeSignedData v_tbs; var octetstring v_tbs_signed; var Ieee1609Dot2Data v_signed_at_signature; var template (value) EccP256CurvePoint v_eccP256_curve_point; var template (value) EccP256CurvePoint v_enc_eccP256_curve_point; var HashAlgorithm v_hashId; var Signature v_signature; var Time32 v_start; var Duration v_duration; var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM })), valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM })) }; log("f_generate_inner_at_request_with_wrong_parameters: p_enc_algo=", p_enc_algo); // Generate verification keys for the certificate to be requested if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) { log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate verification key"); return false; } log ("f_generate_inner_at_request_with_wrong_parameters: AT verification private key: ", p_private_key); log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed key: ", p_public_key_compressed); log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed mode: ", p_compressed_key_mode); // Generate encryption keys for the certificate to be requested if (PX_INCLUDE_ENCRYPTION_KEYS) { if (f_generate_key_pair_for_encryption(p_enc_algo, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) { log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate encryption key"); return false; } else { log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption private key: ", p_private_enc_key); log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed key: ", p_public_compressed_enc_key); log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed mode: ", p_compressed_enc_key_mode); } } else { p_private_enc_key := ''O; v_public_enc_key_x := ''O; v_public_enc_key_y := ''O; p_public_compressed_enc_key := ''O; p_compressed_enc_key_mode := -1; } // Calculate the whole certificate SHA v_enc_value := encvalue(p_ec_certificate); if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) { v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value)); v_ec_hashed_id8 := f_hashedId8FromSha256(v_ec_hash); } else { v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value)); v_ec_hashed_id8 := f_hashedId8FromSha384(v_ec_hash); } log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hash= ", v_ec_hash); log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hashed_id8= ", v_ec_hashed_id8); if (p_alter_signer_digest == true) { v_ec_hashed_id8 := int2oct((f_getCurrentTimeUtc() * 1000), 8); log("f_generate_inner_at_request_with_wrong_parameters: Altered v_ec_hashed_id8= ", v_ec_hashed_id8); } // Generate 32 octets length secret key v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12)); log("f_generate_inner_at_request_with_wrong_parameters: v_hmac_key= ", v_hmac_key); // Generate tag based on the concatenation of verification keys & encryption keys if (f_generate_key_tag(p_public_key_compressed, p_compressed_key_mode, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_encoded_tag) == false) { log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate Key tag"); return false; } log("f_generate_inner_at_request_with_wrong_parameters: v_encoded_tag= ", v_encoded_tag); // Generate hmac key v_key_tag := substr( fx_hmac_sha256( // TODO Rename and use a wrapper function v_hmac_key, v_encoded_tag ), 0, 16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously log("f_generate_inner_at_request_with_wrong_parameters: v_key_tag= ", v_key_tag); if (p_alter_hmac == true) { v_hmac_key[0] := 'aa'O; v_hmac_key[1] := 'bb'O; log("f_generate_inner_at_request_with_wrong_parameters: Altered key_tag= ", v_hmac_key); } // Build the SharedAtRequest if (not(ispresent(p_start))) { v_start := p_ec_certificate.toBeSigned.validityPeriod.start_; } else { v_start := valueof(p_start); log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.start= ", v_start); } if (not(ispresent(p_duration))) { v_duration := p_ec_certificate.toBeSigned.validityPeriod.duration; } else { v_duration := valueof(p_duration); log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.duration= ", v_duration); } p_inner_at_request.sharedAtRequest := valueof( m_shared_at_request( p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity v_key_tag, // Calculated keyTag valueof( m_certificate_subject_attributes( v_appPermissions, p_ec_certificate.toBeSigned.certRequestPermissions, { none_ := NULL },//p_ec_certificate.toBeSigned.id, m_validityPeriod(v_start, v_duration), p_ec_certificate.toBeSigned.region, p_ec_certificate.toBeSigned.assuranceLevel ))) // Desired attributes ); // Calculate the hash of the SharedAtRequest v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest))); log("f_generate_inner_at_request_with_wrong_parameters: v_hash_shared_at_request= ", v_hash_shared_at_request); // Build the ETsiTs103097Data-SignedExternalPayload if (ispresent(p_generation_time)) { v_tbs := m_toBeSignedData( m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash m_headerInfo_inner_pki_request( // HeaderInfo -, valueof(p_generation_time) * 1000) //us ); log("f_generate_inner_at_request_with_wrong_parameters: Altered generation time: v_tbs= ", v_tbs); } else { v_tbs := m_toBeSignedData( m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash m_headerInfo_inner_pki_request( // HeaderInfo -, f_getCurrentTime() * 1000) //us ); log("f_generate_inner_at_request_with_wrong_parameters: v_tbs= ", v_tbs); } // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted // TODO Simplify with f_signWithEcdsa if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { v_hashId := sha384; v_tbs_signed := f_signWithEcdsaBrainpoolp384r1WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } else { v_hashId := sha256; if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) { v_tbs_signed := f_signWithEcdsaBrainpoolp256r1WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key); v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else { // Error log("f_generate_inner_at_request_with_wrong_parameters: Failed to process signature"); return false; } } v_signed_at_signature := valueof( m_etsiTs103097Data_signed( m_signedData( v_hashId, v_tbs, m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is the hasheId8 of the EC certificate obtained from Enrolment request v_signature ) ) ); log("f_generate_inner_at_request_with_wrong_parameters: v_signed_at_signature= ", v_signed_at_signature); if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure var octetstring v_public_enc_key; var integer v_compressed_mode; var Oct12 v_nonce; var Oct16 v_authentication_vector; var Oct16 v_aes_sym_key; var Oct16 v_encrypted_sym_key; var HashedId8 v_recipientId; var octetstring v_public_compressed_ephemeral_key; var integer v_public_compressed_ephemeral_mode; var octetstring v_enc_signed_ec_signature; var EncryptedDataEncryptionKey v_encrypted_data_encryption_key; // Use EA certificate for the encryption if (p_enc_algo == e_nist_p256) { if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0; v_compressed_mode := 0; } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1; v_compressed_mode := 1; } else { log("f_generate_inner_at_request_with_wrong_parameters: Wrong NistP256 encryption variant"); return false; } v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce); if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, v_encrypted_sym_key, v_authentication_vector ))); } else if (p_enc_algo == e_brainpool_p256_r1) { if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0; v_compressed_mode := 0; } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) { v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1; v_compressed_mode := 1; } else { log("f_generate_inner_at_request_with_wrong_parameters: Wrong BrainpoolP256r1 encryption variant"); return false; } v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256r1WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce); if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesBrainpoolP256r1( m_evciesP256EncryptedKey( v_eccP256_curve_point, v_encrypted_sym_key, v_authentication_vector ))); } else if (p_enc_algo == e_sm2_p256) { // FIXME FSCOM } else { log("f_generate_inner_at_request_with_wrong_parameters: Wrong encryption variant"); return false; } log("f_generate_inner_at_request_with_wrong_parameters: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key); v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate log("f_generate_inner_at_request_with_wrong_parameters: v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) p_inner_at_request.ecSignature := valueof( m_ec_signature( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_certRecipInfo( m_pKRecipientInfo( v_recipientId, v_encrypted_data_encryption_key )) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( v_nonce, v_enc_signed_ec_signature ) ) ) ) ) ); } else { // Skip the encryption, alowed to be re-identified by the AA p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature)); } // Build the InnerAtRequest, EcSignature field is already set if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { if (p_compressed_key_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)); } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) { if (p_compressed_key_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point)); } else { var EccP384CurvePoint v_eccP384_curve_point; if (p_compressed_key_mode == 0) { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x)); } else { v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x)); } v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point)); } if (PX_INCLUDE_ENCRYPTION_KEYS) { if (p_compressed_enc_key_mode == 0) { v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x); } else { v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x); } if (p_enc_algo == e_nist_p256) { v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point)); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else { v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point)); } p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate m_publicKeys( v_public_verification_key, m_encryptionKey( // FIXME Encryption keys could be optional -, v_public_encryption_key ) ) ); } else { p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate m_publicKeys( v_public_verification_key ) ); } p_inner_at_request.hmacKey := v_hmac_key; log("f_generate_inner_at_request_with_wrong_parameters: p_inner_at_request= ", p_inner_at_request); return true; } // End of function f_generate_inner_at_request_with_wrong_parameters function f_verify_inner_at_request_signed_for_pop( in EtsiTs102941Data p_etsi_ts_102941_data, in template (omit) EtsiTs103097Certificate p_ec_certificate, out InnerAtRequest p_inner_at_request ) return boolean { var bitstring v_msg_bit; log(">>> f_verify_inner_at_request_signed_for_pop: p_etsi_ts_102941_data=", p_etsi_ts_102941_data); log(">>> f_verify_inner_at_request_signed_for_pop: p_ec_certificate=", p_ec_certificate); // 1. Extract content p_inner_at_request := p_etsi_ts_102941_data.content.authorizationRequest; // 2. Verify the InnerEcRequestSignedForPop signature // TODO log("<<< f_verify_inner_at_request_signed_for_pop: ", p_inner_at_request); return true; } // End of function f_verify_inner_at_request_signed_for_pop function f_generate_inner_at_response( in octetstring p_authorization_request_hash, in EtsiTs103097Certificate p_certificate, out InnerAtResponse p_authorization_response ) return boolean { // Local variables // Build the Proof of Possession InnerEcResponse p_authorization_response := valueof( m_innerAtResponse_ok( substr(p_authorization_request_hash, 0, 16), p_certificate ) ); return true; } // End of function f_generate_inner_at_response } // End of group inner_at_xxx group bfk { function f_generate_ee_ra_cert_request( out octetstring p_caterpillar_private_key, out octetstring p_caterpillar_public_key_compressed, out integer p_caterpillar_compressed_mode, out octetstring p_caterpillar_enc_private_key, out octetstring p_caterpillar_enc_public_key_compressed, out integer p_caterpillar_enc_compressed_mode, out EeRaCertRequest p_ee_ra_cert_request ) runs on ItsPkiHttp return boolean { var octetstring v_public_key_x; var octetstring v_public_key_y; var EccP256CurvePoint v_ecc_p256_curve_point; var EccP256CurvePoint v_ecc_enc_p256_curve_point; var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(36, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM })), valueof(m_appPermissions(37, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_DENM })) }; var PublicVerificationKey v_public_verification_key; var template (value) ToBeSignedCertificate v_tbs; log (">>> f_generate_ee_ra_cert_request"); log("f_generate_ee_ra_cert_request: PX_VE_ALG=", PX_VE_ALG); // Generate caterpillar signing keys if (PX_BFK_TEST_VECTORS) { p_caterpillar_private_key := 'D418760F0CB2DCB856BC3C7217AD3AA36DB6742AE1DB655A3D28DF88CBBF84E1'O; p_caterpillar_public_key_compressed := 'EE9CC7FBD9EDECEA41F7C8BD258E8D2E988E75BD069ADDCA1E5A38E534AC6818'O; p_caterpillar_compressed_mode := 1; } else { if (f_generate_key_pair(p_caterpillar_private_key, v_public_key_x, v_public_key_y, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode) == false) { log("f_generate_ee_ra_cert_request: Failed to generate caterpillar keys"); return false; } } log ("f_generate_ee_ra_cert_request: Caterpillar private key: ", p_caterpillar_private_key); log ("f_generate_ee_ra_cert_request: Caterpillar public compressed key: ", p_caterpillar_public_key_compressed); log ("f_generate_ee_ra_cert_request: Caterpillar public compressed mode: ", p_caterpillar_compressed_mode); if (p_caterpillar_compressed_mode == 0) { v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_caterpillar_public_key_compressed)); } else { v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_caterpillar_public_key_compressed)); } if (PX_EC_ALG_FOR_EC == e_nist_p256) { v_public_verification_key := valueof( m_publicVerificationKey_ecdsaNistP256( v_ecc_p256_curve_point )); } else if (PX_EC_ALG_FOR_EC == e_nist_p384) { // FIXME FSCOM // v_public_verification_key := valueof( // m_publicVerificationKey_ecdsaNistP384( // v_ecc_p384_curve_point // )); } else if (PX_EC_ALG_FOR_EC == e_brainpool_p256_r1) { v_public_verification_key := valueof( m_publicVerificationKey_ecdsaBrainpoolP256r1( v_ecc_p256_curve_point )); } else if (PX_EC_ALG_FOR_EC == e_brainpool_p384_r1) { // FIXME FSCOM // v_public_verification_key := valueof( // m_publicVerificationKey_ecdsaBrainpoolP384r1( // v_ecc_p384_curve_point // )); } else if (PX_EC_ALG_FOR_EC == e_sm2_p256) { // FIXME FSCOM } else { log("f_generate_ee_ra_cert_request: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx"); return false; } v_tbs := m_bfk_to_be_signed_certificate( { none_ := NULL }, v_appPermissions, m_verificationKeyIndicator_verificationKey( v_public_verification_key ), m_validityPeriod( f_getCurrentTime() / 1000, m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION - 1) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2), m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2) } ), PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL ); // Generate caterpillar encryption keys if (PX_BFK_TEST_VECTORS) { p_caterpillar_enc_private_key := '4840ed221502d9ab6786bf68fba9f210373bf2215a6709ea59ce8cfd8e09b24d'O; p_caterpillar_enc_public_key_compressed := '9a2375d5631ca55a522d03fca8daa95a7978620d6798502b4fe4a006de2f7c19'O; p_caterpillar_enc_compressed_mode := 0; } else { if (f_generate_key_pair_for_encryption(e_nist_p256, p_caterpillar_enc_private_key, v_public_key_x, v_public_key_y, p_caterpillar_enc_public_key_compressed, p_caterpillar_enc_compressed_mode) == false) { log("f_generate_ee_ra_cert_request: Failed to generate caterpillar keys"); return false; } } log ("f_generate_ee_ra_cert_request: Caterpillar encryption private key: ", p_caterpillar_enc_private_key); log ("f_generate_ee_ra_cert_request: Caterpillar encryption public compressed key: ", p_caterpillar_enc_public_key_compressed); log ("f_generate_ee_ra_cert_request: Caterpillar encryption public compressed mode: ", p_caterpillar_enc_compressed_mode); if (p_caterpillar_enc_compressed_mode == 0) { v_ecc_enc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_caterpillar_enc_public_key_compressed)); } else { v_ecc_enc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_caterpillar_enc_public_key_compressed)); } if (PICS_SECPKI_ORIGINAL_BFK_KEY) { var Oct16 v_kS; f_generate_bkf_signing_key_expension(v_kS); log ("f_generate_ee_ra_cert_request: v_kS: ", v_kS); var Oct16 v_kE; f_generate_bkf_enc_key_expension(v_kE); log ("f_generate_ee_ra_cert_request: v_kE: ", v_kE); // For Debug purposes, to be removed later // log ("f_generate_ee_ra_cert_request: v_signing_expansion_key: ", v_signing_expansion_key); // var octetstring v_expanded_caterpillar_private_key; // f_bfk_expend_private_key(v_signing_expansion_key, p_caterpillar_private_key, v_expanded_caterpillar_private_key); // log ("f_generate_ee_ra_cert_request: v_expanded_caterpillar_private_key: ", v_expanded_caterpillar_private_key); // var octetstring v_caterpillar_expended_public_key_compressed; // var integer v_caterpillar_expended_compressed_mode; // f_bfk_expend_public_key(v_signing_expansion_key, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode, v_caterpillar_expended_public_key_compressed, v_caterpillar_expended_compressed_mode); // log ("f_generate_ee_ra_cert_request: v_caterpillar_expended_public_key_compressed: ", v_caterpillar_expended_public_key_compressed); // log ("f_generate_ee_ra_cert_request: v_caterpillar_expended_compressed_mode: ", v_caterpillar_expended_compressed_mode); // //v_expanded_caterpillar_private_key[5] := 'FF'O; // var boolean v_verif := f_bfk_verify_expended_keys(v_expanded_caterpillar_private_key, v_caterpillar_expended_public_key_compressed, v_caterpillar_expended_compressed_mode); // stop; p_ee_ra_cert_request := valueof( m_ee_ra_cert_request( f_getCurrentTime() / 1000, explicit, v_tbs, m_additional_params_original( m_butterfly_params_original( m_butterfly_expansion_aes128( v_kS ), m_encryptionKey( -, m_publicEncryptionKey_eciesNistP256( v_ecc_enc_p256_curve_point )), m_butterfly_expansion_aes128( v_kE ))))); } else if (PICS_SECPKI_UNIFIED_BFK_KEY) { var octetstring v_kS; f_generate_bkf_signing_key_expension(v_kS); log ("f_generate_ee_ra_cert_request: v_kS: ", v_kS); p_ee_ra_cert_request := valueof( m_ee_ra_cert_request( f_getCurrentTime(), explicit, v_tbs, m_additional_params_unified( m_butterfly_expansion_aes128( v_kS )))); } else { log("f_generate_ee_ra_cert_request: Wrong configuration, at least one (PICS_SECPKI_ORIGINAL_BFK_KEY, PICS_SECPKI_UNIFIED_BFK_KEY) of shall be set to true"); return false; } log("f_generate_ee_ra_cert_request: p_ee_ra_cert_request: ", p_ee_ra_cert_request); return true; } // End of function f_generate_ee_ra_cert_request function f_generate_bfk_batch( in EeRaCertRequest p_ee_ra_cert_request, out BfkCertificates p_bfk_batch_certificates, out integer p_bfk_batch_counter ) return boolean { log(">>> f_generate_bfk_batch: p_ee_ra_cert_request: ", p_ee_ra_cert_request); p_bfk_batch_certificates := {}; p_bfk_batch_counter := 0; if (ischosen(p_ee_ra_cert_request.additionalParams.original)) { // Extract caterpillar public key var octetstring v_caterpillar_public_key_compressed; var integer v_caterpillar_compressed_mode; if (ischosen(p_ee_ra_cert_request.tbsCert.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { if (ischosen(p_ee_ra_cert_request.tbsCert.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { v_caterpillar_public_key_compressed := p_ee_ra_cert_request.tbsCert.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; v_caterpillar_compressed_mode := 0; } else if (ischosen(p_ee_ra_cert_request.tbsCert.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1)) { v_caterpillar_public_key_compressed := p_ee_ra_cert_request.tbsCert.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; v_caterpillar_compressed_mode := 1; } else { log("f_generate_bfk_batch: Non canonicalized tbsCert"); return false; } } // Extract encryprion expension key var octetstring v_caterpillar_enc_public_key_compressed; var integer v_caterpillar_enc_compressed_mode; if (ischosen(p_ee_ra_cert_request.additionalParams.original.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { v_caterpillar_enc_public_key_compressed := p_ee_ra_cert_request.additionalParams.original.encryptionKey.publicKey.eciesNistP256.compressed_y_0; v_caterpillar_enc_compressed_mode := 0; } else if (ischosen(p_ee_ra_cert_request.additionalParams.original.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) { v_caterpillar_enc_public_key_compressed := p_ee_ra_cert_request.additionalParams.original.encryptionKey.publicKey.eciesNistP256.compressed_y_1; v_caterpillar_enc_compressed_mode := 1; } else { log("f_generate_bfk_batch: Non canonicalized tbsCert"); return false; } { // Loop // Create an expension key for both signing and encrytion var octetstring v_signing_expension_key; f_generate_bkf_signing_key_expension(v_signing_expension_key); log("f_generate_bfk_batch: v_signing_expension_key: ", v_signing_expension_key); var octetstring v_enc_expension_key; f_generate_bkf_enc_key_expension(v_enc_expension_key); log("f_generate_bfk_batch: v_enc_expension_key: ", v_enc_expension_key); var octetstring v_caterpillar_expended_public_key_compressed; var integer v_caterpillar_expended_compressed_mode; f_bfk_expend_public_key( v_signing_expension_key, v_caterpillar_public_key_compressed, v_caterpillar_compressed_mode, v_caterpillar_expended_public_key_compressed, v_caterpillar_expended_compressed_mode ); log ("f_generate_bfk_batch: v_caterpillar_expended_public_key_compressed: ", v_caterpillar_expended_public_key_compressed); log ("f_generate_bfk_batch: v_caterpillar_expended_compressed_mode: ", v_caterpillar_expended_compressed_mode); var octetstring v_caterpillar_expended_enc_public_key_compressed; var integer v_caterpillar_expended_enc_compressed_mode; f_bfk_expend_public_key( v_enc_expension_key, v_caterpillar_enc_public_key_compressed, v_caterpillar_enc_compressed_mode, v_caterpillar_expended_enc_public_key_compressed, v_caterpillar_expended_enc_compressed_mode ); log ("f_generate_bfk_batch: v_caterpillar_enc_public_key_compressed: ", v_caterpillar_enc_public_key_compressed); log ("f_generate_bfk_batch: v_caterpillar_expended_enc_compressed_mode: ", v_caterpillar_expended_enc_compressed_mode); // The new verirfication key are the new coccon key - ETSI TS 102 941 V2.1.1 Clause 6.2.3.5.4 Butterfly certificate request /*var EcdsaNistP256 v_signing_key; if (v_caterpillar_expended_compressed_mode == 0) { v_signing_key.compressed_y_0 := v_caterpillar_expended_public_key_compressed; } else { v_signing_key.compressed_y_1 := v_caterpillar_expended_public_key_compressed; } // The encryption key are the new enc derived key var EciesNistP256 v_enc_key; if (v_caterpillar_expended_enc_compressed_mode == 0) { v_enc_key.compressed_y_0 := v_caterpillar_enc_public_key_compressed; } else { v_enc_key.compressed_y_1 := v_caterpillar_enc_public_key_compressed; } // Generate the certificate based on p_ee_ra_cert_request.content.butterflyAuthorizationRequest.tbsCert and enxpended keys // TODO Load AA certificate var EtsiTs103097Certificate v_cert := m_etsiTs103097Certificate( in template (value) IssuerIdentifier p_issuer, m_toBeSignedCertificate_at( p_ee_ra_cert_request.tbsCert.appPermissions, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( v_signing_key )), p_ee_ra_cert_request.tbsCert.region, p_ee_ra_cert_request.tbsCert.assuranceLevel m_encryptionKey( -, m_publicEncryptionKey_eciesNistP256( v_enc_key ))), -, p_ee_ra_cert_request.type_ ); log("f_generate_bfk_batch: AT toBeSigned:", v_cert.toBeSigned);*/ // Signed certificate with AA certicate // Encode certfificate // Compute whole-hash SHA256 // Extract HashedId8 p_bfk_batch_certificates := {}; p_bfk_batch_counter := p_bfk_batch_counter + 1; } // End of 'for' statement } else { log("f_generate_bfk_batch: Not implemented yet"); return false; } log("<<< f_generate_bfk_batch: p_bfk_batch_certificates: ", p_bfk_batch_certificates); log("<<< f_generate_bfk_batch: p_bfk_batch_counter: ", p_bfk_batch_counter); return true; } // End of function f_generate_bfk_batch function f_generate_ra_ee_cert_info( in EeRaCertRequest p_ee_ra_cert_request, in HashedId8 p_requestHash, out RaEeCertInfo p_ra_ee_cert_info ) runs on ItsPkiHttp return boolean { log(">>> f_generate_ra_ee_cert_info: p_ee_ra_cert_request: ", p_ee_ra_cert_request); var UInt32 v_current_time := f_getCurrentTimeUtc() / 1000; // In seconds var UInt32 v_dl_time := v_current_time + 60; // Current time + one minute // Build Batch of certificates f_generate_bfk_batch(p_ee_ra_cert_request, vc_bfk_batch_certificates, vc_bfk_batch_counter); // Build the response p_ra_ee_cert_info := valueof( m_ra_ee_cert_info( v_current_time, vc_bfk_batch_counter, p_requestHash, v_dl_time )); log("<<< f_generate_ra_ee_cert_info: p_ra_ee_cert_info: ", p_ra_ee_cert_info); return true; } // End of function f_generate_ra_ee_cert_info function f_generate_ee_ra_download_request( in charstring p_filename, out EeRaDownloadRequest p_ee_ra_download_request ) runs on ItsPkiHttp return boolean { var UInt32 v_current_time := f_getCurrentTime() / 1000; // In seconds p_ee_ra_download_request := valueof(m_ee_ra_download_request(v_current_time, p_filename)); log("f_generate_ee_ra_download_request: p_ee_ra_download_request: ", p_ee_ra_download_request); return true } // End of function f_generate_ee_ra_download_request } // End of group bfk group dc { function f_build_dc( in charstring p_rca_certificate_id, out EtsiTs103097Certificate p_rca_certificate ) { log(">>> f_build_dc"); // Load certificate f_readCertificate(p_rca_certificate_id, p_rca_certificate); } function f_verify_rca_ctl_response_message( in EtsiTs103097Data p_etsi_ts_103097_signed_data, in boolean p_check_security := true, out ToBeSignedRcaCtl p_to_be_signed_rca_ctl ) return boolean { var bitstring v_etsi_ts_102941_data_msg; var bitstring v_tbs; var Certificate v_certificate; var charstring v_certificate_id; var octetstring v_issuer; var EtsiTs102941Data v_etsi_ts_102941_data; log(">>> f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data); // 1. Verify signature log("f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData); v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData); if (ispresent(p_etsi_ts_103097_signed_data.content.signedData.signer.digest)) { if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { log("f_verify_rca_ctl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest); if (p_check_security == true) { return false; } } log("f_verify_rca_ctl_response_message (1): v_certificate: ", v_certificate); f_getCertificateHash(v_certificate_id, v_issuer); } else { v_certificate := p_etsi_ts_103097_signed_data.content.signedData.signer.certificate[0]; log("f_verify_rca_ctl_response_message (2): v_certificate: ", v_certificate); if (ispresent(v_certificate.issuer.sha256AndDigest)) { v_issuer := v_certificate.issuer.sha256AndDigest; } if (ispresent(v_certificate.issuer.sha384AndDigest)) { v_issuer := v_certificate.issuer.sha384AndDigest; } else { // self_ if (v_certificate.issuer.self_ == sha256) { v_issuer := int2oct(0, 32); } else { v_issuer := int2oct(0, 48); } } } if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { log("f_verify_rca_ctl_response_message: Failed to verify signature"); if (p_check_security == true) { return false; } } v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) { log("f_verify_rca_ctl_response_message: Failed to decode EtsiTs102941Data"); return false; } else { log("f_verify_rca_ctl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data); log("f_verify_pki_response_message: RcaCertificateTrustListMessage matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl)); if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl) == false) { log("f_verify_rca_ctl_response_message: Failed to decode certificateTrustListRca"); return false; } else { var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000; p_to_be_signed_rca_ctl := v_etsi_ts_102941_data.content.certificateTrustListRca; log("f_verify_rca_ctl_response_message: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl); if (p_to_be_signed_rca_ctl.nextUpdate <= v_time) { log("f_verify_rca_ctl_response_message: Invalid nextUpdate value: compared values=", p_to_be_signed_rca_ctl.nextUpdate, "/", v_time); return false; } // TODO Verify RCA certificate & signature } } return true; } function f_verify_rca_crl_response_message( in EtsiTs103097Data p_etsi_ts_103097_signed_data, in boolean p_check_security := true, out ToBeSignedCrl p_to_be_signed_crl ) return boolean { var bitstring v_etsi_ts_102941_data_msg; var bitstring v_tbs; var Certificate v_certificate; var charstring v_certificate_id; var octetstring v_issuer; var EtsiTs102941Data v_etsi_ts_102941_data; log(">>> f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data); // 1. Verify signature log("f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData); v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData); if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { log("f_verify_rca_crl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest); if (p_check_security == true) { return false; } } f_getCertificateHash(v_certificate_id, v_issuer); if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { log("f_verify_rca_crl_response_message: Failed to verify signature"); if (p_check_security == true) { return false; } } v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) { log("f_verify_rca_crl_response_message: Failed to decode EtsiTs102941Data"); return false; } else { log("f_verify_rca_crl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data); log("f_verify_pki_response_message: CertificateRevocationList matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl)); if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl) == false) { log("f_verify_rca_crl_response_message: Failed to decode certificateRevocationList"); return false; } else { var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000; p_to_be_signed_crl := v_etsi_ts_102941_data.content.certificateRevocationList; log("f_verify_rca_crl_response_message: p_to_be_signed_crl= ", p_to_be_signed_crl); if (p_to_be_signed_crl.thisUpdate >= v_time) { log("f_verify_rca_crl_response_message: Invalid thisUpdate value"); return false; } if (p_to_be_signed_crl.nextUpdate <= v_time) { log("f_verify_rca_crl_response_message: Invalid nextUpdate value"); return false; } // TODO Verify RCA certificate & signature } } return true; } /** * @desc this function is used to retrieve the root certificate from SubCA entity * @param p_certificate The root certificate * @return 0 on success, -1 otherwise */ function f_get_root_ca_certificate( in charstring p_iut_certificate := "CERT_IUT_A_CA", in boolean p_explicit_type := false, out Certificate p_certificate ) runs on ItsPkiHttp return integer { var Headers v_headers; var HttpMessage v_response; var octetstring v_os; var bitstring v_msg_bit; log(">>> f_get_root_ca_certificate"); // Get root certificate f_cfHttpUp_ca(); f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "ca_request", v_headers); // Test Body f_http_send( v_headers, m_http_request( m_http_request_get( PICS_HTTP_GET_URI_DC, v_headers ))); tc_ac.start; alt { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive( mw_http_response( mw_http_response_ok( mw_http_message_body_binary( mw_binary_body_ieee1609dot2_certificate )))) -> value v_response { tc_ac.stop; } [PICS_MULTIPLE_END_POINT] httpCaPort.receive( mw_http_response( mw_http_response_ok( mw_http_message_body_binary( mw_binary_body_ieee1609dot2_certificate )))) -> value v_response { tc_ac.stop; } [] tc_ac.timeout { } } // End of 'alt' statement f_cfHttpDown_ca(); if (not(isvalue(v_response))) { log("f_get_root_ca_certificate: fail to get certificate"); return -1; } log("v_response.response.body.binary_body.ieee1609dot2_certificate: ", v_response.response.body.binary_body.ieee1609dot2_certificate); p_certificate := v_response.response.body.binary_body.ieee1609dot2_certificate; log("<<< f_get_root_ca_certificate: ", p_certificate); return 0; } function f_verify_rca_certificate( in charstring p_authorized_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_RCA", in Certificate p_certificate, in boolean p_check_implicit := false, in boolean p_check_reconstruction_value := false, in boolean p_check_no_signature := false, in boolean p_check_region_restriction := false, in boolean p_check_signature_content := false, in boolean p_check_app_permissions := false, in boolean p_check_app_ssps := false, in boolean p_check_app_validity_period := false ) return boolean { var CertificateType v_type_ := explicit; var template Signature v_signature_ := ?; var template IssuerIdentifier v_issuer := ?; var template PublicVerificationKey v_public_verification_key := ?; log(">>> f_verify_rca_certificate: p_authorized_certificate= ", p_authorized_certificate); log(">>> f_verify_rca_certificate: p_certificate= ", p_certificate); if (p_check_implicit == true) { v_type_ := implicit; } if (p_check_no_signature == true) { v_signature_ := omit; } if (match(p_certificate, mw_etsiTs103097Certificate(-, -, v_signature_, v_type_)) == false) { log("f_verify_rca_certificate: version/explicit mismatch"); return false; } if (p_check_reconstruction_value == false) { if (match(p_certificate, mw_etsiTs103097Certificate( -, mw_toBeSignedCertificate_ca( (mw_certificateId_none, mw_certificateId_name), -, -, mw_verificationKeyIndicator_verificationKey ), v_signature_ )) == false) { log("f_verify_rca_certificate: verificationKey mismatch"); return false; } if (p_check_signature_content) { var template PublicVerificationKey v_publicVerificationKey; if (PICS_SEC_SHA256) { v_signature_ := mw_signature_ecdsaNistP256; v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest); v_public_verification_key := mw_publicVerificationKey_ecdsaNistP256; } else if (PICS_SEC_BRAINPOOL_P256R1) { v_signature_ := mw_signature_ecdsaBrainpoolP256r1; v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest); v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP256r1; } else if (PICS_SEC_BRAINPOOL_P384R1) { v_signature_ := mw_signature_ecdsaBrainpoolP384r1; v_issuer := (mw_issuerIdentifier_self(sha384), mw_issuerIdentifier_sha384AndDigest); v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP384r1; } if (match(p_certificate, mw_etsiTs103097Certificate( v_issuer, mw_toBeSignedCertificate_ca( (mw_certificateId_none, mw_certificateId_name), -, -, mw_verificationKeyIndicator_verificationKey(v_public_verification_key), -, -, -, -, -//mw_encryptionKey ), v_signature_ )) == false) { log("f_verify_rca_certificate: signature mismatch"); return false; } // Verify Signature if (ischosen(p_certificate.issuer.self_)) { v_publicVerificationKey := p_certificate.toBeSigned.verifyKeyIndicator.verificationKey; } else { var HashedId8 v_digest; var Certificate v_authorized_certificate; var charstring v_cert; if (ischosen(p_certificate.issuer.sha256AndDigest)) { v_digest := p_certificate.issuer.sha256AndDigest; } else if (ischosen(p_certificate.issuer.sha384AndDigest)) { v_digest := p_certificate.issuer.sha384AndDigest; } else { log("f_verify_rca_certificate: Invalid certificate issuer ", p_certificate.issuer); return false; } if (f_getCertificateFromDigest(v_digest, v_authorized_certificate, v_cert) == false) { log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); return false; } v_publicVerificationKey := v_authorized_certificate.toBeSigned.verifyKeyIndicator.verificationKey } log("f_verify_rca_certificate: v_publicVerificationKey= ", v_publicVerificationKey); if (f_verifyCertificateSignatureWithPublicKey(p_certificate, v_publicVerificationKey) == false) { log("f_verify_rca_certificate: signature not verified"); return false; } } } else { if (match(p_certificate, mw_etsiTs103097Certificate( -, mw_toBeSignedCertificate_ca( (mw_certificateId_none, mw_certificateId_name), -, -, mw_verificationKeyIndicator_reconstructionValue ), v_signature_ )) == false) { log("f_verify_rca_certificate: verificationKey mismatch"); return false; } // TODO Verify Signature } if (p_check_region_restriction == true) { var Certificate v_authorized_certificate; var template GeographicRegion v_geographic_region := ?; if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); return false; } log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); if (PICS_SEC_CIRCULAR_REGION == true) { v_geographic_region := mw_geographicRegion_circle; } else if (PICS_SEC_RECTANGULAR_REGION == true) { v_geographic_region := mw_geographicRegion_rectangular; } else if (PICS_SEC_POLYGONAL_REGION == true) { v_geographic_region := mw_geographicRegion_polygonal; } else if (PICS_SEC_IDENTIFIED_REGION == true) { v_geographic_region := mw_geographicRegion_identified( { (mw_identifiedRegion_country_only, mw_identifiedRegion_country_and_region) } ); } if (match(p_certificate, mw_etsiTs103097Certificate( -, mw_toBeSignedCertificate_ca( -, -, -, -, -, -, v_geographic_region ) )) == false) { log("f_verify_rca_certificate: Geographical region mismatch"); return false; } // Check interception of area if (f_checkRegionValidityRestiction(v_authorized_certificate, p_certificate) == false) { log("f_verify_rca_certificate: Geographical region intersection mismatch"); return false; } } // Check appPermissions if (p_check_app_permissions == true) { var integer v_idx, v_jdx; var charstring v_psid := ""; // 'psid' currently processed var charstring v_psidsFound := ";"; // Used to build the list of the 'psid' already processed var template charstring m_found_pattern; // Used in regex to verify that 'psid' was not found before var Certificate v_authorized_certificate; if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); return false; } log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); if (match(v_authorized_certificate.toBeSigned.certIssuePermissions, { mw_psidGroupPermissions }) == false) { log("f_verify_rca_certificate: eeType mismatch"); return false; } for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) { log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]); if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions) == false) { log("f_verify_rca_certificate: PsidSsp mismatch"); return false; } // Check uniqueness of PSIDs v_psid := int2str(p_certificate.toBeSigned.appPermissions[v_idx].psid); m_found_pattern := pattern "*({v_psid})*"; if (regexp(v_psidsFound, m_found_pattern, 0) == v_psid) { log("f_verify_rca_certificate: Psid uniqueness is not verified"); return false; // v_psid exist at least 2 times, uniqueness is not verified } // v_psid non found, add it into the built list v_psidsFound := v_psidsFound & v_psid & ";"; // Check that 'psid' is in the certIssuePermissions component in the issuing certificate if (match(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions, mw_subjectPermissions_explicit) == false) { for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) { if (int2str(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid) == v_psid) { break; } } // End of 'for'statement if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) { log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate"); return false; } } } // End of 'for'statement } if (p_check_app_ssps == true) { var integer v_idx, v_jdx; var Certificate v_authorized_certificate; if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); return false; } log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) { log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]); if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions(-, ?)) == false) { log("f_verify_rca_certificate: appPermissions mismatch"); return false; } // Check that 'ssp' is in the certIssuePermissions component in the issuing certificate for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) { log("f_verify_rca_certificate: compare psid ", v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid, " - ", p_certificate.toBeSigned.appPermissions[v_idx].psid); if (v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid == p_certificate.toBeSigned.appPermissions[v_idx].psid) { break; } } // End of 'for'statement if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) { log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate"); return false; } else { var BitmapSsp v_ssp_ca := substr(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue, 1, -1 + lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue)); log("f_verify_rca_certificate: v_ssp_ca= ", v_ssp_ca, " - ssp= ", p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp); if (v_ssp_ca != p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp) { log("f_verify_rca_certificate: SSPs mismatch: CA"); return false; } } } // End of 'for'statement } if (p_check_app_validity_period == true) { var integer v_idx, v_jdx; var Certificate v_authorized_certificate; var UInt32 v_duration, v_duration_ca; if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); return false; } log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); // Check start date (indicating X_START_VALIDITY ( X_START_VALIDITY >= X_START_VALIDITY_CA )) if (p_certificate.toBeSigned.validityPeriod.start_ < v_authorized_certificate.toBeSigned.validityPeriod.start_) { log("f_verify_rca_certificate: validityPeriod.start_ mismatch"); return false; } // Check duration (value <= X_START_VALIDITY_CA + X_DURATION_CA - X_START_VALIDITY) v_duration := duration_to_uint32(p_certificate.toBeSigned.validityPeriod.duration); v_duration_ca := duration_to_uint32(v_authorized_certificate.toBeSigned.validityPeriod.duration); if (v_duration > (v_authorized_certificate.toBeSigned.validityPeriod.start_ + v_duration_ca - p_certificate.toBeSigned.validityPeriod.start_)) { log("f_verify_rca_certificate: validityPeriod.duration mismatch"); return false; } } return true; } function duration_to_uint32( in Duration p_duration ) return UInt32 { if (ischosen(p_duration.microseconds)) { return p_duration.microseconds * 1000000; } else if (ischosen(p_duration.milliseconds)) { return p_duration.milliseconds * 1000; } else if (ischosen(p_duration.seconds)) { return p_duration.seconds; } else if (ischosen(p_duration.minutes)) { return p_duration.minutes * 60; } else if (ischosen(p_duration.hours)) { return p_duration.hours * 3600; } else if (ischosen(p_duration.sixtyHours)) { return p_duration.sixtyHours * 60 * 3600; } else if (ischosen(p_duration.sixtyHours)) { return p_duration.sixtyHours * 60 * 3600; } // No choice! return p_duration.years * 31536000; // One calendar common year has 365 days } } // End of group dc group ctl { function f_build_ctl( in charstring p_ea_certificate_id, in charstring p_aa_certificate_id, in charstring p_rca_certificate_id, out ToBeSignedRcaCtl p_to_be_signed_rca_ctl ) { // Local variables var EtsiTs103097Certificate v_ea_certificate; var EtsiTs103097Certificate v_aa_certificate; var Oct32 v_rca_hash; var CtlCommands v_ctl_commands; var Time32 v_time; log(">>> f_build_ctl"); // Load certificates f_readCertificate(p_ea_certificate_id, v_ea_certificate); f_readCertificate(p_aa_certificate_id, v_aa_certificate); f_getCertificateHash256(p_rca_certificate_id, v_rca_hash); v_ctl_commands := { { add := { ea := valueof(m_ea_entry(v_ea_certificate, PICS_EA_ENDPOINT)) } }, { add := { aa := valueof(m_aa_entry(v_aa_certificate, PICS_AA_ENDPOINT)) } }, { add := { dc := valueof(m_dc_entry(PICS_DC_ENDPOINT, { f_hashedId8FromSha256(v_rca_hash) })) } } }; log("f_build_ctl: v_ctl_commands= ", v_ctl_commands); // Build the main data structure v_time := f_getCurrentTime() / 1000;/*in seconds*/ p_to_be_signed_rca_ctl := valueof(m_to_be_signed_rca_full_ctl(v_time + 30 * 86400/*30 days in seconds*/, PX_CTL_SEQUENCE_NUMBER, v_ctl_commands)); log("<<< f_build_ctl: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl); } // End of function f_build_ctl function f_sign_dc_ctl( in charstring p_signer_certificate_id, in ToBeSignedRcaCtl p_to_be_signed_rca_ctl, out Ieee1609Dot2Data p_ieee_1609Dot2_signed_data ) { // Local variables var EtsiTs103097Certificate v_certificate; var EtsiTs102941Data v_etsi_ts_102941_data; var octetstring v_pki_message; var ToBeSignedData v_tbs; var octetstring v_private_key; var octetstring v_issuer; var bitstring v_tbs_encoded; var octetstring v_sig; var Signature v_signature; log(">>> f_sign_dc_ctl"); f_readSigningKey(p_signer_certificate_id, v_private_key); f_getCertificateHash(p_signer_certificate_id, v_issuer); f_readCertificate(p_signer_certificate_id, v_certificate); // Encode the main data structure v_etsi_ts_102941_data := valueof(m_etsiTs102941Data_to_be_signed_rca_ctl(p_to_be_signed_rca_ctl)); v_pki_message := bit2oct(encvalue(v_etsi_ts_102941_data)); // Signed the encoded PKI message v_tbs := valueof( m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(v_pki_message) ), m_headerInfo_inner_pki_ctl_response(-, (f_getCurrentTime() * 1000)/*us*/) ) ); v_tbs_encoded := encvalue(v_tbs); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs_encoded), v_issuer, v_private_key); if (PX_VE_ALG == e_nist_p256) { v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) )); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) )); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_nist_p384) { v_signature := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) )); } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) )); } log("f_sign_dc_ctl: v_signature= ", v_signature); p_ieee_1609Dot2_signed_data := valueof( m_etsiTs103097Data_signed( m_signedData( sha384, v_tbs, m_signerIdentifier_certificates({v_certificate}), v_signature ) ) ); log("<<< f_sign_dc_ctl: p_ieee_1609Dot2_signed_data= ", p_ieee_1609Dot2_signed_data); } // End of function f_sign_dc_ctl function f_verify_full_ctl( in ToBeSignedRcaCtl p_to_be_signed_rca_ctl ) return boolean { log(">>> f_verify_full_ctl: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl); // 1. Check mandatory fields log("f_verify_full_ctl matching= ", match(p_to_be_signed_rca_ctl, mw_to_be_signed_rca_full_ctl)); if (match(p_to_be_signed_rca_ctl, mw_to_be_signed_rca_full_ctl) == false) { return false; } log("f_verify_full_ctl: ctlCommands length: ", lengthof(p_to_be_signed_rca_ctl.ctlCommands)); for (var integer v_i := 0; v_i < lengthof(p_to_be_signed_rca_ctl.ctlCommands); v_i := v_i + 1) { var CtlCommand v_ctl_command := p_to_be_signed_rca_ctl.ctlCommands[v_i]; if (ischosen(v_ctl_command.delete)) { log("f_verify_full_ctl: ctlCommands shall not contains 'delete' variant"); return false; } else { if (f_verify_ctl_entry(v_ctl_command.add) == false) { log("f_verify_full_ctl: ctlCommands contains invalid entries"); return false; } } } // End of 'for' statements return true; } // End of function f_verify_full_ctl function f_verify_ctl_entry( in CtlEntry p_ctl_entry ) return boolean { log(">>> f_verify_ctl_entry: p_ctl_entry=", p_ctl_entry); if (ischosen(p_ctl_entry.rca)) { if (match(p_ctl_entry.rca, mw_root_ca_entry(mw_etsiTs103097Certificate)) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else if (ischosen(p_ctl_entry.ea)) { if (match(p_ctl_entry.ea, mw_ea_entry(mw_etsiTs103097Certificate)) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else if (ischosen(p_ctl_entry.aa)) { if (match(p_ctl_entry.aa, mw_aa_entry(mw_etsiTs103097Certificate)) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else if (ischosen(p_ctl_entry.dc)) { if (match(p_ctl_entry.dc, mw_dc_entry) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else { return false; } return true; } // End of function f_verify_ctl_entry } // End of group ctl group crl { function f_build_crl( in template (omit) charstring p_ea_certificate_id := omit, in template (omit) charstring p_aa_certificate_id := omit, out ToBeSignedCrl p_to_be_signed_crl ) { // Local variables var HashedId8 v_hashed_id8; var CrlEntries v_crl_entries := {}; // Empty list var integer v_counter := 0; var Time32 v_time; log(">>> f_build_crl"); if (ispresent(p_ea_certificate_id)) { f_getCertificateHash(valueof(p_ea_certificate_id), v_hashed_id8); v_crl_entries[v_counter] := v_hashed_id8; v_counter := v_counter + 1; } if (ispresent(p_aa_certificate_id)) { f_getCertificateHash(valueof(p_aa_certificate_id), v_hashed_id8); v_crl_entries[v_counter] := v_hashed_id8; v_counter := v_counter + 1; } log("f_build_crl: v_crl_entries= ", v_crl_entries); // Build the main data structure v_time := f_getCurrentTime() / 1000; /*in seconds*/ p_to_be_signed_crl := valueof(m_to_be_signed_crl(v_time, v_time + 30 * 86400/*30 days in seconds*/, v_crl_entries)); log("<<< f_build_crl: p_to_be_signed_crl= ", p_to_be_signed_crl); } // End of function f_build_crl function f_sign_dc_crl( in charstring p_signer_certificate_id, in ToBeSignedCrl p_to_be_signed_crl, out Ieee1609Dot2Data p_ieee_1609Dot2_signed_data ) { // Local variables var EtsiTs103097Certificate v_certificate; var EtsiTs102941Data v_etsi_ts_102941_data; var octetstring v_pki_message; var ToBeSignedData v_tbs; var octetstring v_private_key; var octetstring v_issuer; var bitstring v_tbs_encoded; var octetstring v_sig; var Signature v_signature; log(">>> f_sign_dc_crl"); f_readSigningKey(p_signer_certificate_id, v_private_key); f_getCertificateHash(p_signer_certificate_id, v_issuer); f_readCertificate(p_signer_certificate_id, v_certificate); // Encode the main data structure v_etsi_ts_102941_data := valueof(m_etsiTs102941Data_to_be_signed_crl(p_to_be_signed_crl)); v_pki_message := bit2oct(encvalue(v_etsi_ts_102941_data)); // Signed the encoded PKI message v_tbs := valueof( m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(v_pki_message) ), m_headerInfo_inner_pki_crl_response(-, (f_getCurrentTime() * 1000)/*us*/) ) ); v_tbs_encoded := encvalue(v_tbs); // Sign the certificate v_sig := f_signWithEcdsa(bit2oct(v_tbs_encoded), v_issuer, v_private_key); if (PX_VE_ALG == e_nist_p256) { v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) )); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) )); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_nist_p384) { v_signature := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) )); } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_sig, 0, 48) ), substr(v_sig, 48, 48) ) )); } log("f_sign_dc_crl: v_signature= ", v_signature); p_ieee_1609Dot2_signed_data := valueof( m_etsiTs103097Data_signed( m_signedData( sha384, v_tbs, m_signerIdentifier_certificates({v_certificate}), v_signature ) ) ); log("<<< f_sign_dc_crl: p_ieee_1609Dot2_signed_data= ", p_ieee_1609Dot2_signed_data); } // End of function f_sign_dc_crl function f_verify_full_crl( in ToBeSignedCrl p_to_be_signed_crl ) return boolean { log(">>> f_verify_full_crl: p_to_be_signed_crl= ", p_to_be_signed_crl); // 1. Check mandatory fields log("f_verify_full_crl matching= ", match(p_to_be_signed_crl, mw_to_be_signed_crl)); if (match(p_to_be_signed_crl, mw_to_be_signed_crl) == false) { return false; } log("f_verify_full_crl: entries length: ", lengthof(p_to_be_signed_crl.entries)); for (var integer v_i := 0; v_i < lengthof(p_to_be_signed_crl.entries); v_i := v_i + 1) { var CrlEntry v_crl_entry := p_to_be_signed_crl.entries[v_i]; log("f_verify_full_crl: crlEntry: v_crl_entry"); } // End of 'for' statements return true; } // End of function f_verify_full_crl } // End of group crl group tlm { function f_build_tlm( in charstring p_tlm_certificate_id, in charstring p_rca_certificate_id, out ToBeSignedTlmCtl p_to_be_signed_tlm_crl ) { // Local variables var EtsiTs103097Certificate v_tlm_certificate; var EtsiTs103097Certificate v_rca_certificate; var CtlCommands v_ctl_commands; // Empty list var Oct32 v_rca_hash; var Time32 v_time; log(">>> f_build_tlm"); // Load certificates f_readCertificate(p_tlm_certificate_id, v_tlm_certificate); f_readCertificate(p_rca_certificate_id, v_rca_certificate); f_getCertificateHash256(p_rca_certificate_id, v_rca_hash); // Create ctlCommnand list v_ctl_commands := { { add := { tlm := valueof(m_tlm_entry(v_tlm_certificate, PICS_TLM_ENDPOINT)) } }, { add := { rca := valueof(m_root_ca_entry(v_rca_certificate)) } }, { add := { dc := valueof(m_dc_entry(PICS_DC_ENDPOINT, { f_hashedId8FromSha256(v_rca_hash) })) } } }; log("f_build_tlm: v_ctl_commands= ", v_ctl_commands); // Build the main data structure v_time := f_getCurrentTimeUtc() / 1000/*in s*/; //log("f_build_ctl: v_time= ", v_time); //log("f_build_ctl: v_time + 86400= ", v_time + 86400); p_to_be_signed_tlm_crl := valueof(mw_to_be_signed_tlm_full_ctl(v_time + 86400/*1days*/, 7, v_ctl_commands)); log("<<< f_build_tlm: p_to_be_signed_tlm_crl= ", p_to_be_signed_tlm_crl); } // End of function f_buif_build_tlmld_Tlm function f_verify_full_ectl( in ToBeSignedRcaCtl p_to_be_signed_tlm_ectl ) return boolean { log(">>> f_verify_full_ectl: p_to_be_signed_tlm_ectl= ", p_to_be_signed_tlm_ectl); // 1. Check mandatory fields log("f_verify_full_ectl matching= ", match(p_to_be_signed_tlm_ectl, mw_to_be_signed_rca_full_ctl)); if (match(p_to_be_signed_tlm_ectl, mw_to_be_signed_rca_full_ctl) == false) { return false; } log("f_verify_full_ectl: ctlCommands length: ", lengthof(p_to_be_signed_tlm_ectl.ctlCommands)); for (var integer v_i := 0; v_i < lengthof(p_to_be_signed_tlm_ectl.ctlCommands); v_i := v_i + 1) { var CtlCommand v_ectl_command := p_to_be_signed_tlm_ectl.ctlCommands[v_i]; if (ischosen(v_ectl_command.delete)) { log("f_verify_full_ectl: ctlCommands shall not contains 'delete' variant"); return false; } else { if (f_verify_ectl_entry(v_ectl_command.add) == false) { log("f_verify_full_ectl: ctlCommands contains invalid entries"); return false; } } } // End of 'for' statements return true; } function f_verify_ectl_entry( in CtlEntry p_ctl_entry ) return boolean { log(">>> f_verify_ectl_entry: p_ctl_entry=", p_ctl_entry); if (ischosen(p_ctl_entry.tlm)) { if (match(p_ctl_entry.tlm, mw_tlm_entry(mw_etsiTs103097Certificate)) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else if (ischosen(p_ctl_entry.dc)) { if (match(p_ctl_entry.dc, mw_dc_entry) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else if (ischosen(p_ctl_entry.rca)) { if (match(p_ctl_entry.rca, mw_root_ca_entry(mw_etsiTs103097Certificate)) == false) { return false; } else { // TODO Verify RCA certificate & signature } } else { return false; } return true; } function f_verify_tlm_ectl_response_message( in EtsiTs103097Data p_etsi_ts_103097_signed_data, in boolean p_check_security := true, out ToBeSignedTlmCtl p_to_be_signed_tlm_ectl ) return boolean { var bitstring v_etsi_ts_102941_data_msg; var bitstring v_tbs; var Certificate v_certificate; var boolean v_result; var EtsiTs102941Data v_etsi_ts_102941_data; log(">>> f_verify_tlm_ectl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data); // 1. Verify signature log("f_verify_tlm_ectl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData); v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData); if (ischosen(p_etsi_ts_103097_signed_data.content.signedData.signer.certificate)) { v_certificate := p_etsi_ts_103097_signed_data.content.signedData.signer.certificate[0]; } else { var charstring v_certificate_id; if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { log("f_verify_tlm_ectl_response_message: Failed to retrieve certificate from digest ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest); if (p_check_security == true) { return false; } } } if (ischosen(p_etsi_ts_103097_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } else { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } if (v_result == false) { log("f_verify_tlm_ectl_response_message: Failed to verify signature"); if (p_check_security == true) { return false; } } v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) { log("f_verify_tlm_ectl_response_message: Failed to decode EtsiTs102941Data"); return false; } else { log("f_verify_tlm_ectl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data); log("f_verify_pki_response_message: TlmCertificateTrustListMessage matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_tlm_ctl)); if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_tlm_ctl) == false) { log("f_verify_tlm_ectl_response_message: Failed to decode certificateTrustListTlm"); return false; } else { var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000; p_to_be_signed_tlm_ectl := v_etsi_ts_102941_data.content.certificateTrustListTlm; log("f_verify_tlm_ectl_response_message: p_to_be_signed_tlm_ectl= ", p_to_be_signed_tlm_ectl); if (p_to_be_signed_tlm_ectl.nextUpdate <= v_time) { log("f_verify_tlm_ectl_response_message: Invalid nextUpdate value: compared values=", p_to_be_signed_tlm_ectl.nextUpdate, "/", v_time); return false; } // TODO Verify RCA certificate & signature } } return true; } function f_verify_broadcasted_delta_ctl( in GeoNetworkingPdu p_geonetworking_pdu, in boolean p_check_security := true ) return boolean { var EtsiTs103097Data v_secured_msg; var bitstring v_etsi_ts_102941_data_msg; var bitstring v_tbs; var Certificate v_certificate; var boolean v_result; var EtsiTs102941Data v_etsi_ts_102941_data; log(">>> f_verify_broadcasted_delta_ctl: p_geonetworking_pdu= ", p_geonetworking_pdu); if (not(ispresent(p_geonetworking_pdu.gnPacket.securedMsg))) { return false; } v_secured_msg := p_geonetworking_pdu.gnPacket.securedMsg; // 1. Verify signature log("f_verify_broadcasted_delta_ctl: v_secured_msg= ", v_secured_msg); v_tbs := encvalue(v_secured_msg.content.signedData.tbsData); if (ischosen(v_secured_msg.content.signedData.signer.certificate)) { v_certificate := v_secured_msg.content.signedData.signer.certificate[0]; } else { var charstring v_certificate_id; if (f_getCertificateFromDigest(v_secured_msg.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { log("f_verify_broadcasted_delta_ctl: Failed to retrieve certificate from digest ", v_secured_msg.content.signedData.signer.digest); if (p_check_security == true) { return false; } } } if (ischosen(v_secured_msg.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } else { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } if (v_result == false) { log("f_verify_broadcasted_delta_ctl: Failed to verify signature"); if (p_check_security == true) { return false; } } v_etsi_ts_102941_data_msg := oct2bit(v_secured_msg.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) { log("f_verify_broadcasted_delta_ctl: Failed to decode EtsiTs102941Data"); return false; } else { log("f_verify_broadcasted_delta_ctl: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data); // TODO } return true; } // End of function f_verify_broadcasted_delta_ctl function f_verify_and_extract_payload( in GeoNetworkingPdu p_geonetworking_pdu, in boolean p_check_security := true, out octetstring p_payload ) return boolean { var EtsiTs103097Data v_secured_msg; var bitstring v_tbs; var Certificate v_certificate; var boolean v_result; var EtsiTs102941Data v_etsi_ts_102941_data; log(">>> f_verify_and_extract_payload: p_geonetworking_pdu= ", p_geonetworking_pdu); if (not(ispresent(p_geonetworking_pdu.gnPacket.securedMsg))) { return false; } v_secured_msg := p_geonetworking_pdu.gnPacket.securedMsg; // 1. Verify signature log("f_verify_and_extract_payload: v_secured_msg= ", v_secured_msg); v_tbs := encvalue(v_secured_msg.content.signedData.tbsData); if (ischosen(v_secured_msg.content.signedData.signer.certificate)) { v_certificate := v_secured_msg.content.signedData.signer.certificate[0]; } else { var charstring v_certificate_id; if (f_getCertificateFromDigest(v_secured_msg.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { log("f_verify_and_extract_payload: Failed to retrieve certificate from digest ", v_secured_msg.content.signedData.signer.digest); if (p_check_security == true) { return false; } } } if (ischosen(v_secured_msg.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } else { v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); } if (v_result == false) { log("f_verify_and_extract_payload: Failed to verify signature"); if (p_check_security == true) { return false; } } log("f_verify_and_extract_payload: v_etsi_ts_102941_data= ", v_secured_msg.content.signedData.tbsData.payload.data.content.unsecuredData); // TODO return true; } // End of function f_verify_and_extract_payload } // End of group tlm group awaiting_messages { function f_await_http_inner_ec_request_response( out octetstring p_private_key_ec, out octetstring p_compressed_public_key, out integer p_compressed_mode, out HashedId8 p_ec_cert_hashed_id8, out InnerEcResponse p_inner_ec_response, in boolean p_strict_checks := true, in boolean p_store_ec_certificate := false ) runs on ItsPkiHttp return boolean { var Headers v_headers; var Oct32 v_request_hash; var Oct16 v_encrypted_sym_key; var Oct16 v_aes_sym_key; var HashedId8 v_aes_sym_key_hashed_id8; var Oct16 v_authentication_vector; var Oct12 v_nonce; var octetstring v_salt; var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; var EtsiTs102941Data v_etsi_ts_102941_data; var HttpMessage v_response; log(">>> f_await_http_inner_ec_request_response: p_strict_checks=", p_strict_checks); f_http_build_inner_ec_request(p_private_key_ec, p_compressed_public_key, p_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash); v_aes_sym_key_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256('80'O & v_aes_sym_key)); // Used to macth the response f_init_default_headers_list(-, "inner_ec_request", v_headers); f_http_send( v_headers, m_http_request( m_http_request_post( PICS_HTTP_POST_URI_EC, v_headers, m_http_message_body_binary( m_binary_body_ieee1609dot2_data( v_ieee1609dot2_signed_and_encrypted_data ))))); tc_ac.start; alt { [] a_await_ec_http_request_from_iut( mw_http_response( mw_http_response_ok( mw_http_message_body_binary( mw_binary_body_ieee1609dot2_data( mw_enrolmentResponseMessage( mw_encryptedData( { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, mw_symmetricCiphertext_aes128ccm )))))), v_response ) { tc_ac.stop; if (f_verify_pki_response_message(p_private_key_ec, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, p_strict_checks, -, v_etsi_ts_102941_data) == false) { log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***"); if (p_strict_checks) { return false; } } log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***"); // Verify the received EC certificate log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(?/*FIXME YANN Blackberry substr(v_request_hash, 0, 16)*/, mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec)))) == false) { log("f_await_http_inner_ec_request_response: Unexpected message received ***"); if (p_strict_checks) { return false; } } if (ischosen(v_etsi_ts_102941_data.content.enrolmentResponse) and ispresent(v_etsi_ts_102941_data.content.enrolmentResponse.certificate)) { if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, p_compressed_public_key, p_compressed_mode, p_ec_cert_hashed_id8) == false) { log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***"); if (p_strict_checks) { return false; } } vc_ec_hashed_id8[vc_ec_keys_counter - 1] := p_ec_cert_hashed_id8; p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse; log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***"); log("f_await_http_inner_ec_request_response: p_inner_ec_response= ", p_inner_ec_response); if (p_store_ec_certificate) { f_store_certificate(p_private_key_ec, p_inner_ec_response.certificate, p_ec_cert_hashed_id8); // var integer v_signing_algorithm; // var octetstring v_public_key_x; // var octetstring v_public_key_y; // var octetstring v_public_key_compressed; // var integer v_verify_compressed_mode; // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { // v_signing_algorithm := 0; // nist_p_256 // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; // v_verify_compressed_mode := 0; // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; // v_verify_compressed_mode := 1; // } else { // TODO // } // v_public_key_x := v_public_key_compressed; // Key X-Coordinate // fx_get_uncompressed_key_nistp256(p_private_key_ec, v_public_key_compressed, v_verify_compressed_mode, v_public_key_y); // Key Y-Coordinate // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) { // v_signing_algorithm := 2; // brainpool_p_256_r1 // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; // v_verify_compressed_mode := 0; // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; // v_verify_compressed_mode := 1; // } else { // TODO // } // v_public_key_x := v_public_key_compressed; // Key X-Coordinate // fx_get_uncompressed_key_brainpoolp256r1(p_private_key_ec, v_public_key_compressed, v_verify_compressed_mode, v_public_key_y); // Key Y-Coordinate // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { // v_signing_algorithm := 3; // brainpool_p_384_r1 // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_0)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_0; // v_verify_compressed_mode := 0; // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_1)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_1; // v_verify_compressed_mode := 1; // } else { // TODO // } // v_public_key_x := v_public_key_compressed; // Key X-Coordinate // fx_get_uncompressed_key_brainpoolp384r1(p_private_key_ec, v_public_key_compressed, v_verify_compressed_mode, v_public_key_y); // Key Y-Coordinate // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384)) { // v_signing_algorithm := 1; // nist_p_384 // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384.compressed_y_0)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384.compressed_y_0; // v_verify_compressed_mode := 0; // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384.compressed_y_1)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP384.compressed_y_1; // v_verify_compressed_mode := 1; // } else { // TODO // } // v_public_key_x := v_public_key_compressed; // Key X-Coordinate // fx_get_uncompressed_key_brainpoolp384r1(p_private_key_ec, v_public_key_compressed, v_verify_compressed_mode, v_public_key_y); // Key Y-Coordinate // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecsigSm2)) { // v_signing_algorithm := 4; // sm2_p_256 // if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecsigSm2.compressed_y_0)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecsigSm2.compressed_y_0; // v_verify_compressed_mode := 0; // } else if (ischosen(p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecsigSm2.compressed_y_1)) { // v_public_key_compressed := p_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecsigSm2.compressed_y_1; // v_verify_compressed_mode := 1; // } else { // TODO // } // v_public_key_x := v_public_key_compressed; // Key X-Coordinate // fx_get_uncompressed_key_brainpoolp384r1(p_private_key_ec, v_public_key_compressed, v_verify_compressed_mode, v_public_key_y); // Key Y-Coordinate // } else { // log("*** " & testcasename() & ": INCONC: Wrong certificate format, invalid verification key, back to initial"); // f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); // stop; // } // log("f_await_http_inner_ec_request_response: : v_signing_algorithm =", v_signing_algorithm); // log("f_await_http_inner_ec_request_response: : v_public_key_x =", v_public_key_x); // log("f_await_http_inner_ec_request_response: : v_public_key_y =", v_public_key_y); // log("f_await_http_inner_ec_request_response: : v_public_key_compressed =", v_public_key_compressed); // log("f_await_http_inner_ec_request_response: : v_verify_compressed_mode=", v_verify_compressed_mode); // var octetstring v_encoded_cert := bit2oct(encvalue(p_inner_ec_response.certificate)); // var Oct32 v_ec_cert_hash_256 := f_hashWithSha256(v_encoded_cert); // var HashedId8 v_issuer; // if ((v_signing_algorithm == 1) or (v_signing_algorithm == 3)) { // v_issuer := p_inner_ec_response.certificate.issuer.sha384AndDigest; // } else if (v_signing_algorithm == 4) { // v_issuer := p_inner_ec_response.certificate.issuer.sm3AndDigest; // } else { // v_issuer := p_inner_ec_response.certificate.issuer.sha256AndDigest; // } // if (fx_store_certificate( // v_signing_algorithm, // oct2char(unichar2oct(p_inner_ec_response.certificate.toBeSigned.id.name)), // v_encoded_cert, // p_private_key_ec, // v_public_key_x, v_public_key_y, // v_public_key_compressed, v_verify_compressed_mode, v_ec_cert_hash_256, p_ec_cert_hashed_id8, p_ec_cert_hashed_id8, v_issuer, // omit, omit, omit, omit, omit // Ignore encryption keys // ) == false) { // log("f_await_http_inner_ec_request_response: Failed to store certificate: ", p_inner_ec_response.certificate); // return false; // } } } else { log("f_await_http_inner_ec_request_response: Invalid message received ***"); return false; } } [] tc_ac.timeout { log("f_await_http_inner_ec_request_response: Expected message not received ***"); } } // End of 'alt' statement return true; } // End of function f_await_http_inner_ec_request_response group PredefinedRequests { template (present) HttpMessage mw_http_ec_request_generic ( template (present) Ieee1609Dot2Data p_ieee1609dot2_data := mw_enrolmentRequestMessage(mw_encryptedData()) ) := mw_http_request( mw_http_request_post( PICS_HTTP_POST_URI_EC, -, mw_http_message_body_binary( mw_binary_body_ieee1609dot2_data( p_ieee1609dot2_data) ))); } // End of predefined requests function f_await_ec_request_send_response( out InnerEcRequest p_inner_ec_request, out InnerEcResponse p_inner_ec_response, out HttpMessage p_request, in EnrolmentResponseCode p_response_code := ok, in template (omit) CertificateSubjectAttributes p_attributes := omit ) runs on ItsPkiHttp return boolean { var boolean v_result := false; var HttpMessage v_wrong_request; var Headers v_headers; log(">>> f_await_ec_request_send_response"); f_init_default_headers_list(-, "inner_ec_response", v_headers); tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, p_request) { var Ieee1609Dot2Data v_decrypted_message; var EtsiTs102941Data v_etsi_ts_102941_data; var template (value) HttpMessage v_response; var Oct16 v_request_hash, v_aes_enc_key; tc_ac.stop; if(f_read_ec_request_from_iut_itss( p_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_etsi_ts_102941_data, p_inner_ec_request )){ var EtsiTs103097Certificate v_ec_certificate; var HashedId8 v_ec_certificate_hashed_id8; var Ieee1609Dot2Data v_response_message; log(">>>>>> f_await_ec_request_send_response v_inner_ec_request=", p_inner_ec_request); if(ispresent(p_attributes)){ if(isvalue(p_attributes.id)){ p_inner_ec_request.requestedSubjectAttributes.id := valueof(p_attributes.id); } if(isvalue(p_attributes.validityPeriod)){ p_inner_ec_request.requestedSubjectAttributes.validityPeriod := valueof(p_attributes.validityPeriod); } if(isvalue(p_attributes.region)){ p_inner_ec_request.requestedSubjectAttributes.region := valueof(p_attributes.region); } if(isvalue(p_attributes.assuranceLevel)){ p_inner_ec_request.requestedSubjectAttributes.assuranceLevel := valueof(p_attributes.assuranceLevel); } if(isvalue(p_attributes.appPermissions)){ p_inner_ec_request.requestedSubjectAttributes.appPermissions := valueof(p_attributes.appPermissions); } if(isvalue(p_attributes.certIssuePermissions)){ p_inner_ec_request.requestedSubjectAttributes.certIssuePermissions := valueof(p_attributes.certIssuePermissions); } } f_http_build_inner_ec_response(p_inner_ec_request, p_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_response_message); v_response := m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers)); } else { v_response := m_http_response(m_http_response_500_internal_error(v_headers)); } f_http_send(v_headers, v_response); v_result := true; } [] a_await_ec_http_request_from_iut( mw_http_request(), v_wrong_request) { log(">>>>>> f_await_ec_request_send_response: Wrong message received ", v_wrong_request); log(" ", match(v_wrong_request, mw_http_request())); f_http_send(v_headers, m_http_response(m_http_response_500_internal_error(v_headers))); repeat; } [] tc_ac.timeout { log("f_await_ec_request_send_response: Expected message not received ***"); } } // End of 'alt' statement return v_result; } // End of function f_await_ec_request_send_response function f_await_ec_request_send_no_response( out HttpMessage p_request ) runs on ItsPkiHttp { log(">>> f_await_ec_request_send_no_response"); tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, p_request) { tc_ac.stop; log("f_await_ec_request_send_no_response: Restart HTT connection ***"); f_http_restart("inner_ec_request"); } [] tc_ac.timeout { log("f_await_ec_request_send_no_response: Expected message not received ***"); } } // End of 'alt' statement } // End of function f_await_ec_request_send_no_response function f_await_ec_request_send_error_response( out HttpMessage p_request ) runs on ItsPkiHttp { var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; var boolean v_result := false; log(">>> f_await_ec_request_send_error_response"); tc_ac.start; alt { [] a_await_ec_http_request_from_iut( mw_http_request( mw_http_request_post( PICS_HTTP_POST_URI_EC, -, mw_http_message_body_binary( mw_binary_body_ieee1609dot2_data( mw_enrolmentRequestMessage( mw_encryptedData( -, mw_symmetricCiphertext_aes128ccm )))))), p_request ) { var template (value) HttpMessage v_response; var Headers v_headers; tc_ac.stop; f_init_default_headers_list(-, "inner_ec_response", v_headers); log("f_await_ec_request_send_error_response: Failed to verify PKI message ***"); // Send error message v_response := m_http_response(m_http_response_ko(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers, 400, "Bad request")); // Initialize v_reponse with an error message f_http_send(v_headers, v_response); } [] tc_ac.timeout { log("f_await_ec_request_send_error_response: Expected message not received ***"); } } // End of 'alt' statement } // End of function f_await_ec_request_send_error_response } // End of group awaiting_messages group pki_functions { /** * @desc Build a signed and encrypted PKI request message * @param p_private_key Private key for signature * @param p_signer_identifier Signer identifier for signature, could be self or certificate HashedId8 * @param p_recipientId Recipient identifier to be inclued in encrypted layer. * If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built * @param p_public_key_compressed The public compressed key (canonical form) for encryption * @param p_compressed_mode The compressed mode of the public compressed key (canonical form) for encryption * @param p_pki_message The PKI message to be secured * @param p_ieee1609dot2_signed_and_encrypted_data The secured message * @return true on success, false otherwise */ function f_build_pki_secured_request_message_signed_with_pop( in octetstring p_private_key, in SignerIdentifier p_signer_identifier, in HashedId8 p_recipientId, in octetstring p_public_key_compressed, in integer p_compressed_mode, in octetstring p_salt, in octetstring p_pki_message, in SignAlgorithm p_enc_algorithm, // TODO Use RCA to check encryption alg in boolean p_alter_signature := false, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out Oct32 p_request_hash ) return boolean { // Local variables var template (value) EccP256CurvePoint v_eccP256_curve_point; var template (value) ToBeSignedData v_tbs; var octetstring v_tbs_signed; var Signature v_signature; var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data; var octetstring v_encoded_request; var HashedId8 v_recipientId; var octetstring v_public_compressed_ephemeral_key; var integer v_public_compressed_ephemeral_mode; var octetstring v_encrypted_request; var EncryptedDataEncryptionKey v_encrypted_data_encryption_key; var bitstring v_enc_value; log(">>> f_build_pki_secured_request_message_signed_with_pop: p_private_key= ", p_private_key); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_signer_identifier= ", p_signer_identifier); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_recipientId= ", p_recipientId); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_public_key_compressed= ", p_public_key_compressed); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_compressed_mode= ", p_compressed_mode); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_salt= ", p_salt); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_pki_message= ", p_pki_message); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_enc_algorithm= ", p_enc_algorithm); log(">>> f_build_pki_secured_request_message_signed_with_pop: p_alter_signature= ", p_alter_signature); // Signed the encoded PKI message v_tbs := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(p_pki_message) ), m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/) ); log("f_build_pki_secured_request_message_signed_with_pop: v_tbs: ", v_tbs); if (ischosen(p_signer_identifier.self_)) { v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key); } else { var charstring v_certificate_id; var octetstring v_hash; fx_readCertificateFromDigest(p_signer_identifier.digest, v_certificate_id); // TODO Add a wrapper function f_getCertificateHash(v_certificate_id, v_hash); v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), v_hash, p_private_key); } log("f_build_pki_secured_request_message_signed_with_pop: lengthof(v_tbs_signed)= ", lengthof(v_tbs_signed)); log("f_build_pki_secured_request_message_signed_with_pop: v_tbs_signed= ", v_tbs_signed); if (p_alter_signature == true) { v_tbs_signed[0] := '0A'O; v_tbs_signed[1] := '0A'O; log("f_build_pki_secured_request_message_signed_with_pop: Altered signature= ", v_tbs_signed); } // Add the signature and create EtsiTs103097Data-Signed data structure log("f_build_pki_secured_request_message_signed_with_pop: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { v_signature := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (PX_VE_ALG == e_brainpool_p256_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_nist_p384) { v_signature := valueof( m_signature_ecdsaNistP384( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } else if (PX_VE_ALG == e_brainpool_p384_r1) { v_signature := valueof( m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_tbs_signed, 0, 48) ), substr(v_tbs_signed, 48, 48) ) ) ); } log("f_build_pki_secured_request_message_signed_with_pop: v_signature= ", v_signature); v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed( m_signedData( sha256, v_tbs, p_signer_identifier, v_signature ) ); // Encode EtsiTs103097Data-Signed data structure v_encoded_request := bit2oct(encvalue(v_ieee1609dot2_signed_data)); log("f_build_pki_secured_request_message_signed_with_pop: v_encoded_request= ", v_encoded_request); // Encrypt encode EtsiTs103097Data-Signed data structure if (p_enc_algorithm == e_nist_p256) { v_encrypted_request := f_encryptWithEciesNistp256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (PX_VE_ALG == e_sm2_p256) { v_encrypted_request := f_encryptWithEciesSm2p256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_request := f_encryptWithEciesBrainpoolp256r1WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else { log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant"); return false; } log("f_build_pki_secured_request_message_signed_with_pop: p_aes_sym_key= ", p_aes_sym_key); log("f_build_pki_secured_request_message_signed_with_pop: p_encrypted_sym_key= ", p_encrypted_sym_key); log("f_build_pki_secured_request_message_signed_with_pop: p_authentication_vector= ", p_authentication_vector); log("f_build_pki_secured_request_message_signed_with_pop: p_nonce= ", p_nonce); log("f_build_pki_secured_request_message_signed_with_pop: p_recipientId= ", p_recipientId); if (p_recipientId == int2oct(0, 8)) { log("f_build_pki_secured_request_message_signed_with_pop: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key)); v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key)); } else { v_recipientId := p_recipientId; } log("f_build_pki_secured_request_message_signed_with_pop: v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } if (p_enc_algorithm == e_nist_p256) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesBrainpoolP256r1( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } else { log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant"); return false; } p_ieee1609dot2_signed_and_encrypted_data := valueof( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_certRecipInfo( m_pKRecipientInfo( v_recipientId, v_encrypted_data_encryption_key )) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( p_nonce, v_encrypted_request ) ) ) ) ); // The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data); p_request_hash := f_hashWithSha256(bit2oct(v_enc_value)); log("f_build_pki_secured_request_message_signed_with_pop: p_request_hash= ", p_request_hash); log("<<< f_build_pki_secured_request_message_signed_with_pop: ", p_pki_message); return true; } // End of function f_build_pki_secured_request_message_signed_with_pop /** * @desc Build a signed and encrypted PKI request message without POP with signature * @param p_recipientId Recipient identifier to be inclued in encrypted layer. * If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built * @param p_public_key_compressed The public compressed key (canonical form) for encryption * @param p_compressed_mode The compressed mode of the public compressed key (canonical form) for encryption * @param p_pki_message The PKI message to be secured * @param p_ieee1609dot2_signed_and_encrypted_data The secured message * @return true on success, false otherwise */ function f_build_pki_secured_request_message( in HashedId8 p_recipientId, in octetstring p_public_key_compressed, in integer p_compressed_mode, in octetstring p_salt, in octetstring p_pki_message, in SignAlgorithm p_enc_algorithm, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out Oct32 p_request_hash ) return boolean { // Local variables var template (value) EccP256CurvePoint v_eccP256_curve_point; var HashedId8 v_recipientId; var octetstring v_public_compressed_ephemeral_key; var integer v_public_compressed_ephemeral_mode; var octetstring v_encrypted_request; var EncryptedDataEncryptionKey v_encrypted_data_encryption_key; var bitstring v_enc_value; log(">>> f_build_pki_secured_request_message"); // Encrypt encode EtsiTs103097Data-Signed data structure if (p_enc_algorithm == e_nist_p256) { v_encrypted_request := f_encryptWithEciesNistp256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (PX_VE_ALG == e_sm2_p256) { v_encrypted_request := f_encryptWithEciesSm2p256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_request := f_encryptWithEciesBrainpoolp256r1WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else { log("f_build_pki_secured_request_message: Wrong encryption variant"); return false; } log("f_build_pki_secured_request_message: p_aes_sym_key= ", p_aes_sym_key); log("f_build_pki_secured_request_message: p_encrypted_sym_key= ", p_encrypted_sym_key); log("f_build_pki_secured_request_message: p_authentication_vector= ", p_authentication_vector); log("f_build_pki_secured_request_message: p_nonce= ", p_nonce); log("f_build_pki_secured_request_message: p_recipientId= ", p_recipientId); if (p_recipientId == int2oct(0, 8)) { log("f_build_pki_secured_request_message: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key)); v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key)); } else { v_recipientId := p_recipientId; } log("f_build_pki_secured_request_message: v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } if (p_enc_algorithm == e_nist_p256) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesBrainpoolP256r1( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } p_ieee1609dot2_signed_and_encrypted_data := valueof( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_certRecipInfo( m_pKRecipientInfo( v_recipientId, v_encrypted_data_encryption_key )) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( p_nonce, v_encrypted_request ) ) ) ) ); // The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data); p_request_hash := f_hashWithSha256(bit2oct(v_enc_value)); log("f_build_pki_secured_request_message: p_request_hash= ", p_request_hash); log("<<< f_build_pki_secured_request_message: ", p_ieee1609dot2_signed_and_encrypted_data); return true; } // End of function f_build_pki_secured_request_message function f_build_pki_secured_request_message_for_authorization( in HashedId8 p_recipientId, in octetstring p_public_key_compressed, in integer p_compressed_mode, in octetstring p_salt, in octetstring p_pki_message, in SignAlgorithm p_enc_algorithm, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce, out Oct32 p_request_hash ) return boolean { // Local variables var Ieee1609Dot2Data v_unsecured_data; var octetstring v_pki_message; var template (value) EccP256CurvePoint v_eccP256_curve_point; var HashedId8 v_recipientId; var octetstring v_public_compressed_ephemeral_key; var integer v_public_compressed_ephemeral_mode; var octetstring v_encrypted_request; var EncryptedDataEncryptionKey v_encrypted_data_encryption_key; var bitstring v_enc_value; log(">>> f_build_pki_secured_request_message_for_authorization"); // Add Ieee1609Dot2Data layer v_unsecured_data := valueof(m_etsiTs103097Data_unsecured(p_pki_message)); v_pki_message := bit2oct(encvalue(v_unsecured_data)); // Encrypt encode EtsiTs103097Data-Signed data structure if (p_enc_algorithm == e_nist_p256) { v_encrypted_request := f_encryptWithEciesNistp256WithSha256(v_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (p_enc_algorithm == e_sm2_p256) { v_encrypted_request := f_encryptWithEciesSm2p256WithSha256(v_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_request := f_encryptWithEciesBrainpoolp256r1WithSha256(v_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce); } else { log("f_build_pki_secured_request_message_for_authorization: Wrong encryption variant"); return false; } log("f_build_pki_secured_request_message_for_authorization: p_aes_sym_key= ", p_aes_sym_key); log("f_build_pki_secured_request_message_for_authorization: p_encrypted_sym_key= ", p_encrypted_sym_key); log("f_build_pki_secured_request_message_for_authorization: p_authentication_vector= ", p_authentication_vector); log("f_build_pki_secured_request_message_for_authorization: p_nonce= ", p_nonce); log("f_build_pki_secured_request_message_for_authorization: p_recipientId= ", p_recipientId); if (p_recipientId == int2oct(0, 8)) { log("f_build_pki_secured_request_message_for_authorization: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key)); v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key)); } else { v_recipientId := p_recipientId; } log("f_build_pki_secured_request_message_for_authorization: v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) if (v_public_compressed_ephemeral_mode == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key)); } if (p_enc_algorithm == e_nist_p256) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (p_enc_algorithm == e_brainpool_p256_r1) { v_encrypted_data_encryption_key := valueof( m_encryptedDataEncryptionKey_eciesBrainpoolP256r1( m_evciesP256EncryptedKey( v_eccP256_curve_point, p_encrypted_sym_key, p_authentication_vector ))); } p_ieee1609dot2_signed_and_encrypted_data := valueof( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_certRecipInfo( m_pKRecipientInfo( v_recipientId, v_encrypted_data_encryption_key )) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( p_nonce, v_encrypted_request ) ) ) ) ); // The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data); p_request_hash := f_hashWithSha256(bit2oct(v_enc_value)); log("f_build_pki_secured_request_message_for_authorization: p_request_hash= ", p_request_hash); log("<<< f_build_pki_secured_request_message_for_authorization: ", p_ieee1609dot2_signed_and_encrypted_data); return true; } // End of function f_build_pki_secured_request_message_for_authorization /** * @desc Build a signed and encrypted PKI response message * @param p_private_key Private key for signature * @param p_signer_identifier Signer identifier for signature, could be self or certificate HashedId8 * @param p_recipientId Recipient identifier to be inclued in encrypted layer. * If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built * @param p_public_key_compressed The public compressed key (canonical form) for encryption * @param p_compressed_mode The compressed mode of the public compressed key (canonical form) for encryption * @param p_pki_message The PKI message to be secured * @param p_ieee1609dot2_signed_and_encrypted_data The secured message * @return true on success, false otherwise */ function f_build_pki_secured_response_message( in octetstring p_private_key, in SignerIdentifier p_signer_identifier, in octetstring p_pki_message, in Oct16 p_aes_sym_key, in Oct12 p_nonce, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var template (value) ToBeSignedData v_tbs; var octetstring v_tbs_signed; var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data; var octetstring v_encoded_inner_ec_response; var HashedId8 v_recipientId; var octetstring v_encrypted_inner_ec_response; var octetstring v_symkeyidentifier; // Signed the encoded PKI message v_tbs := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(p_pki_message) ), m_headerInfo_inner_pki_response(-, (f_getCurrentTime() * 1000)/*us*/) ); if (ischosen(p_signer_identifier.self_)) { v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key); } else { var charstring v_certificate_id; var Oct32 v_hash; fx_readCertificateFromDigest(p_signer_identifier.digest, v_certificate_id); // TODO Add a wrapper function log(">>>>> f_build_pki_secured_response_message: use ", v_certificate_id, " for signing response"); log(">>>>> f_build_pki_secured_response_message: use ", p_private_key, " as private key"); f_getCertificateHash(v_certificate_id, v_hash); v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_hash, p_private_key); } // Add the signature and create EtsiTs103097Data-Signed data structure v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed( m_signedData( sha256, v_tbs, p_signer_identifier, m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ) ); // Encode EtsiTs103097Data-Signed data structure v_encoded_inner_ec_response := bit2oct(encvalue(v_ieee1609dot2_signed_data)); v_encrypted_inner_ec_response := fx_encrypt_aes_128_ccm_test(p_aes_sym_key, p_nonce, v_encoded_inner_ec_response); v_symkeyidentifier := '80'O & p_aes_sym_key; log("v_symkeyidentifier= ", v_symkeyidentifier); v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(v_symkeyidentifier)); log("v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) p_ieee1609dot2_signed_and_encrypted_data := valueof( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_pskRecipInfo( v_recipientId ) }, m_symmetricCiphertext_aes128ccm( m_aesCcmCiphertext( p_nonce, v_encrypted_inner_ec_response ) ) ) ) ); log("<<< f_build_pki_secured_response_message: ", p_ieee1609dot2_signed_and_encrypted_data); return true; } // End of function f_build_pki_secured_response_message function f_read_pki_request_message( in Ieee1609Dot2Data p_encrypted_message, in Oct32 p_private_enc_key, in Oct32 p_salt, out Oct16 p_request_hash, out Oct16 p_aes_enc_key, out Ieee1609Dot2Data p_decrypted_message, out EtsiTs102941Data p_etsi_ts_102941_data ) return boolean { var octetstring v_msg; var boolean ret := true; // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_encrypted_message)); log("f_parse_pki_request: Encoded request: ", v_msg); p_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); log("f_parse_pki_request: p_request_hash= ", p_request_hash); // 2. Decrypt message log("f_parse_pki_request: p_private_enc_key= ", p_private_enc_key); if (false == f_decrypt(p_private_enc_key, p_encrypted_message, p_salt, p_decrypted_message, p_aes_enc_key)) { log("f_parse_pki_request: Failed to decrypt message"); return false; } log("f_parse_pki_request: v_ieee1609dot2_signed_data= ", p_decrypted_message); log("f_parse_pki_request: p_aes_enc_key= ", p_aes_enc_key); // 3. get TS 102 941 data select(p_decrypted_message){ case( mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload ) ) ) ) { var bitstring v_msg_bit; v_msg_bit := oct2bit(p_decrypted_message.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) { ret := false; } } case else { ret := false; } } return ret; } // End of function f_read_pki_request_message function f_read_ec_request_from_iut_itss( in Ieee1609Dot2Data p_encrypted_message, out Oct16 p_request_hash, out Oct16 p_aes_enc_key, out Ieee1609Dot2Data p_decrypted_message, out EtsiTs102941Data p_etsi_ts_102941_data, out InnerEcRequest p_inner_ec_request ) runs on ItsPkiHttp return boolean { // Local variables var PublicVerificationKey v_canonical_key; var EtsiTs103097Certificate v_ec_certificate; var HashedId8 v_ec_certificate_hashed_id8; var InnerEcResponse v_inner_ec_response; /* if(false == f_get_canonical_itss_key(v_canonical_key)){ log(">>> f_read_ec_request_from_iut_itss: error getting canonical key"); return false; } */ if( f_read_pki_request_message( p_encrypted_message, vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, p_request_hash, p_aes_enc_key, p_decrypted_message, p_etsi_ts_102941_data )) { // decode InnerEcRequest var bitstring v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, p_inner_ec_request) != 0) { log("f_read_ec_request_from_iut_itss: Failed to decode InnerEcRequest"); } return true; } return false; } // End of function f_read_ec_request_from_iut_itss /** * @desc Verify the protocol element of the Pki message. * If p_check_security is set to false, only decryption and decoding of the outer message are verified. * @param p_private_enc_key Private key for decryption * @param p_salt * @param p_p_ieee1609dot2_encrypted_and_signed_data * @param p_check_security Set to true to verify PKI protocol element such as signatures... * @param p_request_hash The request hash for to be used to build the response * @param p_etsi_ts_102941_data The EtsiTs102941Data message * @param p_aes_enc_key The AES 128 encrytion key to be used to encrypt the response * @return true on success, false otherwise */ function f_verify_pki_request_message( in Oct32 p_private_enc_key, in Oct32 p_salt, in octetstring p_issuer_hash, in template (omit) PublicVerificationKey p_verification_key, in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data, in boolean p_check_security := true, out Oct16 p_request_hash, out HashedId8 p_bfk_request_hash, out EtsiTs102941Data p_etsi_ts_102941_data, out Oct16 p_aes_enc_key ) return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct32 v_hash; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var Certificate v_certificate; var charstring v_certificate_id; log(">>> f_verify_pki_request_message: p_private_enc_key= ", p_private_enc_key); log(">>> f_verify_pki_request_message: p_salt= ", p_salt); log(">>> f_verify_pki_request_message: p_issuer_hash= ", p_issuer_hash); log(">>> f_verify_pki_request_message: p_verification_key= ", p_verification_key); log(">>> f_verify_pki_request_message: p_ieee1609dot2_encrypted_and_signed_data= ", p_ieee1609dot2_encrypted_and_signed_data); // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_ieee1609dot2_encrypted_and_signed_data)); log("f_verify_pki_request_message: Encoded request: ", v_msg); v_hash := f_hashWithSha256(v_msg); p_request_hash := substr(v_hash, 0, 16); //p_bfk_request_hash := f_hashedId8FromSha256(v_hash); log("f_verify_pki_request_message: p_request_hash= ", p_request_hash); // 2. Decrypt the InnerEcRequest log("f_verify_pki_request_message: p_private_enc_key= ", p_private_enc_key); if (f_decrypt(p_private_enc_key, p_ieee1609dot2_encrypted_and_signed_data, p_salt, v_ieee1609dot2_signed_data, p_aes_enc_key) == false) { log("f_verify_pki_request_message: Failed to decrypt message"); return false; } log("f_verify_pki_request_message: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data); log("f_verify_pki_request_message: p_aes_enc_key= ", p_aes_enc_key); // 3. Check basics security log( match( v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload, mw_ieee1609Dot2_headerInfo(c_its_aid_SCR) ) ) ))); if (match(v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed(mw_signedData(-, mw_toBeSignedData(mw_signedDataPayload)))) == false) { log("f_verify_pki_request_message: Failed to check basic security"); if (p_check_security == true) { return false; } } // 4. Verifiy signature log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData); v_msg := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData)); if (not ispresent(p_verification_key)){ var EtsiTs103097Certificate v_cert; var charstring v_cert_id; if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.digest)){ if (not f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_cert, v_cert_id)){ if (p_check_security == true) { return false; } } } if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.certificate)){ if(lengthof(v_ieee1609dot2_signed_data.content.signedData.signer.certificate) > 0){ v_cert := v_ieee1609dot2_signed_data.content.signedData.signer.certificate[0]; } } if (isbound(v_cert)){ if(ischosen(v_cert.toBeSigned.verifyKeyIndicator.verificationKey)){ p_verification_key := v_cert.toBeSigned.verifyKeyIndicator.verificationKey; } } } if (ispresent(p_verification_key)){ log("f_verify_pki_request_message: v_msg= ", v_msg); if (false == f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_signed_data.content.signedData.signature_, valueof(p_verification_key))) { if (p_check_security == true) { return false; } } } // 5. Return the PKI message log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) { if (p_check_security == true) { return false; } } if (p_etsi_ts_102941_data.version != PkiProtocolVersion) { if (p_check_security == true) { return false; } } log("<<< f_verify_pki_request_message: true"); return true; } // End of function f_verify_pki_request_message /** * @desc Verify the protocol element of the Pki message. * If p_check_security is set to false, only decryption and decoding of the outer message are verified. * @param p_private_enc_key Private key for decryption * @param p_salt * @param p_p_ieee1609dot2_encrypted_and_signed_data * @param p_check_security Set to true to verify PKI protocol element such as signatures... * @param p_request_hash The request hash for to be used to build the response * @param p_etsi_ts_102941_data The EtsiTs102941Data message * @param p_aes_enc_key The AES 128 encrytion key to be used to encrypt the response * @return true on success, false otherwise */ function f_verify_pki_request_message_with_certificate( in Oct32 p_private_enc_key, in Oct32 p_salt, in EtsiTs103097Certificate p_signer_certificate, in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data, in boolean p_check_security := true, out Oct16 p_request_hash, out HashedId8 p_bfk_request_hash, out EtsiTs102941Data p_etsi_ts_102941_data, out Oct16 p_aes_enc_key ) return boolean { // Local variables var bitstring v_msg_bit; var octetstring v_msg; var Oct32 v_hash; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; log(">>> f_verify_pki_request_message_with_certificate: p_private_enc_key= ", p_private_enc_key); log(">>> f_verify_pki_request_message_with_certificate: p_salt= ", p_salt); log(">>> f_verify_pki_request_message_with_certificate: p_signer_certificate= ", p_signer_certificate); log(">>> f_verify_pki_request_message_with_certificate: p_ieee1609dot2_encrypted_and_signed_data= ", p_ieee1609dot2_encrypted_and_signed_data); // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_ieee1609dot2_encrypted_and_signed_data)); log("f_verify_pki_request_message_with_certificate: Encoded request: ", v_msg); v_hash := f_hashWithSha256(v_msg); p_request_hash := substr(v_hash, 0, 16); //p_bfk_request_hash := f_hashedId8FromSha256(v_hash); log("f_verify_pki_request_message_with_certificate: p_request_hash= ", p_request_hash); // 2. Decrypt the InnerEcRequest log("f_verify_pki_request_message_with_certificate: p_private_enc_key= ", p_private_enc_key); if (f_decrypt(p_private_enc_key, p_ieee1609dot2_encrypted_and_signed_data, p_salt, v_ieee1609dot2_signed_data, p_aes_enc_key) == false) { log("f_verify_pki_request_message_with_certificate: Failed to decrypt message"); return false; } log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data); log("f_verify_pki_request_message_with_certificate: p_aes_enc_key= ", p_aes_enc_key); // 3. Check basics security log( match( v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload, mw_ieee1609Dot2_headerInfo(c_its_aid_SCR) ) ) ))); if (match(v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed(mw_signedData(-, mw_toBeSignedData(mw_signedDataPayload)))) == false) { log("f_verify_pki_request_message_with_certificate: Failed to check basic security"); if (p_check_security == true) { return false; } } // 4. Verifiy signature log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData); v_msg := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData)); log("f_verify_pki_request_message_with_certificate: v_msg= ", v_msg); var octetstring v_enc := bit2oct(encvalue(p_signer_certificate)); var Oct32 v_issuer := f_hashWithSha256(v_enc); log("f_verify_pki_request_message_with_certificate: signing issuer= ", v_issuer); if (f_verifyEcdsa(v_msg, v_issuer, v_ieee1609dot2_signed_data.content.signedData.signature_, p_signer_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { if (p_check_security == true) { return false; } } // 4. Return the PKI message log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) { if (p_check_security == true) { return false; } } if (p_etsi_ts_102941_data.version != PkiProtocolVersion) { if (p_check_security == true) { return false; } } log("<<< f_verify_pki_request_message_with_certificate: true"); return true; } // End of function f_verify_pki_request_message_with_certificate_with_certificate /** * @desc Verify the protocol element of the Pki message. * If p_check_security is set to false, only decryption and decoding of the outer message are verified. * @param p_private_key Private key for decryption * @param p_publicEphemeralCompressedKey * @param p_publicEphemeralCompressedKeyMode * @param p_issuer Issuer * @param p_certificate Certificate to use for verification key * @param p_ieee1609dot2_encrypted_and_signed_data The received encrypted and signed data * @param p_check_security Set to true to verify PKI protocol element such as signatures... * @param p_response_type Response type (0: InnerEcResponse, 1: InnerAtResponse...). Default: 0 * @param p_etsi_ts_102941_data The EtsiTs102941Data message * @return true on success, false otherwise */ function f_verify_pki_response_message( in octetstring p_private_enc_key, in Oct16 p_aes_sym_key, in Oct16 p_authentication_vector, // TODO Tobe removed in octetstring p_issuer, in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data, in boolean p_check_security := true, in integer p_response_type := 0, out EtsiTs102941Data p_etsi_ts_102941_data ) return boolean { // Local variables var octetstring v_public_enc_key; var integer v_compressed_enc_key_mode; var octetstring v_plain_message; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; var Certificate v_certificate; var charstring v_certificate_id; var bitstring v_etsi_ts_102941_data_msg; var bitstring v_tbs; var boolean v_ret; log(">>> f_verify_pki_response_message: p_private_enc_key= ", p_private_enc_key); log(">>> f_verify_pki_response_message: p_aes_sym_key= ", p_aes_sym_key); log(">>> f_verify_pki_response_message: p_authentication_vector= ", p_authentication_vector); log(">>> f_verify_pki_response_message: p_issuer= ", p_issuer); log(">>> f_verify_pki_response_message: p_check_security= ", p_check_security); log(">>> f_verify_pki_response_message: p_response_type= ", p_response_type); // TODO Check p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.recipients[0].pskRecipInfo. See IEEE Std 1609.2-2017 Clause 6.3.34 PreSharedKeyRecipientInfo // 1. Decrypt the data v_plain_message := fx_decrypt_aes_128_ccm_test(p_aes_sym_key, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.nonce, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.ccmCiphertext); if (isbound(v_plain_message) == false) { return false; } log("f_verify_pki_response_message: v_plain_message= ", v_plain_message); // 2. Decode it v_tbs := oct2bit(v_plain_message); if (decvalue(v_tbs, v_ieee1609dot2_signed_data) != 0) { return false; } log("f_verify_pki_response_message: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data); // 3. Check the signature log("f_verify_pki_response_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData); v_tbs := encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData); if (f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { if (p_check_security == true) { return false; } } if (f_verifyEcdsa(bit2oct(v_tbs), p_issuer, v_ieee1609dot2_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { if (p_check_security == true) { return false; } } // 4. Verify EtsiTs103097Data-Signed HeaderInfo // TODO Parameter p_response_type seems to be useless if ((p_response_type == 0) or (p_response_type == 1)) { // InnerEcResponse & InnerAtResponse log("f_verify_pki_response_message: headerInfo matching= ", match(v_ieee1609dot2_signed_data.content.signedData.tbsData.headerInfo, mw_headerInfo_inner_pki_response)); if (match(v_ieee1609dot2_signed_data.content.signedData.tbsData.headerInfo, mw_headerInfo_inner_pki_response) == false) { if (p_check_security == true) { return false; } } } // else, no check // 5. Return the PKI message log("f_verify_pki_response_message: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_etsi_ts_102941_data_msg := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_etsi_ts_102941_data_msg, p_etsi_ts_102941_data) != 0) { return false; } if (p_etsi_ts_102941_data.version != PkiProtocolVersion) { return false; } return true; } // End of function f_verify_pki_response_message function f_verify_repeated_request( in HttpMessage p_request_1, in HttpMessage p_request_2 ) return boolean { return false; } // End of function f_verify_repeated_request /** * @desc Verify the EC certificate generated by the EA entity * @param p_ec_certificate The new EC certificate * @param p_ea_certificate The certificate issuer * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerEcRequest * @param p_compressed_mode The public compressed key mode * @return true on success, false otherwise */ function f_verify_ec_certificate( in Certificate p_ec_certificate, in Certificate p_ea_certificate, in HashedId8 p_ea_hashed_id8, in octetstring p_public_key_compressed, in integer p_compressed_mode, out HashedId8 p_ec_cert_hashed_id8 ) return boolean { var bitstring v_encoded_cert; var Oct32 v_ec_cert_hash_256; // Calculate the HashedId8 of the whole certificate v_encoded_cert := encvalue(p_ec_certificate); v_ec_cert_hash_256 := f_hashWithSha256(bit2oct(v_encoded_cert)); log("f_verify_ec_certificate: ==> EC certificate Hash: ", v_ec_cert_hash_256); p_ec_cert_hashed_id8 := f_hashedId8FromSha256(v_ec_cert_hash_256); log("f_verify_ec_certificate: ==> EC certificate HashedId8: ", p_ec_cert_hashed_id8); // Check the signer log("f_verify_ec_certificate: Check the signer: ", match(p_ec_certificate.issuer, m_issuerIdentifier_sha256AndDigest(p_ea_hashed_id8))); log("f_verify_ec_certificate: Check the signer: ", match(p_ec_certificate.issuer, m_issuerIdentifier_sha384AndDigest(p_ea_hashed_id8))); if ( (match(p_ec_certificate.issuer, m_issuerIdentifier_sha256AndDigest(p_ea_hashed_id8)) == false) and (match(p_ec_certificate.issuer, m_issuerIdentifier_sha384AndDigest(p_ea_hashed_id8)) == false) ) { log("f_verify_ec_certificate: Wrong issuer"); return false; } // Check EC certificate signature if (f_verifyCertificateSignatureWithPublicKey(p_ec_certificate, p_ea_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { log("f_verify_ec_certificate: Signature not verified"); return false; } // TODO Check that requested information are present if (f_verifySspPermissions(p_ec_certificate.toBeSigned.appPermissions, p_ea_certificate.toBeSigned.appPermissions) == false) { log("f_verify_ec_certificate: Ssp permissions not verified"); return false; } return true; } // End of function f_verify_ec_certificate /** * @desc Verify the generated AT certificate * @param p_at_certificate The new AT certificate * @param p_ea_certificate The certificate issuer * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerAtRequest * @param p_compressed_mode The public compressed key mode * @return true on success, false otherwise */ function f_verify_at_certificate( in Certificate p_at_certificate, in Certificate p_aa_certificate, in octetstring p_public_key_compressed, in integer p_compressed_mode ) return boolean { var bitstring v_encoded_cert; var HashedId8 v_at_cert_hashed_id8; // Calculate the HashedId8 of the whole certificate v_encoded_cert := encvalue(p_at_certificate); v_at_cert_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(bit2oct(v_encoded_cert))); log("f_verify_at_certificate: EC certificate HashedId8: ", v_at_cert_hashed_id8); // Check the signer log("f_verify_at_certificate: ", match(p_at_certificate.issuer, mw_issuerIdentifier_self())); if (match(p_at_certificate.issuer, mw_issuerIdentifier_self)) { return false; } // Check EC certificate signature if (f_verifyCertificateSignatureWithPublicKey(p_at_certificate, p_aa_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { log("f_verify_at_certificate: Signature not verified"); return false; } // TODO Check that requested information are present if (f_verifySspPermissions(p_aa_certificate.toBeSigned.appPermissions, p_at_certificate.toBeSigned.appPermissions) == false) { log("f_verify_at_certificate: Ssp permissions not verified"); return false; } return true; } // End of function f_verify_at_certificate } // End of group inner_ec_xxx group altsteps { altstep a_default_pki_http() runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [not(PICS_MULTIPLE_END_POINT)] httpPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http altstep a_default_pki_http_ec() runs on ItsPkiHttp { [PICS_MULTIPLE_END_POINT] httpEcPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [PICS_MULTIPLE_END_POINT] httpEcPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpEcPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpEcPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http_ec altstep a_default_pki_http_atv() runs on ItsPkiHttp { [PICS_MULTIPLE_END_POINT] httpAtVPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpAtVPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http_atv altstep a_default_pki_http_at() runs on ItsPkiHttp { [PICS_MULTIPLE_END_POINT] httpAtPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [PICS_MULTIPLE_END_POINT] httpAtPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpAtPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpAtPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http_at altstep a_default_pki_http_ca() runs on ItsPkiHttp { [PICS_MULTIPLE_END_POINT] httpCaPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http_ca altstep a_default_pki_http_tlm() runs on ItsPkiHttp { [PICS_MULTIPLE_END_POINT] httpTlmPort.receive( mw_http_response( mw_http_response_ko )) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); } [PICS_MULTIPLE_END_POINT] httpTlmPort.receive(mw_http_request) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Request received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpTlmPort.receive(mw_http_response) { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP Response received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [PICS_MULTIPLE_END_POINT] httpTlmPort.receive { tc_ac.stop; log("*** a_default: ERROR: Unexpected HTTP message received ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } // End of altstep a_default_pki_http_tlm altstep a_await_ec_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_ec_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_request { log("a_await_ec_http_request_from_iut: Received message on httpEcPort"); } } // End of altstep a_await_ec_http_request_from_iut altstep a_await_ec_http_response_from_iut( template HttpMessage p_http_message, out HttpMessage p_response ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response { log("a_await_ec_http_response_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_response { log("a_await_ec_http_response_from_iut: Received message on httpEcPort"); } } // End of altstep a_await_ec_http_response_from_iut altstep a_await_at_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_at_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpAtPort.receive(p_http_message) -> value p_request { log("a_await_at_http_request_from_iut: Received message on httpAtPort"); } } // End of altstep a_await_at_http_request_from_iut altstep a_await_at_http_response_from_iut( template HttpMessage p_http_message, out HttpMessage p_response ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response { log("a_await_at_http_response_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpAtPort.receive(p_http_message) -> value p_response { log("a_await_at_http_response_from_iut: Received message on httpAtPort"); } } // End of altstep a_await_at_http_response_from_iut altstep a_await_atv_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_atv_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(p_http_message) -> value p_request { log("a_await_avt_http_request_from_iut: Received message on httpAtVPort"); } } // End of altstep a_await_atv_http_request_from_iut altstep a_await_atv_http_response_from_iut( template HttpMessage p_http_message, out HttpMessage p_response ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response { log("a_await_atv_http_response_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(p_http_message) -> value p_response { log("a_await_avt_http_response_from_iut: Received message on httpAtVPort"); } } // End of altstep a_await_atv_http_response_from_iut altstep a_await_dc_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_dc_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request { log("a_await_dc_http_request_from_iut: Received message on httpCaPort"); } } // End of altstep a_await_dc_http_request_from_iut altstep a_await_ctl_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_ctl_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request { log("a_await_ctl_http_request_from_iut: Received message on httpCaPort"); } } // End of altstep a_await_ctl_http_request_from_iut altstep a_await_crl_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_crl_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request { log("a_await_crl_http_request_from_iut: Received message on httpCaPort"); } } // End of altstep a_await_crl_http_request_from_iut altstep a_await_cpoc_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_cpoc_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request { log("a_await_cpoc_http_request_from_iut: Received message on httpCaPort"); } } // End of altstep a_await_cpoc_http_request_from_iut altstep a_await_any_http_request_from_iut( template HttpMessage p_http_message, out HttpMessage p_request ) runs on ItsPkiHttp { [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request { log("a_await_any_http_request_from_iut: Received message on httpPort"); } [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request { log("a_await_any_http_request_from_iut: Received message on httpEcPort"); } } // End of altstep a_await_any_http_request_from_iut } // End of group altsteps } // End of module LibItsPki_Functions