From f99be062db136bbb4a03f30614049a3d90b02ec9 Mon Sep 17 00:00:00 2001 From: Denis Filatov Date: Fri, 23 Jul 2021 12:46:52 +0200 Subject: [PATCH 1/9] Initial --- .gitmodules | 4 + ItsPki_Pixits.ttcn | 13 + ItsPki_TestCases.ttcn | 9344 +++++++++++++++++++++++++ ItsPki_TestControl.ttcn | 101 + lib/LibItsPki_EncdecDeclarations.ttcn | 138 + lib/LibItsPki_Functions.ttcn | 4856 +++++++++++++ lib/LibItsPki_Pics.ttcn | 250 + lib/LibItsPki_Pixits.ttcn | 79 + lib/LibItsPki_Templates.ttcn | 671 ++ lib/LibItsPki_TestSystem.ttcn | 124 + lib/LibItsPki_TypesAndValues.ttcn | 153 + lib/asn1 | 1 + lib/module.mk | 31 + module.mk | 53 + 14 files changed, 15818 insertions(+) create mode 100644 .gitmodules create mode 100755 ItsPki_Pixits.ttcn create mode 100755 ItsPki_TestCases.ttcn create mode 100755 ItsPki_TestControl.ttcn create mode 100755 lib/LibItsPki_EncdecDeclarations.ttcn create mode 100755 lib/LibItsPki_Functions.ttcn create mode 100755 lib/LibItsPki_Pics.ttcn create mode 100755 lib/LibItsPki_Pixits.ttcn create mode 100755 lib/LibItsPki_Templates.ttcn create mode 100755 lib/LibItsPki_TestSystem.ttcn create mode 100755 lib/LibItsPki_TypesAndValues.ttcn create mode 160000 lib/asn1 create mode 100755 lib/module.mk create mode 100755 module.mk diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9f836d5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "lib/asn1"] + path = lib/asn1 + url = https://forge.etsi.org/rep/ITS/asn1/pki_ts102941.git + branch = testing diff --git a/ItsPki_Pixits.ttcn b/ItsPki_Pixits.ttcn new file mode 100755 index 0000000..301885d --- /dev/null +++ b/ItsPki_Pixits.ttcn @@ -0,0 +1,13 @@ +module ItsPki_Pixits { + + modulepar integer PX_RE_ENROLMENT_COUNTER := 2; + + modulepar integer PX_RE_AUTHORIZATION_COUNTER := 2; + + modulepar float PX_RE_ENROLMENT_DELAY := 2.0; + + modulepar float PX_RE_AUTHORIZATION_DELAY := 2.0; + + modulepar boolean PX_TRIGGER_EC_BEFORE_AT := true; + +} // End of module ItsPki_Pixits diff --git a/ItsPki_TestCases.ttcn b/ItsPki_TestCases.ttcn new file mode 100755 index 0000000..302a93d --- /dev/null +++ b/ItsPki_TestCases.ttcn @@ -0,0 +1,9344 @@ +/** + * @Author ETSI / STF545 + * @version $Url$ + * $Id$ + * @desc Testcases file for Security Protocol + * @reference ETSI TS ITS-00546v006 + * @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 ItsPki_TestCases { + + // 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; + + // 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 ITS_Container 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_TypesAndValues all; + import from LibItsCommon_ASN1_NamedNumbers all; + + // LibItsGeoNetworking + import from LibItsGeoNetworking_TypesAndValues all; + import from LibItsGeoNetworking_Functions all; + import from LibItsGeoNetworking_Templates all; + import from LibItsGeoNetworking_Pics all; + import from LibItsGeoNetworking_TestSystem all; + + // LibItsSecurity + import from LibItsSecurity_TypesAndValues all; + import from LibItsSecurity_TestSystem all; + import from LibItsSecurity_Templates all; + import from LibItsSecurity_Functions all; + import from LibItsSecurity_Pixits all; + import from LibItsSecurity_Pics all; + + // LibItsHttp + import from LibItsHttp_TypesAndValues all; + import from LibItsHttp_Templates all; + import from LibItsHttp_BinaryTemplates all; + import from LibItsHttp_Functions all; + import from LibItsHttp_TestSystem all; + import from LibItsHttp_Pics all; + + // LibItsPki + import from LibItsPki_TypesAndValues all; + import from LibItsPki_Templates all; + import from LibItsPki_Functions all; + import from LibItsPki_TestSystem all; + import from LibItsPki_Pics all; + import from LibItsPki_Pixits all; + + // ItsPki + import from ItsPki_Pixits all; + + /** + * @desc 5.2 ITS-S behaviour + */ + group itss_behavior { + + group itss_helpers { + + /** + * @desc The purpose of this function is verify the EC request and extract InnerEcRequest and build the InnerEcResponse for the HTTP response + * Note: This function accepts additional parameters to alter the reponse + */ + function f_verify_http_ec_request_from_iut_itss( + in Request p_request, + in Headers p_headers, + out InnerEcRequest p_inner_ec_request, + out InnerEcResponse p_inner_ec_response, + out HttpMessage p_response, + out integer p_result, + in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID, + in template SignerIdentifier p_signer := m_signerIdentifier_self, + in EnrolmentResponseCode p_force_response_code := ok + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_request_hash; + var Oct16 v_aes_enc_key; + var template (value) HttpMessage v_response; + + log(">>> f_verify_http_ec_request_from_iut_itss: ", p_request); + + p_result := 0; + + if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message + // Send error message + v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an error message + // Set verdict + p_result := -1; + } else { + log("f_verify_http_ec_request_from_iut_itss: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer)))) == false) { + // Send error message + f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + // Set verdict + p_result := -2; + } else { + // Verify signature of mw_innerEcRequestSignedForPop + if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request) == false) { + // Send error message + f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := -3; + } else { + log("f_verify_http_ec_request_from_iut_itss: matching: ", match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes({mw_appPermissions(c_its_aid_SCR, ?)})))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)}))) == false) { + // Send error message: Not enrolmentrequest + f_http_build_inner_ec_response(p_inner_ec_request, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := -4; + } else { + // TODO Check ValidityPeriod + // Send OK message + log("f_verify_http_ec_request_from_iut_itss: Receive ", p_inner_ec_request); + if (p_force_response_code == ok) { + f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + } else { + log("f_verify_http_ec_request_from_iut_itss: Succeed buit force error code ", p_force_response_code); + f_http_build_inner_ec_response(p_inner_ec_request, p_force_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + } + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := 0; + } + } + } + } + + p_response := valueof(v_response); + log("<<< f_verify_http_ec_request_from_iut_itss: p_response: ", p_response); + log("<<< f_verify_http_ec_request_from_iut_itss: p_result: ", p_result); + } // End of function f_verify_http_ec_request_from_iut_itss + + /** + * @desc The purpose of this function is verify the AT request and extract InnerAtRequest and build the InnerAtResponse for the HTTP response + * Note: This function accepts additional parameters to alter the reponse + */ + function f_verify_http_at_request_from_iut_itss( + in Request p_request, + in Headers p_headers, + in EtsiTs103097Certificate p_ec_certificate, + out InnerAtRequest p_inner_at_request, + out InnerAtResponse p_inner_at_response, + out HttpMessage p_response, + out integer p_result, + in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID, + in AuthorizationResponseCode p_force_response_code := ok + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_request_hash; + var Oct16 v_aes_enc_key; + var template (value) HttpMessage v_response; + + log(">>> f_verify_http_at_request_from_iut_itss:", p_request); + + p_result := 0; + + // Do not verify the signature now because ATRequest is required to verify the POP signature ==> false + if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Only decryption + // Send error message, unable to decypt it + v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an error message + // Set verdict + p_result := -1; + } else { + log("f_verify_http_at_request_from_iut_itss: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest)) == false) { + // Send error message + f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + // Set verdict + p_result := -2; + } else { + // Extract InnerAtRequest and Verify signature of mw_innerATRequestSignedForPop + if (f_verify_inner_at_request_signed_for_pop(v_etsi_ts_102941_data, p_ec_certificate, p_inner_at_request) == false) { + // Send error message + f_http_build_authorization_response(p_inner_at_request, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := -3; + } else { + log("f_verify_http_at_request_from_iut_itss: match ", match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined + // Send error message: No enrolment request + f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := -4; + } else { + var PublicVerificationKey v_verification_tag; + var octetstring v_encoded_tag; + var octetstring v_key_tag; + + // Build the tag + v_encoded_tag := bit2oct(encvalue(p_inner_at_request.publicKeys.verificationKey)); + if (ispresent(p_inner_at_request.publicKeys.encryptionKey)) { + v_encoded_tag := v_encoded_tag & bit2oct(encvalue(p_inner_at_request.publicKeys.encryptionKey)); + } + // Verify HMAC-SHA256 + log("f_verify_http_at_request_from_iut_itss: v_encoded_tag= ", v_encoded_tag); + v_key_tag := substr( + fx_hmac_sha256( // TODO Rename and use a wrapper function + p_inner_at_request.hmacKey, + v_encoded_tag + ), + 0, + 16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously + log("f_verify_http_at_request_from_iut_itss: v_key_tag: ", v_key_tag); + log("f_verify_http_at_request_from_iut_itss: keyTag= ", p_inner_at_request.sharedAtRequest.keyTag); + log("f_verify_http_at_request_from_iut_itss: matching: ", match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag)); + if (match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag) == false) { + // Send error message: No enrolment request + f_http_build_authorization_response(p_inner_at_request, its_aa_keysdontmatch, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := -5; + + } else { + // Send OK message + log("f_verify_http_at_request_from_iut_itss: Receive ", p_inner_at_request); + if (p_force_response_code == ok) { + f_http_build_authorization_response(p_inner_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + } else { + log("f_verify_http_at_request_from_iut_itss: Succeed built force error code ", p_force_response_code); + f_http_build_authorization_response(p_inner_at_request, p_force_response_code, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + } + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // Set verdict + p_result := 0; + } + } + } + } + } + + p_response := valueof(v_response); + log("<<< f_verify_http_at_request_from_iut_itss: p_response: ", p_response); + log("<<< f_verify_http_at_request_from_iut_itss: p_result: ", p_result); + } // End of function f_verify_http_at_request_from_iut_itss + + /** + * @desc Await ITS CA message using the default AT certificate + */ + altstep a_await_cam_with_current_cert( + in EtsiTs103097Certificate p_certificate + ) runs on ItsPkiItss { + [PICS_SEC_SHA256 == true] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData( + sha256, + mw_toBeSignedData( + mw_signedDataPayload, + mw_headerInfo_cam + ), + mw_signerIdentifier_certificate( + mw_etsiTs103097Certificate( + mw_issuerIdentifier_sha256AndDigest( + p_certificate.issuer.sha256AndDigest + ), + mw_toBeSignedCertificate_at( + -, + p_certificate.toBeSigned.verifyKeyIndicator + ) + ) + ) + ) + ), + mw_geoNwShbPacket + ))) { + } + [PICS_SEC_SHA384 == true] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData( + sha384, + mw_toBeSignedData( + mw_signedDataPayload, + mw_headerInfo_cam + ), + mw_signerIdentifier_certificate( + mw_etsiTs103097Certificate( + mw_issuerIdentifier_sha384AndDigest( + p_certificate.issuer.sha384AndDigest + ), + mw_toBeSignedCertificate_at( + -, + p_certificate.toBeSigned.verifyKeyIndicator + ) + ) + ) + ) + ), + mw_geoNwShbPacket + ))) { + } + } // End of altstep a_await_cam_with_current_cert + + } // End of group itss_helpers + + group itss_enrolment_request { + + /** + * @desc Check that IUT sends an enrolment request when triggered. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "initial state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Enrolment Certificate (EC)
+       *         }
+       *         then {
+       *             the IUT sends to EA an EnrolmentRequestMessage
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_01_BV + * @reference ETSI TS 102 941 [2], clause 6.1.3 + */ + testcase TC_SECPKI_ITSS_ENR_01_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_ENR_01_BV + + group f_TC_SECPKI_ITSS_ENR_01_BV { + + function f_TC_SECPKI_ITSS_ENR_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + f_sendUtTriggerEnrolmentRequestPrimitive(); + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_ENR_01_BV_itss + + function f_TC_SECPKI_ITSS_ENR_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "inner_ec_response", v_headers); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } // TODO Send HTTP error 500 + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_ENR_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_ENR_01_BV + + /** + * @desc If the enrolment request of the IUT is an initial enrolment request, the itsId + * (contained in the InnerECRequest) shall be set to the canonical identifier, the + * signer (contained in the outer EtsiTs1030971Data-Signed) shall be set to self and + * the outer signature shall be computed using the canonical private key. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                          containing InnerECRequestSignedForPOP
+       *                             containing InnerEcRequest
+       *                                 containing itsId
+       *                                     indicating the canonical identifier of the ITS-S 
+       *                 and containing signer
+       *                     declared as self
+       *                 and containing signature 
+       *                     computed using the canonical private key
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_02_BV + * @reference ETSI TS 102 941, clause 6.1.3 + */ + testcase TC_SECPKI_ITSS_ENR_02_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_ENR_02_BV + + /** + * @desc In presence of a valid EC, the enrolment request of the IUT is a rekeying enrolment + request with the itsId (contained in the InnerECRequest) and the SignerIdentifier + (contained in the outer EtsiTs1030971Data-Signed) both declared as digest containing + the HashedId8 of the EC and the outer signature computed using the current valid EC + private key corresponding to the verification public key. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                          containing InnerECRequestSignedForPOP
+       *                             containing InnerEcRequest
+       *                                 containing itsId
+       *                                     declared as digest containing the HashedId8 of the EC identifier
+       *                 and containing signer
+       *                     declared as digest containing the HashedId8 of the EC identifier 
+       *                 and containing signature 
+       *                     computed using the current valid EC private key corresponding to the verification public key
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_03_BV + * @reference ETSI TS 102 941, clause 6.1.3 + */ + testcase TC_SECPKI_ITSS_ENR_03_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_REENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_03_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_ENR_03_BV + + group f_TC_SECPKI_ITSS_ENR_03_BV { + + function f_TC_SECPKI_ITSS_ENR_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + // Trigger the first enrolment + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + // Trigger the second enrolment + f_sendUtTriggerEnrolmentRequestPrimitive(); + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_ENR_03_BV_itss + + function f_TC_SECPKI_ITSS_ENR_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "inner_ec_response", v_headers); + alt { + [] a_await_at_http_response_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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var integer v_result; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + var HttpMessage v_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); + + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } // TODO Send HTTP error 500 + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var integer v_result; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + var HttpMessage v_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss( + v_request.request, + v_headers, + v_inner_ec_request, + v_inner_ec_response, + v_response, + v_result, + PX_EC_HASHED_ID8, // v_response... + // containing itsId declared as digest containing the HashedId8 of the EC identifier + m_signerIdentifier_digest(PX_EC_HASHED_ID8 // containing signer declared as digest containing the HashedId8 of the EC identifier + ) + ); + + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } // TODO Send HTTP error 500 + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_ENR_03_BV_pki + + } // End of group f_TC_SECPKI_ITSS_ENR_03_BV + + /** + * @desc If the EC is revoked, the IUT returns to the state 'initialized'. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_CRL
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is informed about a revocation of its EC
+       *         }
+       *         then {
+       *             the IUT returns to the "initialized" state
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_04_BV + * @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_04_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_key_x; + var Oct32 v_public_key_y; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_CRL) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_CRL required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + + // Synchronization + + // Cleanup + setverdict(inconc); + + } // End of TC_SECPKI_ITSS_ENR_04_BV + + /** + * @desc If the EC expires, the IUT returns to the state 'initialized'. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the EC of the IUT expires
+       *         }
+       *         then {
+       *             the IUT returns to the "initialized" state
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_05_BV + * @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_05_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_key_x; + var Oct32 v_public_key_y; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + + // Synchronization + + // Cleanup + setverdict(inconc); + + } // End of TC_SECPKI_ITSS_ENR_05_BV + + /** + * @desc For each enrolment request, the ITS-S shall generate a new verification key pair + corresponding to an approved signature algorithm as specified in TS 103 097. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and not PICS_SECPKI_REENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send multiple EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             each EnrolmentRequestMessage
+       *                 contains a different and unique verification key pair within the InnerECRequest
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_06_BV + * @reference ETSI TS 102 941, clause 6.1.3 + */ + testcase TC_SECPKI_ITSS_ENR_06_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or PICS_SECPKI_REENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and not PICS_SECPKI_REENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_06_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_06_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_06_BV + + group f_TC_SECPKI_ITSS_ENR_06_BV { + + function f_TC_SECPKI_ITSS_ENR_06_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest := int2oct(0, 8); + var EtsiTs103097Certificate v_certificate; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + // Re-enrolment + for (var integer v_i := 0; v_i < PX_RE_ENROLMENT_COUNTER; v_i := v_i + 1) { + f_sendUtTriggerEnrolmentRequestPrimitive(); + f_sleep(PX_RE_ENROLMENT_DELAY); + } // End of 'for' statement + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_ENR_06_BV_itss + + function f_TC_SECPKI_ITSS_ENR_06_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var integer v_counter := 0; + var Headers v_headers; + var HttpMessage v_request; + var HttpMessage v_response; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + var ListOfPublicVerificationKey v_generated_keys; + var integer v_result; + + // Test component configuration + f_cfHttpUp(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "inner_ec_response", v_headers); + // Wait for the first enrolment response + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + v_generated_keys[v_counter] := v_inner_ec_request.publicKeys.verificationKey; + v_counter := v_counter + 1; + f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": LOG: ", match(v_generated_keys, superset(v_inner_ec_request.publicKeys.verificationKey)), "***"); + if (match(v_generated_keys, superset(v_inner_ec_request.publicKeys.verificationKey)) == true) { + v_generated_keys[v_counter] := v_inner_ec_request.publicKeys.verificationKey; + v_counter := v_counter + 1; + f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Duplication of generated public keys ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + if (v_counter == PX_RE_ENROLMENT_COUNTER) { + log("*** " & testcasename() & ": PASS: InnerEcRequest received with different key pairs ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_ENR_06_BV_pki + + } // End of f_TC_SECPKI_ITSS_ENR_06_BV + + /** + * @desc Within the InnerECRequest, the requestedSubjectAttributes shall not contain a certIssuePermissions field. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                         containing InnerECRequestSignedForPOP
+       *                             containing InnerEcRequest
+       *                                 containing requestedSubjectAttributes
+       *                                     not containing certIssuePermissions 
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_07_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_07_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_key_x; + var Oct32 v_public_key_y; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_07_BV + + /** + * @desc In the headerInfo of the tbsData of the InnerECRequestSignedForPOP all other components + * of the component tbsdata.headerInfo except generationTime and psid are not used and absent. + * The psid shall be set to "secured certificate request" as assigned in ETSI TS 102 965 and + * the generationTime shall be present. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                         containing InnerECRequestSignedForPOP
+       *                             containing tbsData
+       *                                 containing headerInfo
+       *                                     containing psid
+       *                                         indicating AID_CERT_REQ
+       *                                     and containing generationTime
+       *                                     and not containing any other component of tbsdata.headerInfo
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_08_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_08_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_08_BV + + /** + * @desc In the headerInfo of the tbsData of the outer EtsiTs102941Data-Signed all other components + * of the component tbsdata.headerInfo except generationTime and psid are not used and absent. + * The psid shall be set to "secured certificate request" as assigned in ETSI TS 102 965 and + * the generationTime shall be present. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                         containing InnerECRequestSignedForPOP
+       *                             containing tbsData
+       *                                 containing headerInfo
+       *                                     containing psid
+       *                                         indicating AID_CERT_REQ
+       *                                     and containing generationTime
+       *                                     and not containing any other component of tbsdata.headerInfo
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_09_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_09_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_09_BV + + /** + * @desc The EtsiTs103097Data-Encrypted containing the correctly encrypted ciphertext and a recipients + * component containing one instance of RecipientInfo of choice certRecipInfo containing the + * hashedId8 of the EA certificate in recipientId and the encrypted data encryption key in encKey. + * The data encryption key is encrypted using the public key found in the EA certificate referenced + * in the recipientId. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing recipients
+       *                     containing exactly one instance of RecipientInfo of choice certRecipInfo
+       *                         containing recipientId
+       *                             indicating the hashedId8
+       *                                 referencing to the EA certificate
+       *                                     containing encryptionKey (KEY)
+       *                      and containing encKey
+       *                          being a symmetric key (SYMKEY) encrypted using the key KEY
+       *                  containing ciphertext
+       *                      which is encrypted using the symmetric key SYMKEY contained in encKey
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_10_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_10_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_10_BV + + /** + * @desc In the inner signed data structure (InnerECRequestSignedForPOP), the signature is computed + * on InnerECRequest with the private key corresponding to the new verificationKey to prove + * possession of the generated verification key pair. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                         containing InnerECRequestSignedForPOP
+       *                             containing tbsData
+       *                                 containing InnerEcRequest
+       *                                     containing verificationKey (VKEY)
+       *                              containing signature
+       *                                  computed on InnerECRequest
+       *                                      using the private key corresponding to VKEY
+       *                                          contained in InnerECRequest
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_11_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_11_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_11_BV + + /** + * @desc Check that signing of Enrolment HttpRequest message is permitted by the EC certificate. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing signer
+       *                         containing digest
+       *                             indicating HashedId8 of the EC certificate
+       *                                 containing appPermissions
+       *                                     containing an item of type PsidSsp
+       *                                         containing psid
+       *                                             indicating AID_CERT_REQ
+       *                                         and containing ssp
+       *                                             containing opaque[0] (version) 
+       *                                                 indicating 1
+       *                                             containing opaque[1] (value) 
+       *                                                 indicating "Enrolment Request" (bit 1) set to 1
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_12_BV + * @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_12_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_REENROLMENT ) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_03_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + + } // End of TC_SECPKI_ITSS_ENR_12_BV + + } // End of group itss_enrolment_request + + group itss_enrolment_response { + + /** + * @desc If an enrolment request fails, the IUT returns to the state 'initialized. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an EnrolmentRequestMessage
+       *             and the EnrolmentResponseMessage is received
+       *                 containing a responseCode different than 0
+       *         }
+       *         then {
+       *             the IUT returns to the "initialized" state
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_RECV_01_BV + * @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_RECV_01_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_ENR_RECV_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_RECV_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of TC_SECPKI_ITSS_ENR_RECV_01_BV + + group f_TC_SECPKI_ITSS_ENR_RECV_01_BV { + + function f_TC_SECPKI_ITSS_ENR_RECV_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_ENR_RECV_01_BV_itss + + function f_TC_SECPKI_ITSS_ENR_RECV_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "inner_ec_response", v_headers); + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_eaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result, -, -, cantparse); + // Send response forcing error code + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": INFO: InnerEcRequest received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_ENR_RECV_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_ENR_RECV_01_BV + + /** + * @desc The IUT is capable of parsing and handling of positive EnrolmentResponse messages + * containing the requested EC. In case of a successful enrolment, the IUT switches + * to the state 'enrolled'. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is requested to send an initial EnrolmentRequestMessage
+       *             and when the IUT receives a subsequent EnrolmentResponseMessage as an answer of the EA
+       *                 containing a responseCode
+       *                     indicating 0
+       *                 and containing an enrolment certificate
+       *         }
+       *         then {
+       *             the IUT switches to the "enrolled" state
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_ENR_RECV_02_BV + * @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1 + */ + testcase TC_SECPKI_ITSS_ENR_RECV_02_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_ENR_RECV_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_RECV_02_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_ENR_RECV_02_BV + + group f_TC_SECPKI_ITSS_ENR_RECV_02_BV { + + function f_TC_SECPKI_ITSS_ENR_RECV_02_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "inner_ec_response", v_headers); + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_eaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerEcRequest v_inner_ec_request; + var InnerEcResponse v_inner_ec_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); + // Send response forcing error code + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_ENR_RECV_02_BV_pki + + } // End of group f_TC_SECPKI_ITSS_ENR_RECV_02_BV + + } // End of group itss_enrolment_response + + group itss_authorization_request { + + /** + * @desc Check that the ITS-S send the Authorization HttpRequest message to the Authorization Authority (AA) to request an authorization ticket. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_01_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.0 + */ + testcase TC_SECPKI_ITSS_AUTH_01_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_01_BV + + group f_TC_SECPKI_ITSS_AUTH_01_BV { + + function f_TC_SECPKI_ITSS_AUTH_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + var InfoPortData v_info_port_data; + var boolean v_start_awaiting := false; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + f_sendUtTriggerAuthorizationRequestPrimitive(); + tc_ac.start; + alt { + [v_start_awaiting == true] a_await_cam_with_current_cert( + v_info_port_data.at_certificate + ) { + log("*** " & testcasename() & ": PASS: IUT started to send CA message using new AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] geoNetworkingPort.receive { + log("*** " & testcasename() & ": FAIL: IUT started to send CA message using wrong AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] infoPort.receive(InfoPortData:?) -> value v_info_port_data { + log("*** " & testcasename() & ": INFO: Received new AT certificate ***"); + v_start_awaiting := true; + repeat; + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_01_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + var InnerEcResponse v_inner_ec_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PX_TRIGGER_EC_BEFORE_AT) { + if (f_await_ec_request_send_response(v_inner_ec_response) == true) { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerAtRequest v_inner_at_request; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_response.certificate, v_inner_at_request, v_inner_at_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + var octetstring v_msg; + var octetstring v_hashed_id8; + + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + v_msg := bit2oct(encvalue(v_inner_at_response.certificate)); + if (ischosen(v_inner_at_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { + v_hashed_id8 := f_hashedId8FromSha384(f_hashWithSha384(v_msg)); + } else { + v_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(v_msg)); + } + infoPort.send(InfoPortData : { hashed_id8 := v_hashed_id8, at_certificate := v_inner_at_response.certificate }); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_01_BV + + /** + * @desc Check that the AuthorizationRequest message is encrypted and sent to only one Authorization Authority. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *             authorized with CERT_AA certificate
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *                 containing content.encryptedData.recipients
+       *                     indicating size 1
+       *                     and containing the instance of RecipientInfo
+       *                         containing certRecipInfo
+       *                             containing recipientId
+       *                                 indicating HashedId8 of the CERT_AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_02_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 + */ + testcase TC_SECPKI_ITSS_AUTH_02_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_02_BV + + /** + * @desc Check that the AuthorizationRequest message is encrypted using the encryptionKey found in the AA certificate referenced in recipientId. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *             authorized with AA certificate
+       *                 containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *                 containing content.encryptedData
+       *                     containing ciphertext
+       *                         containing data
+       *                             encrypted using AA_ENC_PUB_KEY
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_03_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 + */ + testcase TC_SECPKI_ITSS_AUTH_03_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_03_BV + + /** + * @desc Check that the AuthorizationRequest message is never reused the same encryption key and nonce. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *                 containing content.encryptedData
+       *                     containing ciphertext.aes128ccm.nonce
+       *                         indicating value not equal to the nonce in N previous messages
+       *                 and containing recipients[0].certRecipInfo.encKey
+       *                     containing encrypted symmetric key (S_KEY)
+       *                         indicating symmetric key not equal to the key was used in N previous messages
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_04_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 + */ + testcase TC_SECPKI_ITSS_AUTH_04_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_04_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_04_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_04_BV + + group f_TC_SECPKI_ITSS_AUTH_04_BV { + + function f_TC_SECPKI_ITSS_AUTH_04_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest := int2oct(0, 8); + var EtsiTs103097Certificate v_certificate; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // First enrolment + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] a_await_cam_with_current_cert(v_certificate) { + tc_ac.stop; + + if (PX_TRIGGER_EC_BEFORE_AT) { + f_sendUtTriggerEnrolmentRequestPrimitive(); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed + ))) { + repeat; + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected CA message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + // N authorization + for (var integer v_i := 0; v_i < PX_RE_AUTHORIZATION_COUNTER; v_i := v_i + 1) { + f_sendUtTriggerAuthorizationRequestPrimitive(); + f_sleep(PX_RE_AUTHORIZATION_DELAY); + } // End of 'for' statement + log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_04_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_04_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var integer v_counter := 0; + var Headers v_headers; + var HttpMessage v_request; + var HttpMessage v_response; + var InnerAtRequest v_inner_at_request; + var ListOfPublicVerificationKey v_generated_keys; + var integer v_result; + + // Test component configuration + f_cfHttpUp(); + + // Test adapter configuration + + // Preamble + /*f_init_default_headers_list(-, "inner_at_response", v_headers); + // Wait for the first enrolment response + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_at_request, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + v_generated_keys[v_counter] := v_inner_at_request.publicKeys.verificationKey; + v_counter := v_counter + 1; + f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_request( + mw_http_request_post( + PICS_HTTP_POST_URI_AT, + -, + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentRequestMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_at_request, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": LOG: ", match(v_generated_keys, superset(v_inner_at_request.publicKeys.verificationKey)), "***"); + if (match(v_generated_keys, superset(v_inner_at_request.publicKeys.verificationKey))) { + v_generated_keys[v_counter] := v_inner_at_request.publicKeys.verificationKey; + v_counter := v_counter + 1; + f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Duplication of generated public keys ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + if (v_counter == PX_RE_AUTHORIZATION_COUNTER) { + log("*** " & testcasename() & ": PASS: InnerAtRequest received with different key pairs ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } + } // End of 'alt' statement + */ + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_04_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_04_BV + + /** + * @desc Check that the Authozation request protocol version is set to 1. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *                 containing version
+       *                     indicating value 1
+       *                 and containing content
+       *                     containing autihorizationRequest
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_05_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 + */ + testcase TC_SECPKI_ITSS_AUTH_05_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_05_BV + + } // End of group itss_authorization_request + + group itss_authorization_response { + // TODO + } // End of group itss_authorization_response + + group itss_ctl_handling { + // TODO + } // End of group itss_ctl_handling + + group itss_crl_handling { + // TODO + } // End of group itss_crl_handling + + } // End of group itss_behavior + + group ea_behavior { + + group ea_helpers { + + + } // End of group ea_helpers + + group enrolment_request_handling { + + /** + * @desc The EnrolmentResponse message shall be sent by the EA to the ITS-S across the interface at + * reference point S3 in response to a received EnrolmentRequest message. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage across the interface at the reference point S3
+       *         }
+       *         then {
+       *             the IUT answers with an EnrolmentResponseMessage across the interface at reference point S3
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_RCV_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_RCV_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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 match the response + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_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(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_01_BV + + /** + * @desc Check that EA doesn't accept Enrolment rekeying request when enrolment is not permitted + * by signing certificate. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *                 containing an encrypted EtsiTs103097Data-Signed
+       *                     containing signer
+       *                         containing digest
+       *                             indicating HashedId8 of the certificate CERT
+       *                                 containing appPermissions
+       *                                     not containing an item of type PsidSsp
+       *                                         containing psid
+       *                                             indicating AID_CERT_REQ
+       *                                     or containing an item of type PsidSsp
+       *                                         containing psid
+       *                                             indicating AID_CERT_REQ
+       *                                         and containing ssp
+       *                                             containing opaque[0] (version)
+       *                                                 indicating other value than 1
+       *                                             or containing opaque[1] (value)
+       *                                                 indicating "Enrolment Request" (bit 1) set to 0
+       *         }
+       *         then {
+       *             the IUT answers with an EnrolmentResponseMessage
+       *                 containing InnerECResponse
+       *                     containing responseCode
+       *                         indicating "deniedpermissions"
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_RCV_02_BI + * @reference ETSI TS 102 941, clause B.5 + */ + testcase TC_SECPKI_EA_ENR_RCV_02_BI_01() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + // f_cfHttpUp("CERT_TS_A_EA_AA_AUTHVAL_RCV_02_BI_01", PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + // f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions))) == true) { + log("*** " & testcasename() & ": PASS: InnerEcResponse error code received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_02_BI_01 + + testcase TC_SECPKI_EA_ENR_RCV_02_BI_02() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + // f_cfHttpUp("CERT_TS_A_EA_AA_AUTHVAL_RCV_02_BI_01", PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR_WRONG_VERSION })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + // f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions))) == true) { + log("*** " & testcasename() & ": PASS: InnerEcResponse error code received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_02_BI_02 + + testcase TC_SECPKI_EA_ENR_RCV_02_BI_03() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + // f_cfHttpUp("CERT_TS_A_EA_AA_AUTHVAL_RCV_02_BI_01", PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR_WRONG_SSP_BIT })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + // f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions))) == true) { + log("*** " & testcasename() & ": PASS: InnerEcResponse error code received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_02_BI_03 + + /** + * @desc Enroll an ITS-Station, but with a canonical-ID, that is not registered. + */ + testcase TC_SECPKI_EA_ENR_RCV_05_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, PICS_INVALID_ITS_S_CANONICAL_ID, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), unknownits)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), unknownits))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_05_BI + + /** + * @desc Enroll the ITS-Station, but the CSR re-quests more permissions than the issuer allows, + * i.e. request for security management SSP bit which is not set in the EA SSP + */ + testcase TC_SECPKI_EA_ENR_RCV_06_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedpermissions received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_06_BI + + /** + * @desc Enroll the ITS-Station, but the CSR requests a AID permission that the issuer does not allow, i.e. request for CAM AID + */ + testcase TC_SECPKI_EA_ENR_RCV_07_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })), valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedpermissions))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedpermissions received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_07_BI + + /** + * @desc Enroll the ITS-Station, but the expiring date of the CSR is before the start date of the EA + */ + testcase TC_SECPKI_EA_ENR_RCV_08_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, vc_eaCertificate.toBeSigned.validityPeriod.start_ / 2, valueof(m_duration_years(50)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_08_BI + + /** + * @desc Enroll the ITS-Station, but the start date of the CSR is before the start date of the EA + */ + testcase TC_SECPKI_EA_ENR_RCV_09_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, vc_eaCertificate.toBeSigned.validityPeriod.start_ / 2, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_09_BI + + /** + * @desc Enroll the ITS-Station, but the expiring date of the CSR is after the expiring date of the EA + */ + testcase TC_SECPKI_EA_ENR_RCV_10_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, vc_eaCertificate.toBeSigned.validityPeriod.start_, valueof(m_duration_years(50)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_10_BI + + /** + * @desc Enroll the ITS-Station, but the start date of the CSR is after the expiring date of the EA + */ + testcase TC_SECPKI_EA_ENR_RCV_11_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, 3 * vc_eaCertificate.toBeSigned.validityPeriod.start_, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_11_BI + + /** + * @desc Enroll the ITS-Station, but the lifetime of the EC would be grater than allowed (considering values in C-ITS CP) + */ + testcase TC_SECPKI_EA_ENR_RCV_12_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_years(4)), -, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), deniedrequest))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_12_BI + + /** + * @desc Enroll the ITS-Station, but the inner PoP signature in the CSR, created with the EC private key, can not be verified with the provided public key + */ + testcase TC_SECPKI_EA_ENR_RCV_13_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request_with_wrong_parameters({ valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR })) }, -, f_getCurrentTime() / 1000, valueof(m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)), true, v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), invalidsignature)))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16), invalidsignature))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse with deniedrequest received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_RCV_13_BI + + } // End of group enrolment_request_handling + + group enrolment_response { + + /** + * @desc The EnrolmentResponse message shall be encrypted using an ETSI TS 103 097 approved + * algorithm and the encryption shall be done with the same AES key as the one used + * by the ITS-S requestor for the encryption of the EnrolmentRequest message + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *                 containing encKey
+       *                     containing an encrypted AES key (SYMKEY)
+       *         }
+       *         then {
+       *             the IUT answers with an EnrolmentResponseMessage
+       *                 containing cipherTex
+       *                     being encrypted using SYMKEY
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + log("*** " & testcasename() & ": PASS: InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_01_BV + + /** + * @desc The EnrolmentResponse message shall be encrypted using an ETSI TS 103 097 approved + * algorithm and the encryption shall be done with the same AES key as the one used + * by the ITS-S requestor for the encryption of the EnrolmentRequest message. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *                 containing encKey
+       *                     containing an encrypted AES key (SYMKEY)
+       *         }
+       *         then {
+       *             the IUT answers with an EnrolmentResponseMessage
+       *                 containing cipherTex
+       *                     being encrypted
+       *                         using SYMKEY
+       *                         and using an ETSI TS 103 097 approved algorithm
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP 22 + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_02_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + f_init_default_headers_list(-, "inner_ec_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + 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_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + log("*** " & testcasename() & ": PASS: InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_02_BV + + /** + * @desc The outermost structure is an EtsiTs103097Data-Encrypted structure containing + * the component recipients containing one instance of RecipientInfo of choice + * pskRecipInfo, which contains the HashedId8 of the symmetric key used by the + * ITS-S to encrypt the EnrolmentRequest message to which the response is built + * and containing the component ciphertext, once decrypted, contains an + * EtsiTs103097Data-Signed structure + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing recipients
+       *                     containing one instance of RecipientInfo of choice pskRecipInfo
+       *                         containing the HashedId8 of the symmetric key used to encrypt the EnrolmentRequestMessage
+       *                 and containing cipherText
+       *                     being an encrypted EtsiTs103097Data-Signed structure
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_03_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_03_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + log("*** " & testcasename() & ": PASS: InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_03_BV + + /** + * @desc If the ITS-S has been able to decrypt the content, this expected EtsiTs103097Data-Signed structure shall + * contain hashId, tbsData, signer and signature. The hashId shall indicate the hash algorithm to be used as + * specified in ETSI TS 103 097, the signer shall be declared as a digest, containing the HashedId8 of the + * EA certificate and the signature over tbsData shall be computed using the EA private key corresponding to + * its publicVerificationKey found in the referenced EA certificate. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing hashId
+       *                        indicating the hash algorithm to be used as specified in ETSI TS 103 097
+       *                     and containing tbsData
+       *                     and containing signer
+       *                         declared as a digest
+       *                             containing the HashedId8 of the EA certificate
+       *                     and containing signature
+       *                         computed over tbsData
+       *                             using the EA private key
+       *                                 corresponding to the publicVerificationKey found in the referenced EA certificate
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_04_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_04_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode) == false) { + log("*** " & testcasename() & ": FAIL: Cannot verify EC certificate signature ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: Well-secured EA certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_04_BV + + /** + * @desc Within the headerInfo of the tbsData, the psid shall be set to secured certificate request as assigned in + * ETSI TS 102 965 and the generationTime shall be present. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing headerInfo
+       *                             containing psid
+       *                                 indicating AID_CERT_REQ
+       *                             and containing generationTime
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_05_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_05_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode)) { + log("*** " & testcasename() & ": PASS: Well-secured EC certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Cannot verify EC certificate signature ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_05_BV + + /** + * @desc Within the headerInfo of the tbsData, aside from psid and generationTime, + * all other components of the component tbsData.headerInfo not used and absent. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing headerInfo
+       *                             containing psid
+       *                             and containing generationTime
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_06_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_06_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode)) { + log("*** " & testcasename() & ": PASS: Well-secured EC certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Cannot verify EC certificate signature ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_06_BV + + /** + * @desc The EtsiTS102941Data shall contain the version set to v1 (integer value set to 1) + * and the content set to InnerECResponse. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing EtsiTS102941Data
+       *                             containing version
+       *                                 indicating v1 (integer value set to 1)
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_07_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_07_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + log("*** " & testcasename() & ": PASS: Well-secured EA certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_07_BV + + /** + * @desc The InnerECResponse shall contain the requestHash, which is the left-most 16 octets of the SHA256 digest of the + * EtsiTs103097Data - Signed structure received in the request and a responseCode indicating the result of the request. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing EtsiTS102941Data
+       *                             containing requestHash
+       *                                 indicating the left-most 16 octets of the SHA256 digest of the EtsiTs103097Data-Signed structure received in the request
+       *                             and containing responseCode
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_08_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_08_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16)))), " ***"); // 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(substr(v_request_hash, 0, 16))))) { + log("*** " & testcasename() & ": PASS: Well-secured EA certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_08_BV + + /** + * @desc If the responseCode is 0, the InnerECResponse shall also contain an (enrolment) certificate. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing EtsiTS102941Data
+       *                             containing InnerECResponse
+       *                                 containing an enrolment certificate
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_09_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_09_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_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 }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: 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(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode) == true) { + log("*** " & testcasename() & ": PASS: Well-secured EC certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: EC certificate is not proerly formated ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_09_BV + + /** + * @desc If the responseCode is different than 0, the InnerECResponse shall not contain a certificate. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing tbsData
+       *                         containing EtsiTS102941Data
+       *                             containing InnerECResponse
+       *                                 not containing a certificate
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_10_BV + * @reference ETSI TS 102 941, clause 6.2.3.2.2 + */ + testcase TC_SECPKI_EA_ENR_10_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_invalid_enrolment_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentResponseMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ko))) { + log("*** " & testcasename() & ": PASS: Well-secured EA certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_10_BV + + /** + * @desc Check that signing of Enrolment response message is permitted by the EA certificate. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the IUT sends an EtsiTs103097Data-Encrypted structure
+       *                 containing an encrypted EtsiTs103097Data-Signed structure
+       *                     containing signer
+       *                         declared as a digest
+       *                             containing the HashedId8 of the EA certificate
+       *                                 containing appPermissions
+       *                                     containing an item of type PsidSsp
+       *                                         containing psid
+       *                                             indicating AID_CERT_REQ
+       *                                         and containing ssp
+       *                                             containing opaque[0] (version) 
+       *                                                 indicating 1
+       *                                             containing opaque[1] (value) 
+       *                                                 indicating bit "Enrolment Response" (5) set to 1
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_11_BV + * @reference ETSI TS 102 941, clause B[5] + */ + testcase TC_SECPKI_EA_ENR_11_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_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 }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: 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(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode) == true) { + log("*** " & testcasename() & ": PASS: Well-secured EC certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: EC certificate is not proerly formated ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_11_BV + + /** + * @desc Check that generated EC certificate contains only allowed permissions. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an EnrolmentRequestMessage
+       *         }
+       *         then {
+       *             the EC_CERT
+       *                 containing appPermissions
+       *                     containing an item of type PsidSsp
+       *                         containing psid
+       *                             indicating AID_CERT_REQ
+       *                         and containing ssp
+       *                             containing opaque[0] (version) 
+       *                                 indicating 1
+       *                             containing opaque[1] (value) 
+       *                                 indicating "Enrolment Request" (bit 0) set to 1
+       *                                 indicating "Authorization Request" (bit 1) set to 1
+       *                                 indicating other bits set to 0
+       *                     and NOT containing an item of type PsidSsp
+       *                         containing psid
+       *                             indicating AID_CTL
+       *                     and NOT containing an item of type PsidSsp
+       *                         containing psid
+       *                             indicating AID_CRL
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_ENR_12_BV + * @reference ETSI TS 102 941, clause B[5] + */ + testcase TC_SECPKI_EA_ENR_12_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key; + var Oct32 v_public_compressed_key; + var integer v_compressed_mode; + var Oct32 v_request_hash; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Oct16 v_aes_sym_key; + var Oct16 v_encrypted_sym_key; + var Oct16 v_authentication_vector; + var Oct12 v_nonce; + var octetstring v_salt; + var Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_http_build_inner_ec_request(v_private_key, v_public_compressed_key, v_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); + 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 + ))))); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + tc_ac.start; + alt { + [] a_await_ec_http_response_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 }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, -, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": LOG: Receive ", v_etsi_ts_102941_data, " ***"); + log("*** " & testcasename() & ": DEBUG: 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(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) { + if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, vc_eaHashedId8, v_public_compressed_key, v_compressed_mode) == true) { + log("*** " & testcasename() & ": PASS: Well-secured EC certificate received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: EC certificate is not proerly formated ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: Unexpected message received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_ENR_12_BV + + } // End of group enrolment_response + + group authorization_validation_request { + + group atv_helpers { + + function f_verify_http_at_request_from_iut_atv( + in Request p_request, + out Oct16 p_aes_enc_key, + out Oct16 p_request_hash, + out SharedAtRequest p_shared_at_request, + out integer p_result + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + + log(">>> f_verify_http_at_request_from_iut_atv: p_request= ", p_request); + + p_result := 0; + + if (f_verify_pki_request_message(vc_eaPrivateEncKey/*Encrypted with AA*/, vc_eaWholeHash/*salt*/, vc_aaWholeHash/*Issuer is AA*/, p_request.body.binary_body.ieee1609dot2_data, true, p_request_hash, v_etsi_ts_102941_data, p_aes_enc_key) == false) { + // Set verdict + p_result := -1; + } else { + log("f_verify_http_at_request_from_iut_atv: Receive ", v_etsi_ts_102941_data); + log(match(v_etsi_ts_102941_data.content, mw_authorizationValidationRequest(mw_authorization_validation_request(mw_shared_at_request, mw_ec_signature)))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_authorizationValidationRequest(mw_authorization_validation_request(mw_shared_at_request, mw_ec_signature))) == false) { // TODO To be refined + // Set verdict + p_result := -2; + } else { + p_shared_at_request := v_etsi_ts_102941_data.content.authorizationValidationRequest.sharedAtRequest; + log("f_verify_http_at_request_from_iut_atv: p_shared_at_request= ", p_shared_at_request); + // TODO Refined expected mw_signature_ecdsaNistP256 + } + } + + log("<<< f_verify_http_at_request_from_iut_atv: p_shared_at_request= ", p_shared_at_request); + log("<<< f_verify_http_at_request_from_iut_atv: p_aes_sym_key= ", p_aes_enc_key); + log("<<< f_verify_http_at_request_from_iut_atv: p_request_hash= ", p_request_hash); + log("<<< f_verify_http_at_request_from_iut_atv: p_result: ", p_result); + } // End of function f_verify_http_at_request_from_iut_atv + + function f_verify_http_at_response_from_iut_atv( + in InnerAtRequest p_inner_at_request, + in Response p_response, + in octetstring p_private_key, + in Oct16 p_aes_sym_key, + in Oct16 p_authentication_vector, + in Oct32 p_request_hash, + out InnerAtResponse p_inner_at_response, + //TODO out EtsiTs103097Data p_authorization_validation_response, + out integer p_result + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key; + var InnerEcResponse v_inner_ec_response; + + log(">>> f_verify_http_at_response_from_iut_atv: p_inner_at_request= ", p_inner_at_request); + log(">>> f_verify_http_at_response_from_iut_atv: p_response= ", p_response); + log(">>> f_verify_http_at_response_from_iut_atv: p_private_key= ", p_private_key); + log(">>> f_verify_http_at_response_from_iut_atv: p_aes_sym_key= ", p_aes_sym_key); + log(">>> f_verify_http_at_response_from_iut_atv: p_authentication_vector= ", p_authentication_vector); + log(">>> f_verify_http_at_response_from_iut_atv: p_request_hash= ", p_request_hash); + + p_result := 0; + + if (f_verify_pki_response_message(p_private_key, p_aes_sym_key, p_authentication_vector, vc_eaWholeHash, p_response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + // Set verdict + p_result := -1; + } else { + log("f_verify_http_at_response_from_iut_atv: Receive ", v_etsi_ts_102941_data); + log(match(v_etsi_ts_102941_data.content, mw_authorizationValidationResponse(mw_authorizationValidationResponse_ok(substr(p_request_hash, 0, 16), mw_certificate_subject_attributes(p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.id, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod))))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_authorizationValidationResponse(mw_authorizationValidationResponse_ok(substr(p_request_hash, 0, 16), mw_certificate_subject_attributes(p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.id, p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod)))) == false) { + // Set verdict + p_result := -2; + } else { + // TODO Refined expected mw_signature_ecdsaNistP256 + log("f_verify_http_at_response_from_iut_atv: Well-secured AT certificate received"); + } + } + + log("<<< f_verify_http_at_response_from_iut_atv: p_result: ", p_result); + } // End of function f_verify_http_at_response_from_iut_atv + + function f_verify_http_at_response_from_iut_atv_error( + in InnerAtRequest p_inner_at_request, + in Response p_response, + in octetstring p_private_key, + in Oct16 p_aes_sym_key, + in Oct16 p_authentication_vector, + in Oct32 p_request_hash, + out InnerAtResponse p_inner_at_response, + //TODO out EtsiTs103097Data p_authorization_validation_response, + out integer p_result + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key; + var InnerEcResponse v_inner_ec_response; + + log(">>> f_verify_http_at_response_from_iut_atv_error: p_inner_at_request= ", p_inner_at_request); + log(">>> f_verify_http_at_response_from_iut_atv_error: p_response= ", p_response); + log(">>> f_verify_http_at_response_from_iut_atv_error: p_private_key= ", p_private_key); + log(">>> f_verify_http_at_response_from_iut_atv_error: p_aes_sym_key= ", p_aes_sym_key); + log(">>> f_verify_http_at_response_from_iut_atv_error: p_authentication_vector= ", p_authentication_vector); + log(">>> f_verify_http_at_response_from_iut_atv_error: p_request_hash= ", p_request_hash); + + p_result := 0; + + if (f_verify_pki_response_message(p_private_key, p_aes_sym_key, p_authentication_vector, vc_eaWholeHash, p_response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + // Set verdict + p_result := -1; + } else { + log("f_verify_http_at_response_from_iut_atv_error: Receive ", v_etsi_ts_102941_data); + log(match(v_etsi_ts_102941_data.content, mw_authorizationValidationResponse(mw_authorizationValidationResponse_ko(substr(p_request_hash, 0, 16))))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_authorizationValidationResponse(mw_authorizationValidationResponse_ko(substr(p_request_hash, 0, 16)))) == false) { + // Set verdict + p_result := -2; + } else { + // TODO Refined expected mw_signature_ecdsaNistP256 + log("f_verify_http_at_response_from_iut_atv_error: Well-formatted error response received"); + } + } + + log("<<< f_verify_http_at_response_from_iut_atv_error: p_result: ", p_result); + } // End of function f_verify_http_at_response_from_iut_atv_error + + } // End of group atv_helpers + + /** + * @desc The AuthorizationValidationResponse message shall be sent by the EA to the AA across the interface + * at reference point S4 in response to a received AuthorizationValidationRequest message + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 across the reference point S4 to the AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_RCV_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.4 + * @remark Need to provide CERT_TS_A_AA & CERT_IUT_A_RCA to the PKI + */ + testcase TC_SECPKI_EA_AUTHVAL_RCV_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured AT certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AT response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_RCV_01_BV + + /** + * @desc Check that EA doesn't accept Authorization Validation Request when + * SharedAtRequest is signed with certificate without appropriate + * permissions + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest  message
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 across the reference point S4 to the AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_RCV_02_BI + * @reference ETSI TS 102 941, clause B[5] + * @remark Need to provide CERT_TS_A_EA_AA_AUTHVAL_RCV_02_BI_01 to the PKI + */ + testcase TC_SECPKI_EA_AUTHVAL_RCV_02_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + //f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + f_cfHttpUp("CERT_TS_A_EA_AA_AUTHVAL_RCV_02_BI_01", PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + if (f_verify_pki_response_message(v_private_key_at, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify PKI message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log(match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16))))); + if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_inner_ec_response(mw_innerEcResponse_ko(substr(v_request_hash, 0, 16)))) == false) { + log("*** " & testcasename() & ": FAIL: Invalid InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: InnerEcResponse received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_RCV_02_BI + + } // End of group authorization_validation_request + + group authorization_validation_response { + + /** + * @desc The EtsiTs103097Data-Encrypted is build with the component recipients containing one instance of RecipientInfo + * of choice pskRecipInfo, which contains the HashedId8 of the symmetric key used by the ITS-S to encrypt the + * AuthorizationRequest message to which the response is built and the component ciphertext containing the encrypted + * representation of the EtsiTs103097Data-Signed. The encryption uses a ETSI TS 103 097 [3] approved algorithm. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *                 containing encKey
+       *                     containing the encrypted symmetric data encryption key (SYMKEY)
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 containing EtsiTs103097Data-Encrypted
+       *                     containing recipients
+       *                         containing one instance of RecipientInfo of choice pskRecipInfo
+       *                             indicating the HashedId8 of SYMKEY
+       *                     and containing ciphertext
+       *                         containing EtsiTs103097Data-Signed
+       *                             being encrypted using SYMKEY and an ETSI TS 103 097 approved algorithm
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured AT certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AT response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_01_BV + + /** + * @desc To read an authorization validation response, the AA shall receive an EtsiTs103097Data-Encrypted structure, + * containing a EtsiTs103097Data-Signed structure, containing a EtsiTs102941Data structure, containing an + * AuthorizationValidationResponse structure. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 containing EtsiTs103097Data-Signed
+       *                     containing AuthorizationValidationResponse
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_02_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_02_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured ATV certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify ATV response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_02_BV + + /** + * @desc The AuthorizationValidationResponse structure contains the requestHash being the left-most 16 octets of + * the SHA256 digest of the EtsiTs103097Data-Signed structure received in the AuthorizationValidationRequest + * and a responseCode. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *                 containing EtsiTs103097Data-Signed structure (REQDSS)
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 containing EtsiTs103097Data-Signed
+       *                     containing EtsiTs102941Data
+       *                         containing AuthorizationValidationResponse
+       *                             containing requestHash
+       *                                 indicating the left-most 16 octets of the SHA256 digest of REQDSS
+       *                             and containing responseCode
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_03_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_03_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured ATV certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify ATV response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_03_BV + + /** + * @desc If the responseCode is 0, the AuthorizationValidationResponse structure contains the component + * confirmedSubjectAttributes with the attributes the EA wishes to confirm, except for certIssuePermissions + * which is not allowed to be present. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *             and the IUT responds with a AuthorizationValidationResponse message
+       *                 containing AuthorizationValidationResponse
+       *                     containing responseCode
+       *                         indicating 0
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 contains an AuthorizationValidationResponse structure
+       *                     containing confirmedSubjectAttributes
+       *                         not containing certIssuePermissions
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_04_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_04_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured ATV certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify ATV response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_04_BV + + /** + * @desc If the responseCode is different than 0, the AuthorizationValidationResponse structure does not contain + * the component confirmedSubjectAttributes. + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *             and the IUT responds with a AuthorizationValidationResponse message
+       *                 containing AuthorizationValidationResponse
+       *                     containing responseCode
+       *                         indicating a value different than 0
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 contains an AuthorizationValidationResponse structure
+       *                     not containing confirmedSubjectAttributes
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_05_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_05_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_invalid_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv_error(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-formatted error response received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AT response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_04_BV + + /** + * @desc The component version of the EtsiTs102941Data structure is set to v1 (integer value set to 1). + *
+       * Pics Selection: PICS_IUT_EA_ROLE
+       * Initial conditions: 
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives a AuthorizationValidationRequest message
+       *         }
+       *         then {
+       *             the IUT sends a AuthorizationValidationResponse message
+       *                 containing EtsiTs103097Data-Signed
+       *                     containing EtsiTs103097Data
+       *                         containing version
+       *                             indicating v1 (integer value set to 1) 
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 TP SECPKI_EA_AUTHVAL_06_BV + * @reference ETSI TS 102 941, clause 6.2.3.4.2 + */ + testcase TC_SECPKI_EA_AUTHVAL_06_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_key_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var InnerAtRequest v_inner_at_request; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + // Test control + if (not PICS_IUT_EA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Trigger an enrolment request + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + // Generate an InnerAtRequest + if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, v_inner_at_request) == false) { + log("*** " & testcasename() & ": ERROR: Failed to generate AuthorizationValidationRequest ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + log("*** " & testcasename() & ": DEBUG: v_inner_at_request= ", v_inner_at_request); + log("*** " & testcasename() & ": DEBUG: v_private_key_at= ", v_private_key_at); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_build_authorization_validation_request(v_inner_at_request, v_public_compressed_key_at, v_compressed_key_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_atv_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_ATV, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_atv(v_inner_at_request, v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured ATV certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify ATV response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + + } // End of testcase TC_SECPKI_EA_AUTHVAL_06_BV + + // TC_SECPKI_EA_AUTHVAL_07_BV covered by TC_SECPKI_EA_AUTHVAL_02..04_BV + + // TC_SECPKI_EA_AUTHVAL_08_BV covered by TC_SECPKI_EA_AUTHVAL_02..04_BV + + // TC_SECPKI_EA_AUTHVAL_09_BV covered by TC_SECPKI_EA_AUTHVAL_02..04_BV + + } // End of group authorization_validation_response + + group ca_ceetificate_request { + // TODO + } // End of group ca_ceetificate_request + + } // End of group ea_behavior + + group aa_behavior { + + group aa_helpers { + + function f_verify_http_at_response_from_iut_aa( + in Response p_response, + in octetstring p_private_key, + in Oct16 p_aes_sym_key, + in Oct16 p_authentication_vector, + in Oct32 p_request_hash, + out InnerAtResponse p_authorization_response, + out integer p_result + ) runs on ItsPkiHttp { + // Local variables + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key; + var InnerEcResponse v_inner_ec_response; + + log(">>> f_verify_http_at_response_from_iut_aa: p_response= ", p_response); + log(">>> f_verify_http_at_response_from_iut_aa: p_private_key= ", p_private_key); + log(">>> f_verify_http_at_response_from_iut_aa: p_aes_sym_key= ", p_aes_sym_key); + log(">>> f_verify_http_at_response_from_iut_aa: p_authentication_vector= ", p_authentication_vector); + log(">>> f_verify_http_at_response_from_iut_aa: p_request_hash= ", p_request_hash); + + p_result := 0; + + if (f_verify_pki_response_message(p_private_key, p_aes_sym_key, p_authentication_vector, vc_aaWholeHash, p_response.body.binary_body.ieee1609dot2_data, true, 1, v_etsi_ts_102941_data) == false) { + // Set verdict + p_result := -1; + } else { + log("f_verify_http_at_response_from_iut_aa: Receive ", v_etsi_ts_102941_data); + p_authorization_response := v_etsi_ts_102941_data.content.authorizationResponse; + log(match(v_etsi_ts_102941_data.content, mw_authorizationResponse(mw_innerAtResponse_ok(substr(p_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_at, -))))); // TODO In TITAN, this is the only way to get the unmatching in log + if (match(v_etsi_ts_102941_data.content, mw_authorizationResponse(mw_innerAtResponse_ok(substr(p_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_at, -)))) == false) { + log(match(v_etsi_ts_102941_data.content, mw_authorizationResponse(mw_innerAtResponse_ko))); + if (match(v_etsi_ts_102941_data.content, mw_authorizationResponse(mw_innerAtResponse_ko)) == false) { + // Set verdict + p_result := -2; + } else { + // Set verdict + p_result := -3; + } + } else { + // Verify AT Certificate signature + if (f_verifyCertificateSignatureWithIssuingCertificate(v_etsi_ts_102941_data.content.authorizationResponse.certificate, vc_aaCertificate) == false) { + // Set verdict + p_result := -4; + } + log("f_verify_http_at_response_from_iut_aa: Well-secured AT certificate received"); + } + } + + log("<<< f_verify_http_at_response_from_iut_aa: p_result: ", p_result); + } // End of function f_verify_http_at_response_from_iut_aa + + } // End of group aa_helpers + + group authorization_request { + + /** + * @desc Check that the EA/AA is able to decrypt the AuthorizationRequest message using the encryption private key corresponding to the recipient certificate + * Check that the EA/AA is able to verify the inner signature + * Check that the EA/AA is able to verify the request authenticity using the hmacKey verification + * Check that the EA/AA sends the AuthorizationValidationRequest message to the correspondent EA + *
+       * Pics Selection: PICS_IUT_AA_ROLE and not PICS_PKI_AUTH_POP
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives an EtsiTs103097Data message
+       *                containing content.encryptedData
+       *                    containing recipients
+       *                        containing the instance of RecipientInfo
+       *                            containing certRecipInfo
+       *                                containing recipientId
+       *                                    indicating HashedId8 of the certificate CERT_AA
+       *                                and containing encKey
+       *                                    indicating symmetric key (S_KEY)
+       *                                        encrypted with the private key correspondent to the AA_ENC_PUB_KEY
+       *                    and containing cyphertext (ENC_DATA)
+       *                        containing encrypted representation of the EtsiTs103097Data-Signed
+       *                            containing content.signedData
+       *                                containing hashId
+       *                                    indicating valid hash algorythm
+       *                and containing signer
+       *                    containing self
+       *                and containing tbsData (SIGNED_DATA)
+       *                    containing payload
+       *                        containing EtsiTs102941Data
+       *                            containing content.authorizationRequest
+       *                                containing publicKeys.verificationKey (V_KEY)
+       *                                and containing hmacKey (HMAC)
+       *                                and containing sharedAtRequest
+       *                                    containing keyTag (KEY_TAG)
+       *                                    and containing eaId (EA_ID)
+       *                                        indicating HashedId8 of the known EA certificate
+       *                and containing signature (SIGNATURE)
+       *         }
+       *         then {
+       *            the IUT is able to decrypt the S_KEY
+       *                using the private key
+       *                    corresponding to the AA_ENC_PUB_KEY
+       *            and the IUT is able to decrypt the cypthertext ENC_DATA
+       *                using the S_KEY
+       *            and the IUT is able to verify the signature SIGNATURE over the SIGNED_DATA
+       *                using the V_KEY
+       *            and the IUT is able to verify integrity of HMAC and KEY_TAG
+       *            and the IUT sends the AuthorizationValidationRequest message to the EA
+       *                identified by the EA_ID
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request(v_ec_certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured AT certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AT response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_01_BV + + /** + * @desc Check that the AA is able to decrypt the AuthorizationRequest message using the encryption private key corresponding to the recipient certificate + * Check that the AA is able to verify the request authenticity using the hmacKey verification + * Check that the AA sends the AuthorizationValidationRequest message to the correspondent EA + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives an EtsiTs103097Data message
+       *                containing content.encryptedData
+       *                    containing recipients
+       *                        containing the instance of RecipientInfo
+       *                            containing certRecipInfo
+       *                                containing recipientId
+       *                                    indicating HashedId8 of the certificate CERT_AA
+       *                                and containing encKey
+       *                                    indicating symmetric key (S_KEY)
+       *                                        encrypted with the private key correspondent to the AA_ENC_PUB_KEY
+       *                    and containing cyphertext (ENC_DATA)
+       *                        containing EtsiTs102941Data
+       *                            containing content.authorizationRequest
+       *                                containing publicKeys.verificationKey (V_KEY)
+       *                                and containing hmacKey (HMAC)
+       *                                and containing sharedAtRequest
+       *                                    containing keyTag (KEY_TAG)
+       *                                    and containing eaId (EA_ID)
+       *                                        indicating HashedId8 of the known EA certificate
+       *         }
+       *         then {
+       *            the IUT is able to decrypt the S_KEY
+       *                using the private key
+       *                    corresponding to the AA_ENC_PUB_KEY
+       *            and the IUT is able to decrypt the cypthertext ENC_DATA
+       *                using the S_KEY
+       *            and the IUT is able to verify integrity of HMAC and KEY_TAG
+       *            and the IUT sends the AuthorizationValidationRequest message to the EA
+       *                identified by the EA_ID
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_02_BV + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_02_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE or PICS_PKI_AUTH_POP) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE and not PICS_PKI_AUTH_POP required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request(v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: Well-secured AT certificate received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AT response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_02_BV + + /** + * @desc Check that the AA skips the AuthorizationRequest message if it is not addressed to this AA + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives an EtsiTs103097Data message
+       *                containing content.encryptedData
+       *                    containing recipients
+       *                        containing the instance of RecipientInfo
+       *                            containing certRecipInfo
+       *                                containing recipientId
+       *                                    NOT equal to the HashedId8 of the certificate CERT_AA
+       *                                and containing encKey
+       *                                    indicating symmetric key (S_KEY)
+       *                                        encrypted with the private key correspondent to the AA_ENC_PUB_KEY
+       *         }
+       *         then {
+       *            the IUT does not send the AuthorizationValidationRequest message
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_03_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_03_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, true, -, -, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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)); + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_noac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_noac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_noac.stop; + + log("*** " & testcasename() & ": PASS: IUT has rejected the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: IUT has discarded the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_03_BI + + /** + * @desc Check that the AA skips the AuthorizationRequest message if it unable to decrypt the encKey + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives an EtsiTs103097Data message
+       *                containing content.encryptedData
+       *                    containing recipients
+       *                        containing the instance of RecipientInfo
+       *                            containing certRecipInfo
+       *                                containing recipientId
+       *                                    indicating value
+       *                                        equal to the HashedId8 of the certificate CERT_AA
+       *                                and containing encKey
+       *                                    indicating symmetric key (S_KEY)
+       *                                        encrypted with the OTHER private key correspondent to the AA_ENC_PUB_KEY
+       *         }
+       *         then {
+       *            the IUT does not send the AuthorizationValidationRequest message
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_04_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_04_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_private_key(v_inner_ec_response.certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_noac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_noac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_noac.stop; + + log("*** " & testcasename() & ": PASS: IUT has rejected the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: IUT has discarded the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_04_BI + + /** + * @desc Check that the AA skips the AuthorizationRequest message if it unable to decrypt the encKey + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives an EtsiTs103097Data message
+       *                containing content.encryptedData
+       *                    containing recipients[0].encKey
+       *                        indicating encrypted symmetric key (S_KEY)
+       *                    and containing cyphertext (ENC_DATA)
+       *                        encrypted with the OTHER key than S_KEY
+       *         }
+       *         then {
+       *            the IUT does not send the AuthorizationValidationRequest message
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_05_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_05_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, true, -, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_noac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + tc_noac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_noac.stop; + + log("*** " & testcasename() & ": PASS: IUT has rejected the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: IUT has discarded the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_05_BI + + /** + * @desc Check that the AA rejects the AuthorizationRequest message if it unable to verify the POP signature + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT is received the EtsiTs103097Data message
+       *                containing content.encryptedData.cyphertext
+       *                    containing encrypted representation of the EtsiTs103097Data-Signed (SIGNED_DATA)
+       *                        containing content.signedData
+       *                            containing tbsData
+       *                                containing payload
+       *                                    containing EtsiTs102941Data
+       *                                        containing content.authorizationRequest
+       *                                            containing publicKeys.verificationKey (V_KEY)
+       *                        and containing signature (SIGNATURE)
+       *                            indicating value calculated with OTHER key than private key correspondent to V_KEY
+       *         }
+       *         then {
+       *            the IUT does not send the AuthorizationValidationRequest message
+       *            and the IUT sends to the TS the AuthorizationResponse message
+       *                containing authorizationResponse
+       *                    containing requestHash
+       *                        indicating the leftmost 16 bits of the SHA256 value
+       *                            calculated over the SIGNED_DATA
+       *                and containing responseCode
+       *                    indicating the value NOT EQUAL to 0
+       *                and not containing certificate
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_06_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_06_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE or not PICS_PKI_AUTH_POP) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE and PICS_PKI_AUTH_POP required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, true, -, -, -, -, -, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": PASS: IUT has rejected the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_06_BI + + /** + * @desc Check that the AA rejects the AuthorizationRequest message if it unable to verify the integrity of the request using hmacKey + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the EA/AA in "operational state"
+       *              authorized with the certificate CERT_AA
+       *                  containing encryptionKey (AA_ENC_PUB_KEY)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT is received the EtsiTs103097Data message
+       *                containing EtsiTs102941Data
+       *                    containing content.authorizationRequest
+       *                        containing hmacKey (HMAC)
+       *                        and containing sharedAtRequest
+       *                            containing keyTag (KEY_TAG)
+       *                                indicating wrong value
+       *         }
+       *         then {
+       *            the IUT does not send the AuthorizationValidationRequest message
+       *            and the IUT sends to the TS the AuthorizationResponse message
+       *                containing authorizationResponse
+       *                    containing requestHash
+       *                        indicating the leftmost 16 bits of the SHA256 value
+       *                            calculated over the X_HASH_STRUCTURE
+       *                and containing responseCode
+       *                    indicating the value NOT EQUAL to 0
+       *                and not containing certificate
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTH_RCV_07_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.1 + */ + testcase TC_SECPKI_AA_AUTH_RCV_07_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, true, -, -, -, -, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": PASS: IUT has rejected the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_07_BI + + /** + * @desc Send a correctly encoded AT request, but the ITS-Station is not enrolled at the EA + */ + testcase TC_SECPKI_AA_AUTH_RCV_08_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, true, -, -, -, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, unknownits)) == true) { + log("*** " & testcasename() & ": PASS: Error code is unknownits ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be unknownits ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_08_BI + + /** + * @desc Send an AT request, but the inner signer (valid EC) is not issued by the EA which is known / trusted by the AA. The AA trusts only EAs listet on the RCA-CTL. + */ + testcase TC_SECPKI_AA_AUTH_RCV_09_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, true, -, -, -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, its_aa_unknownea)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_09_BI + + /** + * @desc Send an AT request, but the generation time of the CSR is in the past. + */ + testcase TC_SECPKI_AA_AUTH_RCV_10_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, -, -, f_getCurrentTime() / 2, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, its_aa_outofsyncrequest)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_10_BI + + /** + * @desc Send an AT request, but the generation time of the CSR is in the future. + */ + testcase TC_SECPKI_AA_AUTH_RCV_11_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, -, -, f_getCurrentTime() * 2, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, its_aa_outofsyncrequest)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_11_BI + + /** + * @desc Send an AT request, but the expiry date of the CSR is before the start date of the EC. + */ + testcase TC_SECPKI_AA_AUTH_RCV_12_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, vc_eaCertificate.toBeSigned.validityPeriod.start_ / 2, m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION), -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, deniedpermissions)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_12_BI + + /** + * @desc Send an AT request, but the start date of the CSR is before the start date of the EC. + */ + testcase TC_SECPKI_AA_AUTH_RCV_13_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, vc_eaCertificate.toBeSigned.validityPeriod.start_ / 2, m_duration_years(50), -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, deniedpermissions)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_13_BI + + /** + * @desc Send an AT request, but the expiry date of the CSR is after the expiry date of the EC. + */ + testcase TC_SECPKI_AA_AUTH_RCV_14_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, f_getCurrentTime() / 1000, m_duration_years(100), -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, deniedpermissions)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_14_BI + + /** + * @desc Send an AT request, but the start date of the CSR is after the expiring date of the EC. + */ + testcase TC_SECPKI_AA_AUTH_RCV_15_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, 2 * f_getCurrentTime() / 1000, m_duration_years(1), -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, deniedpermissions)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_15_BI + + /** + * @desc Send an AT request, but the expiry date of the CSR is after now + maximum pre-loading period (considering values in C-ITS CP). + */ + testcase TC_SECPKI_AA_AUTH_RCV_16_BI() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcResponse v_inner_ec_response; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer p_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + 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 Headers v_headers; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PICS_SIMULATE_EA_ENTITY) { + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + log("*** " & testcasename() & ": DEBUG: v_ec_certificate= ", v_ec_certificate); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_response) == false) { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + v_ec_certificate := v_inner_ec_response.certificate; + log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response); + log("*** " & testcasename() & ": DEBUG: v_private_key_ec= ", v_private_key_ec); + } + + // Test Body + f_http_build_authorization_request_with_wrong_parameters(v_inner_ec_response.certificate, v_private_key_ec, -, -, -, -, -, -, f_getCurrentTime() / 1000, m_duration_in_hours(15*24/* ts_102941v010301 Clause7.2.1*/), -, v_private_key_at, v_public_compressed_key_at, p_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationResponseMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + var InnerAtResponse v_authorization_validation_response; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_authorization_validation_response, v_result); + log("*** " & testcasename() & ": INFO: AuthorizationValidationResponse= ", v_authorization_validation_response, " ***"); + // Set verdict + if (v_result == -3) { + log("*** " & testcasename() & ": INFO: IUT has rejected the request ***"); + if (match(v_authorization_validation_response, mw_innerAtResponse_ko(-, deniedpermissions)) == true) { + log("*** " & testcasename() & ": PASS: Error code is its_aa_unknownea ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Expected error code should be its_aa_outofsyncrequest ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } else { + log("*** " & testcasename() & ": FAIL: IUT shall not process the request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] a_await_at_http_response_from_iut(mw_http_response(mw_http_response_ko), v_response) { + tc_ac.stop; + + log("*** " & testcasename() & ": FAIL: IUT shall not respond with HTTP error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": FAIL: No response received from the IUT ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_AA_AUTH_RCV_16_BI + + } // End of group authorization_request + + group authorization_validation_request { + + /** + * @desc Check that the AA sends AuthorizationValidationRequest after receiving of the AuthorizationRequest. + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *         the EA in "operational" state
+       *             authorized with CERT_EA certificate
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT received the AuthorizationRequest
+       *         }
+       *         then {
+       *            the IUT sends the EtsiTs103097Data message to the ITSS
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTHVAL_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.3.2 + */ + testcase TC_SECPKI_AA_AUTHVAL_01_BV() runs on ServerSyncComp system ItsPkiHttpSystem { + // Local variables + var ItsPkiHttp v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp02(v_itss, v_ea); + + // Test adapter configuration + + // Start components + v_itss.start(f_TC_SECPKI_AA_AUTHVAL_01_BV_itss()); + v_ea.start(f_TC_SECPKI_AA_AUTHVAL_01_BV_ea()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + f_cfMtcDown02(v_itss, v_ea); + } // End of testcase TC_SECPKI_AA_AUTHVAL_01_BV + + group f_TC_SECPKI_AA_AUTHVAL_01_BV { + + function f_TC_SECPKI_AA_AUTHVAL_01_BV_itss() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var octetstring 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 Headers v_headers; + var HttpMessage v_request; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key; + var InnerAtRequest v_inner_at_request; + var InnerAtResponse v_inner_at_response; + + // Test component configuration + f_cfHttpUp_itss(cc_taCert_A_EA, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // Generate EC certificate + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate); + // Send AuthorizationRequest + f_http_build_authorization_request(v_ec_certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test body + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationRequestMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo, * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + + tc_ac.stop; + + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + if (v_result == 0) { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_itss: PASS: Received exptected response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // inconc + } else { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_itss: FAIL: Unexptected response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); // inconc + } + } + [] tc_ac.timeout { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_itss: INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown_itss(); + } // End of function f_TC_SECPKI_AA_AUTHVAL_01_BV_itss + + function f_TC_SECPKI_AA_AUTHVAL_01_BV_ea() runs on ItsPkiHttp system ItsPkiHttpSystem { + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var octetstring v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var HashedId8 v_aes_sym_key_hashed_id8; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_request; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key := int2oct(0, 16); + var SharedAtRequest v_shared_at_request; + var AuthorizationValidationResponse v_authorization_validation_response; + + // Test component configuration + f_cfHttpUp_ea(cc_taCert_A_EA, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test body + tc_ac.start; + alt { + [] a_await_atv_http_request_from_iut( // Wait for authorizationValidation Request from IUT to EA + mw_http_request( + mw_http_request_post( + -, //FIXME: Use another PIXIT than PICS_HTTP_POST_URI_ATV, + -, + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationRequestMessage( + mw_encryptedData( + { *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var integer v_result; + + tc_ac.stop; + + f_verify_http_at_request_from_iut_atv(v_request.request, v_aes_sym_key, v_request_hash, v_shared_at_request, v_result); + // Set verdict + if (v_result == 0) { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_ea: PASS: IUT has sent AuthorizationValidation request ***"); + // Send AuthorizationValidation response to finalize the exchange + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_ea: INFO: Send AuthorizationValidation response to finalize the exchange ***"); + f_init_default_headers_list(-, "inner_atv_response", v_headers); + f_http_build_authorization_validation_response(v_shared_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_authorization_validation_response, v_ieee1609dot2_signed_and_encrypted_data); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_ea: FAIL: Failed to verify AuthorizationValidation request ***"); + // Send AuthorizationValidation response to finalize the exchange + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_ea: INFO: Send AuthorizationValidation response to finalize the exchange ***"); + f_init_default_headers_list(-, "inner_atv_response", v_headers); + f_http_build_authorization_validation_response(v_shared_at_request, deniedpermissions, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_authorization_validation_response, v_ieee1609dot2_signed_and_encrypted_data); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** f_TC_SECPKI_AA_AUTHVAL_01_BV_ea: INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + // TODO Wait for AuthorizationResponse + f_cfHttpDown_ea(); + + } // End of function f_TC_SECPKI_AA_AUTHVAL_01_BV_ea + + } // End of group f_TC_SECPKI_AA_AUTHVAL_01_BV + + } // End of authorization_validation_request + + group authorization_validation_response { + + /** + * @desc Check that the AA sends AuthorizationResponse after receiving the AuthorizationRequest. + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the ITSS in "enrolled" state
+       *          the EA in "operational" state
+       *          and the IUT(AA) in "operational" state
+       *          and the IUT had received the AuthorizationRequest from the ITSS
+       *          and the IUT sent the AuthorizationValidationRequest
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT received the AuthorizationValidationResponseMessage
+       *         }
+       *         then {
+       *            the IUT sends the EtsiTs103097Data message to the ITSS
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTHVAL_RCV_01_BV + * @reference ETSI TS 102 941, clause 6.2.3.3.2 + */ + testcase TC_SECPKI_AA_AUTHVAL_RCV_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {/* + var Oct32 v_private_key_ec; + var Oct32 v_public_compressed_key_ec; + var integer v_compressed_key_mode_ec; + var InnerEcRequest v_inner_ec_request; + var EtsiTs103097Certificate v_ec_certificate; + var Oct32 v_private_key_at; + var Oct32 v_public_compressed_key_at; + var integer v_compressed_mode_at; + var Oct32 v_private_enc_key_at; + var Oct32 v_public_compressed_enc_key_at; + var integer v_compressed_enc_mode_at; + var octetstring v_request_hash; + var Oct16 v_encrypted_sym_key; + var Oct16 v_aes_sym_key; + var HashedId8 v_aes_sym_key_hashed_id8; + var Oct12 v_nonce; + var octetstring v_salt; + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Headers v_headers; + var HttpMessage v_request; + var HttpMessage v_response; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_aes_enc_key; + var InnerAtRequest v_shared_at_request; + var InnerAtResponse v_inner_at_response; + var AuthorizationValidationResponse v_authorization_validation_response; + + // Test control + if (not PICS_IUT_AA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_AA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp(cc_taCert_A_EA, PICS_IUT_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + // TODO Use a function + // Generate EC certificate + f_generate_inner_ec_request(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_inner_ec_request); + f_generate_ec_certificate_for_inner_ec_response(v_inner_ec_request, v_private_key_ec, vc_eaWholeHash, v_ec_certificate) + // Send AuthorizationRequest + f_http_build_authorization_request(v_ec_certificate, v_private_key_ec, v_private_key_at, v_public_compressed_key_at, v_compressed_mode_at, v_private_enc_key_at, v_public_compressed_enc_key_at, v_compressed_enc_mode_at, 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 match the response + f_init_default_headers_list(-, "inner_at_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_atv_http_request_from_iut( // Wait for authorizationValidation Request from IUT to EA + mw_http_request( + mw_http_request_post( + PICS_HTTP_POST_URI_ATV, + -, + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_authorizationRequestMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo, * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var integer v_result; + + tc_ac.stop; + + f_verify_http_at_request_from_iut_atv(v_request.request, v_aes_sym_key, v_request_hash, v_shared_at_request, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": INFO: IUT has sent AuthorizationValidation request ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AuthorizationValidation request ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + // Send AuthorizationValidationResponse + f_init_default_headers_list(-, "inner_atv_response", v_headers); + f_http_build_authorization_response(v_inner_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + f_http_send( + v_headers, + m_http_request( + m_http_request_post( + PICS_HTTP_POST_URI_AT, + v_headers, + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_and_encrypted_data + ))))); + tc_ac.start; + alt { + [] a_await_at_http_response_from_iut( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentRequestMessage( + mw_encryptedData( + { *, mw_recipientInfo_pskRecipInfo(vc_eaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_response + ) { + var integer v_result; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_response_from_iut_aa(v_response.response, v_private_key_at, v_aes_sym_key, v_authentication_vector, v_request_hash, v_inner_at_response, v_result); + // Set verdict + if (v_result == 0) { + log("*** " & testcasename() & ": PASS: IUT has sent AuthorizationValidation response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify AuthorizationValidation response ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown();*/ + } // End of testcase TC_SECPKI_AA_AUTHVAL_RCV_01_BV + + /** + * @desc Check that AA doesn't accept Authorization Validation Response message when this message is + * signed with certificate without appropriate permissions + *
+       * Pics Selection: PICS_IUT_AA_ROLE
+       * Initial conditions: 
+       *     with {
+       *          the ITSS in "enrolled" state
+       *          the EA in "operational" state
+       *          and the IUT(AA) in "operational" state
+       *          and the IUT had received the AuthorizationRequest from the ITSS
+       *          and the IUT sent the AuthorizationValidationRequest
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *            the IUT receives the AuthorizationValidationResponseMessage
+       *                containing signer
+       *                    containing digest
+       *                        indicating HashedId8 of the certificate
+       *                    containing appPermissions
+       *                        not containing an item of type PsidSsp
+       *                        containing psid
+       *                            indicating AID_CERT_REQ
+       *                        or containing an item of type PsidSsp
+       *                            containing psid
+       *                                indicating AID_CERT_REQ
+       *                        and containing ssp
+       *                             containing opaque[0] (version) 
+       *                                 indicating other value than 1
+       *                        or containing opaque[1] (value) 
+       *                            indicating "AuthorizationValidationResponse" (bit 4) set to 0
+       *         }
+       *         then {
+       *            the IUT answers with an AuthorisationValidationResponseMessage
+       *                containing responseCode
+       *                    indicating non-zero value
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_AA_AUTHVAL_RCV_02_BI + * @reference ETSI TS 102 941, clause 6.2.3.3.2 + */ + testcase TC_SECPKI_AA_AUTHVAL_RCV_02_BI() runs on ItsPkiHttp system ItsPkiHttpSystem {} // End of testcase TC_SECPKI_AA_AUTHVAL_RCV_02_BI + + } // End of group authorization_validation_response + + } // End of group aa_beavior + + group ca_behavior { + + group ctl { + + /** + * @desc Check that the RootCA generates the Full CTL when new EA is about to be added to the Root CTL + *
+       * Pics Selection: PICS_IUT_CA_ROLE
+       * Initial conditions: 
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the RootCA is triggered to add new EA certificate (CERT_EA) in the CTL
+       *         }
+       *         then {
+       *             the IUT issue a new CTL of type CtlFormat
+       *                 containing isFullCtl
+       *                     indicating TRUE
+       *                 and containing ctlCommands
+       *                     containing CtlCommand
+       *                         containing add
+       *                             containing ea
+       *                                 containing eaCertificate
+       *                                     indicating CERT_EA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP RCA_CTLGEN_01_BV + * @reference ETSI TS 102 941, clause 6.3.2 and 6.3.4 + */ + testcase TC_RCA_CTLGEN_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Headers v_headers; + var HttpMessage v_response; + + // Test control + if (not PICS_IUT_CA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp_ca(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "ca_request", v_headers); + action("The RootCA is triggered to add new EA certificate (CERT_EA) in the CTL"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_send( + v_headers, + m_http_request( + m_http_request_get( + PICS_HTTP_GET_URI_CTL, + 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_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( + mw_signedDataPayload + ), + mw_signerIdentifier_digest + ))))))) -> value v_response { + var ToBeSignedRcaCtl v_to_be_signed_rca_ctl; + + tc_ac.stop; + + if (f_verify_rca_ctl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, true, v_to_be_signed_rca_ctl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ctl(v_to_be_signed_rca_ctl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [PICS_MULTIPLE_END_POINT] httpCaPort.receive( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( + mw_signedDataPayload + ), + mw_signerIdentifier_digest + ))))))) -> value v_response { + var ToBeSignedRcaCtl v_to_be_signed_rca_ctl; + + tc_ac.stop; + + if (f_verify_rca_ctl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, true, v_to_be_signed_rca_ctl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ctl(v_to_be_signed_rca_ctl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown_ca(); + + } // End of testcase TC_RCA_CTLGEN_01_BV + + testcase TC_RCA_CTLGEN_xx_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var ToBeSignedRcaCtl v_ctl; + var Headers v_headers; + var HttpMessage v_response; + + // Test component configuration + f_cfHttpUp_ca(); + + // Test control + if (not PICS_IUT_CA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp_ca(); + + // Test adapter configuration + + + /*{ + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var ToBeSignedRcaCtl p_to_be_signed_rca_ctl; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_request_hash; + var Oct16 v_aes_enc_key; + var bitstring v_tbs; + + f_build_dc_ctl( + "CERT_IUT_A_RCA", "CERT_TS_A_AA", "CERT_TS_A_EA", + p_to_be_signed_rca_ctl + ); + f_sign_dc_ctl("CERT_IUT_A_RCA", p_to_be_signed_rca_ctl, v_ieee1609dot2_signed_and_encrypted_data); + v_tbs := encvalue(v_ieee1609dot2_signed_and_encrypted_data); + log("############# ", bit2oct(v_tbs)); + setverdict(inconc); + stop; + }*/ + + // Preamble + f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "tlm_request", v_headers); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + if (f_await_dc_request_send_response("CERT_IUT_A_RCA", "CERT_TS_A_AA", "CERT_TS_A_EA", v_ctl)) { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl sent ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to send CTL to the IUT ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + + // Postamble + f_cfHttpDown_ca(); + + } // End of testcase TC_RCA_CTLGEN_xx_BV + + } // End of group ctl + + group crl { + + /** + * @desc Check that the RootCA generates the CRL signed with appropriate certificate + *
+       * Pics Selection: PICS_IUT_CA_ROLE
+       * Initial conditions: 
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the RootCA is triggered to add new CA certificate (CERT_CA) to the revocation list
+       *         }
+       *         then {
+       *             the IUT issue a new CRL of type ToBeSignedCrl
+       *                 containing emtries
+       *                     containing item of type CrlEntry
+       *                         indicating HashedId8 of CERT_CA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP RCA_CRLGEN_01_BV + * @reference ETSI TS 102 941, clause 6.3.3 + */ + testcase TC_RCA_CRLGEN_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Headers v_headers; + var HttpMessage v_response; + + // Test control + if (not PICS_IUT_CA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp_ca(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(PICS_HEADER_CRL_CONTENT_TYPE, "ca_request", v_headers); + action("the RootCA is triggered to generate new CRL"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_send( + v_headers, + m_http_request( + m_http_request_get( + PICS_HTTP_GET_URI_CRL, + 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_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( mw_signedDataPayload ), + mw_signerIdentifier_digest + ))))))) -> value v_response { + var ToBeSignedCrl v_to_be_signed_crl; + + tc_ac.stop; + + if (f_verify_rca_crl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, true, v_to_be_signed_crl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_crl(v_to_be_signed_crl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedCrl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [PICS_MULTIPLE_END_POINT] httpCaPort.receive( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( mw_signedDataPayload ), + mw_signerIdentifier_digest + ))))))) -> value v_response { + var ToBeSignedCrl v_to_be_signed_crl; + + tc_ac.stop; + + if (f_verify_rca_crl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, true, v_to_be_signed_crl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_crl(v_to_be_signed_crl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedCrl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown_ca(); + + } // End of testcase TC_RCA_CRLGEN_01_BV + + } // End of group crl + + } // End of group ca_behavior + + group tlm_behavior { + + group ctl { + + /** + * @desc Check that the TLM generates the ECTL when new RootCA is about to be added + *
+       * Pics Selection: PICS_IUT_CA_ROLE
+       * Initial conditions: 
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the TLM is triggered to add new RootCA certificate (CERT_RCA) in the CTL
+       *         }
+       *         then {
+       *             the IUT issue a new CTL of type CtlFormat
+       *                 containing isFullCtl
+       *                     indicating TRUE
+       *                 and containing ctlCommands
+       *                     containing CtlCommand
+       *                         containing add
+       *                             containing rca
+       *                                 containing selfsignedRootCa
+       *                                     indicating CERT_RCA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP TLM_ECTLGEN_01_BV + * @reference ETSI TS 102 941, clause 6.3.1 + */ + testcase TC_TLM_ECTLGEN_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var Headers v_headers; + var HttpMessage v_response; + + // Test control + if (not PICS_IUT_CA_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfHttpUp_tlm(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "tlm_request", v_headers); + action("The TLM is triggered to add new RootCA certificate (CERT_RCA) in the CTL"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + f_http_send( + v_headers, + m_http_request( + m_http_request_get( + PICS_HTTP_GET_URI_ECTL, + 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_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( mw_signedDataPayload ), + - // Certificate or HasedId8 + ))))))) -> value v_response { + var ToBeSignedTlmCtl v_to_be_signed_tlm_ectl; + + tc_ac.stop; + + // FIXME Can not verify signature, to be checked + if (f_verify_tlm_ectl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, false, v_to_be_signed_tlm_ectl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ectl(v_to_be_signed_tlm_ectl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [PICS_MULTIPLE_END_POINT] httpTlmPort.receive( + mw_http_response( + mw_http_response_ok( + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( mw_signedDataPayload ), + - // Certificate or HasedId8 + ))))))) -> value v_response { + var ToBeSignedTlmCtl v_to_be_signed_tlm_ectl; + + tc_ac.stop; + + // FIXME Can not verify signature, to be checked + if (f_verify_tlm_ectl_response_message(v_response.response.body.binary_body.ieee1609dot2_data, false, v_to_be_signed_tlm_ectl) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ectl(v_to_be_signed_tlm_ectl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown_tlm(); + + } // End of testcase TC_TLM_ECTLGEN_01_BV + + } // End of group ctl + + } // End of group tlm_behavior + +} // End of module ItsPki_TestCases diff --git a/ItsPki_TestControl.ttcn b/ItsPki_TestControl.ttcn new file mode 100755 index 0000000..2bb00be --- /dev/null +++ b/ItsPki_TestControl.ttcn @@ -0,0 +1,101 @@ +module ItsPki_TestControl { + + // LibItsPki + import from LibItsPki_Pics all; + + // AtsPki + import from ItsPki_TestCases all; + + control { + + if (PICS_IUT_ITS_S_ROLE) { + if (PICS_SECPKI_ENROLMENT) { + execute(TC_SECPKI_ITSS_ENR_01_BV()); + execute(TC_SECPKI_ITSS_ENR_02_BV()); + if (PICS_SECPKI_REENROLMENT) { + execute(TC_SECPKI_ITSS_ENR_03_BV()); + execute(TC_SECPKI_ITSS_ENR_06_BV()); + execute(TC_SECPKI_ITSS_ENR_12_BV()); + } + if (PICS_SECPKI_CRL) { + execute(TC_SECPKI_ITSS_ENR_04_BV()) + } + execute(TC_SECPKI_ITSS_ENR_05_BV()); + execute(TC_SECPKI_ITSS_ENR_07_BV()); + execute(TC_SECPKI_ITSS_ENR_08_BV()); + execute(TC_SECPKI_ITSS_ENR_09_BV()); + execute(TC_SECPKI_ITSS_ENR_10_BV()); + execute(TC_SECPKI_ITSS_ENR_11_BV()); + + execute(TC_SECPKI_ITSS_ENR_RECV_01_BV()); + execute(TC_SECPKI_ITSS_ENR_RECV_02_BV()); + } + + if (PICS_SECPKI_AUTHORIZATION) { + // TODO + } + } + + if (PICS_IUT_EA_ROLE) { + execute(TC_SECPKI_EA_ENR_RCV_01_BV()); + execute(TC_SECPKI_EA_ENR_RCV_02_BI_01()); + execute(TC_SECPKI_EA_ENR_RCV_02_BI_02()); + execute(TC_SECPKI_EA_ENR_RCV_05_BI()); + execute(TC_SECPKI_EA_ENR_RCV_06_BI()); + execute(TC_SECPKI_EA_ENR_RCV_07_BI()); + execute(TC_SECPKI_EA_ENR_RCV_08_BI()); + execute(TC_SECPKI_EA_ENR_RCV_09_BI()); + execute(TC_SECPKI_EA_ENR_RCV_10_BI()); + execute(TC_SECPKI_EA_ENR_RCV_11_BI()); + execute(TC_SECPKI_EA_ENR_RCV_12_BI()); + execute(TC_SECPKI_EA_ENR_RCV_13_BI()); + + execute(TC_SECPKI_EA_ENR_01_BV()); + execute(TC_SECPKI_EA_ENR_02_BV()); + execute(TC_SECPKI_EA_ENR_03_BV()); + execute(TC_SECPKI_EA_ENR_04_BV()); + execute(TC_SECPKI_EA_ENR_05_BV()); + execute(TC_SECPKI_EA_ENR_06_BV()); + execute(TC_SECPKI_EA_ENR_07_BV()); + execute(TC_SECPKI_EA_ENR_08_BV()); + execute(TC_SECPKI_EA_ENR_09_BV()); + execute(TC_SECPKI_EA_ENR_10_BV()); + execute(TC_SECPKI_EA_ENR_11_BV()); + execute(TC_SECPKI_EA_ENR_12_BV()); + + execute(TC_SECPKI_EA_AUTHVAL_RCV_01_BV()); + execute(TC_SECPKI_EA_AUTHVAL_RCV_02_BI()); + } + + if (PICS_IUT_AA_ROLE) { + execute(TC_SECPKI_AA_AUTH_RCV_01_BV()); + if (PICS_PKI_AUTH_POP) { + execute(TC_SECPKI_AA_AUTH_RCV_02_BV()); + } + execute(TC_SECPKI_AA_AUTH_RCV_03_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_04_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_05_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_06_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_07_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_08_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_09_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_10_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_11_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_12_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_13_BI()); + execute(TC_SECPKI_AA_AUTH_RCV_14_BI()); + + execute(TC_SECPKI_AA_AUTHVAL_01_BV()); + } + + if (PICS_IUT_CA_ROLE) { + execute(TC_RCA_CTLGEN_01_BV()); + + execute(TC_RCA_CRLGEN_01_BV()); + + execute(TC_TLM_ECTLGEN_01_BV()); + } + + } // End of 'control' statement + +} // End of module module ItsPki_TestControl diff --git a/lib/LibItsPki_EncdecDeclarations.ttcn b/lib/LibItsPki_EncdecDeclarations.ttcn new file mode 100755 index 0000000..70257d4 --- /dev/null +++ b/lib/LibItsPki_EncdecDeclarations.ttcn @@ -0,0 +1,138 @@ +module LibItsPki_EncdecDeclarations { + + // LibIts + import from Ieee1609Dot2BaseTypes 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 EtsiTs103097Module language "ASN.1:1997" all; + + import from LibItsSecurity_TypesAndValues all; + + external function fx_enc_EtsiTs102941Data(in EtsiTs102941MessagesCa.EtsiTs102941Data p_etsi_ts_102941_data) return bitstring + with {extension "prototype(convert) encode(PER)"} + + + external function fx_dec_EtsiTs102941Data(inout bitstring b, out EtsiTs102941MessagesCa.EtsiTs102941Data p_etsi_ts_102941_data)return integer + with {extension "prototype(sliding) decode(PER)"} + + external function fx_enc_EtsiTs102941DataContent(in EtsiTs102941MessagesCa.EtsiTs102941DataContent p_etsi_ts_102941_data) return bitstring + with {extension "prototype(convert) encode(PER)"} + + + external function fx_dec_EtsiTs102941DataContent(inout bitstring b, out EtsiTs102941MessagesCa.EtsiTs102941DataContent p_etsi_ts_102941_data)return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesEnrolment InnerEcRequest + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_InnerEcRequest(in EtsiTs102941TypesEnrolment.InnerEcRequest p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_InnerEcRequest(inout bitstring b, out EtsiTs102941TypesEnrolment.InnerEcRequest p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesEnrolment InnerEcResponse + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_InnerEcResponse(in EtsiTs102941TypesEnrolment.InnerEcResponse p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_InnerEcResponse(inout bitstring b, out EtsiTs102941TypesEnrolment.InnerEcResponse p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesAuthorization InnerAtRequest + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_InnerAtRequest(in EtsiTs102941TypesAuthorization.InnerAtRequest p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_InnerAtRequest(inout bitstring b, out EtsiTs102941TypesAuthorization.InnerAtRequest p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesAuthorization InnerAtResponse + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_InnerAtResponse(in EtsiTs102941TypesAuthorization.InnerAtResponse p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_InnerAtResponse(inout bitstring b, out EtsiTs102941TypesAuthorization.InnerAtResponse p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesAuthorization SharedAtRequest + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_SharedAtRequest(in EtsiTs102941TypesAuthorization.SharedAtRequest p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_SharedAtRequest(inout bitstring b, out EtsiTs102941TypesAuthorization.SharedAtRequest p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesAuthorizationValidation AuthorizationValidationRequest + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_AuthorizationValidationRequest(in EtsiTs102941TypesAuthorizationValidation.AuthorizationValidationRequest p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_AuthorizationValidationRequest(inout bitstring b, out EtsiTs102941TypesAuthorizationValidation.AuthorizationValidationRequest p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941TypesAuthorizationValidation AuthorizationValidationResponse + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_AuthorizationValidationResponse(in EtsiTs102941TypesAuthorizationValidation.AuthorizationValidationResponse p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_AuthorizationValidationResponse(inout bitstring b, out EtsiTs102941TypesAuthorizationValidation.AuthorizationValidationResponse p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for EtsiTs102941BaseTypes PublicKeys + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_PublicKeys(in EtsiTs102941BaseTypes.PublicKeys p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_PublicKeys(inout bitstring b, out EtsiTs102941BaseTypes.PublicKeys p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for Ieee1609Dot2BaseTypes PublicVerificationKey + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_PublicVerificationKey(in Ieee1609Dot2BaseTypes.PublicVerificationKey p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_PublicVerificationKey(inout bitstring b, out Ieee1609Dot2BaseTypes.PublicVerificationKey p) return integer + with {extension "prototype(sliding) decode(PER)"} + + /** + * @desc Encoding function for Ieee1609Dot2BaseTypes PublicEncryptionKey + * @param p The certificate to encode + * @return The encode message in OER format + */ + external function fx_enc_PublicEncryptionKey(in Ieee1609Dot2BaseTypes.PublicEncryptionKey p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_PublicEncryptionKey(inout bitstring b, out Ieee1609Dot2BaseTypes.PublicEncryptionKey p) return integer + with {extension "prototype(sliding) decode(PER)"} + +} // End of module LibItsPki_EncdecDeclarations diff --git a/lib/LibItsPki_Functions.ttcn b/lib/LibItsPki_Functions.ttcn new file mode 100755 index 0000000..9dbe69b --- /dev/null +++ b/lib/LibItsPki_Functions.ttcn @@ -0,0 +1,4856 @@ +/** + * @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; + + // 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 ITS_Container 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; + + // LibItsHttp + import from LibItsHttp_TypesAndValues all; + import from LibItsHttp_Templates all; + import from LibItsHttp_BinaryTemplates all; + import from LibItsHttp_Functions all; + import from LibItsHttp_TestSystem 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 + + /** + * @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_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 { + + 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 { + + 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: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_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_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( + in charstring p_certificate_id := "CERT_TS_A_EA" // TODO Use a constant + ) 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; + } + + /** + * @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: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 { + // Local variables + + // Load certificates + if(not(f_loadCertificates(PX_IUT_SEC_CONFIG_NAME))) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + setverdict(inconc); + stop; + } + + // f_prepareCertificates(p_certificate_id, vc_aaCertificate, vc_atCertificate); + } // 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 + ) 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; + } + + 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; + alt { + [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { + tc_ac.stop; + } + [] utPort.receive(UtPkiResults: { utPkiTriggerResult := false }) { + tc_ac.stop; + log("*** f_sendUtTriggerEnrolmentRequestPrimitive: ERROR: Received unexpected message ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + [] 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_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); + } + [] 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 + + } // End of group ut_port + + group helpers { + + 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_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 { + // error + return false; + } + + log("<<< f_generate_key_pair: p_compressed_mode=", p_compressed_mode); + return true; + } + + function f_generate_key_pair_for_encryption( + in SecurityAlg 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 { + // error + return false; + } + + return true; + } + + function f_signWithEcdsa( + in octetstring p_toBeSignedSecuredMessage, + in octetstring p_certificateIssuer, + in octetstring p_privateKey + ) return octetstring { + log(">>> f_verifyEcdsa: p_toBeSignedSecuredMessage= ", p_toBeSignedSecuredMessage); + log(">>> f_verifyEcdsa: p_certificateIssuer= ", p_certificateIssuer); + log(">>> f_verifyEcdsa: p_privateKey= ", p_privateKey); + log(">>> f_verifyEcdsa: PX_VE_ALG= ", PX_VE_ALG); + + if (PX_VE_ALG == e_nist_p256) { + return f_signWithEcdsaNistp256WithSha256(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey); + } else if (PX_VE_ALG == e_brainpool_p256_r1) { + return f_signWithEcdsaBrainpoolp256r1WithSha256(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey); + } else if (PX_VE_ALG == e_brainpool_p384_r1) { + if (p_certificateIssuer == int2oct(0, 32)) { + return f_signWithEcdsaBrainpoolp384r1WithSha384(p_toBeSignedSecuredMessage, int2oct(0, 48), p_privateKey); + } else { + return f_signWithEcdsaBrainpoolp384r1WithSha384(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey); + } + } + + return ''O; + } // End of function f_signWithEcdsa + + function f_verifyEcdsa( + in octetstring p_tbs, + in octetstring p_issuer, + in Signature p_signature_, + in PublicVerificationKey p_verification_key + ) return boolean { + var boolean v_ret := false; + + log(">>> f_verifyEcdsa: p_tbs= ", p_tbs); + log(">>> f_verifyEcdsa: p_issuer= ", p_issuer); + log(">>> f_verifyEcdsa: p_signature_= ", p_signature_); + log(">>> f_verifyEcdsa: p_verification_key= ", p_verification_key); + + if (ischosen(p_verification_key.ecdsaNistP256)) { + if (ischosen(p_verification_key.ecdsaNistP256.compressed_y_0)) { + v_ret := f_verifyWithEcdsaNistp256WithSha256( + p_tbs, + p_issuer, + p_signature_.ecdsaNistP256Signature.rSig.x_only & p_signature_.ecdsaNistP256Signature.sSig, + p_verification_key.ecdsaNistP256.compressed_y_0, + 0); + } else { + v_ret := f_verifyWithEcdsaNistp256WithSha256( + p_tbs, + p_issuer, + p_signature_.ecdsaNistP256Signature.rSig.x_only & p_signature_.ecdsaNistP256Signature.sSig, + p_verification_key.ecdsaNistP256.compressed_y_1, + 1); + } + } else if (ischosen(p_verification_key.ecdsaBrainpoolP256r1)) { + if (ischosen(p_verification_key.ecdsaBrainpoolP256r1.compressed_y_0)) { + v_ret := f_verifyWithEcdsaBrainpoolp256r1WithSha256( + p_tbs, + p_issuer, + p_signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP256r1Signature.sSig, + p_verification_key.ecdsaBrainpoolP256r1.compressed_y_0, + 0); + } else { + v_ret := f_verifyWithEcdsaBrainpoolp256r1WithSha256( + p_tbs, + p_issuer, + p_signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP256r1Signature.sSig, + p_verification_key.ecdsaBrainpoolP256r1.compressed_y_1, + 1); + } + } else if (ischosen(p_verification_key.ecdsaBrainpoolP384r1)) { + if (ischosen(p_verification_key.ecdsaBrainpoolP384r1.compressed_y_0)) { + v_ret := f_verifyWithEcdsaBrainpoolp384r1WithSha384( + p_tbs, + p_issuer, + p_signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP384r1Signature.sSig, + p_verification_key.ecdsaBrainpoolP384r1.compressed_y_0, + 0); + } else { + v_ret := f_verifyWithEcdsaBrainpoolp384r1WithSha384( + p_tbs, + p_issuer, + p_signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP384r1Signature.sSig, + p_verification_key.ecdsaBrainpoolP384r1.compressed_y_1, + 1); + } + } + + return v_ret; + } // End of function f_verifyEcdsa + + 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_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 == { "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 == { "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 { + 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 { + 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 + + 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"); + 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); + // TODO 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. + 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 { + 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: ", PX_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(PX_EC_HASHED_ID8)), PX_EC_HASHED_ID8/*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. + if (PICS_SECPKI_REENROLMENT == false) { // 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 { + 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_with_wrong_parameters: v_ec_private_key: ", PX_EC_PRIVATE_KEY); + log("f_http_build_inner_ec_request_with_wrong_parameters: v_ec_hashed_id8: ", PX_EC_HASHED_ID8); + v_result := f_build_pki_secured_request_message_signed_with_pop(PX_EC_PRIVATE_KEY, valueof(m_signerIdentifier_digest(PX_EC_HASHED_ID8)), PX_EC_HASHED_ID8/*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; + + 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 (PICS_SECPKI_REENROLMENT == false) { // 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 { + 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); + } 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: ", PX_EC_PRIVATE_KEY); + log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", PX_EC_HASHED_ID8); + v_ret_code := f_build_pki_secured_request_message_signed_with_pop(PX_EC_PRIVATE_KEY, valueof(m_signerIdentifier_digest(PX_EC_HASHED_ID8)), PX_EC_HASHED_ID8/*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 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 EtsiTs103097Certificate v_ec_certificate; + 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, v_ec_certificate) == 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, + v_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_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 { + // 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + return; + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } + 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); + } // 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 { + // 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + return; + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } + 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); + } // 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 { + // 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + return; + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } 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 ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + } + 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); + } // 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 p_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 + ) + ); + p_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 { + p_result := true; + } + + log("<<< f_http_build_authorization_response: p_result= ", p_result); + log("<<< f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response); + return p_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 { + // 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"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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); + } // 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 { + // 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"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + 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); + } // 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 EtsiTs103097Certificate v_at_certificate; + var boolean p_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 + ) + ); + p_result := true; + } else { + p_authorization_validation_response := valueof(m_authorizationValidationResponse_ok( + p_request_hash, + p_shared_at_request.requestedSubjectAttributes + ) + ); + } + + // Secure the response + log("f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response); + v_msg := bit2oct(encvalue(p_authorization_validation_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_validation_response: Failed to generate the certificate"); + p_authorization_validation_response := valueof( + m_authorizationValidationResponse_ko( + p_request_hash, + deniedpermissions + ) + ); + } else { + p_result := true; + } + + log("<<< f_http_build_authorization_validation_response: p_result= ", p_result); + log("<<< f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response); + return p_result; + } // End of function f_http_build_authorization_validation_response + + 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_brainpool_p256_r1) { + v_public_verification_key := valueof( + m_publicVerificationKey_ecdsaBrainpoolP256r1( + v_ecc_p256_curve_point + )); + } 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) or (PX_VE_ALG == e_brainpool_p256_r1)) { + 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_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 + ) return boolean { + var CertificateId v_certificate_id; + var EtsiTs103097Certificate v_cert; + var IssuerIdentifier v_issuer; + var bitstring v_tbs; + var octetstring v_sig; + + 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; + } + 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 + ), + p_inner_ec_request.requestedSubjectAttributes.validityPeriod, + 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_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) + ) + ) + ); + } + p_ec_certificate := valueof(v_cert); + log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate= ", p_ec_certificate); + + 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_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) + ) + ) + ); + } + p_at_certificate := valueof(v_cert); + log("f_generate_at_certificate_for_inner_at_response: p_ec_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_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) + ) + ) + ); + } + 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 + ) 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 { + 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 + ) + ) + ); + } + if (PICS_SECPKI_REENROLMENT) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential + log("f_generate_inner_ec_request: This is a re-enrolment"); + p_inner_ec_request.itsId := PX_EC_HASHED_ID8; + } + 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 + ) 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 { + 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)); + } + 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 + ) + ) + ); + if (PICS_SECPKI_REENROLMENT) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential + log("f_generate_inner_ec_request_with_wrong_parameters: This is a re-enrolment"); + p_inner_ec_request.itsId := PX_EC_HASHED_ID8; + } + 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 + ) 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_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_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 SecurityAlg 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.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 { + 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 { + 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 { // 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 { + 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 SecurityAlg 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 { + 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 { + 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 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 authorization_validation_xxx { + + } // End of group authorization_validation_xxx + + group dc { + + function f_build_dc_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 EtsiTs103097Certificate v_rca_certificate; + var CtlCommands v_ctl_commands; + var ToBeSignedRcaCtl v_to_be_signed_rca_ctl; + + log(">>> f_build_dc_ctl"); + + // Load certificates + f_readCertificate(p_ea_certificate_id, v_ea_certificate); + f_readCertificate(p_aa_certificate_id, v_aa_certificate); + f_readCertificate(p_rca_certificate_id, v_rca_certificate); + // Create ctrlCommnand list + v_ctl_commands := { + { add := { rca := valueof(m_root_ca_entry(v_rca_certificate)) } }, + { add := { aa := valueof(m_aa_entry(v_aa_certificate, "http://www.etsi.org")) } }, + { add := { ea := valueof(m_ea_entry(v_ea_certificate, "http://www.etsi.org")) } } + }; + log("f_build_dc_ctl: v_ctl_commands= ", v_ctl_commands); + // Build the main data structure + p_to_be_signed_rca_ctl := valueof(m_to_be_signed_rca_full_ctl(1000, 1, v_ctl_commands)); + + log("<<< f_build_dc_ctl: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl); + } // End of function f_build_dc_ctl + + function f_sign_dc_ctl( + in charstring p_issuer_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_issuer_certificate_id, v_private_key); + f_getCertificateHash(p_issuer_certificate_id, v_issuer); + + // 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_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) or (PX_VE_ALG == e_brainpool_p256_r1)) { + v_signature := valueof( + m_signature_ecdsaNistP256( + m_ecdsaP256Signature( + m_eccP256CurvePoint_x_only( + substr(v_sig, 0, 32) + ), + substr(v_sig, 32, 32) + ) + )); + p_ieee_1609Dot2_signed_data := valueof( + m_etsiTs103097Data_signed( + m_signedData( + sha256, + v_tbs, + m_signerIdentifier_digest(v_issuer), + v_signature + ) + ) + ); + } 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) + ) + )); + p_ieee_1609Dot2_signed_data := valueof( + m_etsiTs103097Data_signed( + m_signedData( + sha384, + v_tbs, + m_signerIdentifier_digest(v_issuer), + v_signature + ) + ) + ); + } + log("<<< f_sign_dc_ctl: p_ieee_1609Dot2_signed_data= ", p_ieee_1609Dot2_signed_data); + } // End of function f_sign_dc_ctl + + } // End of group dc + + group rca { + + 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 (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; + } + } + 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_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; + } + + 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; + } + + 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; + } + + 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_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; + } + + 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; + } + + } // End of group rca + + group tlm { + + 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; + } + + } // End of group tlm + + group awaiting_messages { + + function f_await_http_inner_ec_request_response( + out Oct32 p_private_key, + out Oct32 p_compressed_public_key, + out integer p_compressed_mode, + out InnerEcResponse p_inner_ec_response, + in boolean p_strict_checks := true + ) 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, 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, 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) == false) { + log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***"); + if (p_strict_checks) { + return false; + } + } + 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("p_inner_ec_response= ", p_inner_ec_response); + } 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 + + function f_await_ec_request_send_response( + out InnerEcResponse p_inner_ec_response + ) runs on ItsPkiHttp return boolean { + var HttpMessage v_request; + var boolean v_result := false; + + log(">>> f_await_ec_request_send_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 + )))))), + v_request + ) { + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_request_hash; + var Oct16 v_aes_enc_key; + var InnerEcRequest v_inner_ec_request; + var template (value) HttpMessage v_response; + var Headers v_headers; + + tc_ac.stop; + + f_init_default_headers_list(-, "inner_ec_response", v_headers); + + if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, v_request.request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message + log("f_await_ec_request_send_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 + } else { + log("f_await_ec_request_send_response: Receive ", v_etsi_ts_102941_data, " ***"); + if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, v_inner_ec_request) == false) { + log("f_await_ec_request_send_response: Failed to verify PKI message ***"); + // Send error message + f_http_build_inner_ec_response(v_inner_ec_request/*Not required*/, cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers)); + } else { + f_http_build_inner_ec_response(v_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers)); + v_result := true; + } + f_http_send(v_headers, v_response); + } + } + [] 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_dc_request_send_response( + in charstring p_rca_certificate_id, + in charstring p_aa_certificate_id, + in charstring p_ea_certificate_id, + out ToBeSignedRcaCtl p_ctl + ) runs on ItsPkiHttp return boolean { + var HttpMessage v_request; + var boolean v_result := false; + + log(">>> f_await_dc_request_send_response"); + + tc_ac.start; + alt { + [] a_await_dc_http_request_from_iut( + mw_http_request( + mw_http_request_post( + PICS_HTTP_POST_URI_DC + )), + v_request + ) { + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var ToBeSignedRcaCtl p_to_be_signed_rca_ctl; + var EtsiTs102941Data v_etsi_ts_102941_data; + var Oct16 v_request_hash; + var Oct16 v_aes_enc_key; + var template (value) HttpMessage v_response; + var Headers v_headers; + tc_ac.stop; + + f_init_default_headers_list(-, "inner_dc_response", v_headers); + + // Send message + f_build_dc_ctl( + p_rca_certificate_id, + p_aa_certificate_id, + p_ea_certificate_id, + p_to_be_signed_rca_ctl + ); + f_sign_dc_ctl(p_rca_certificate_id, p_to_be_signed_rca_ctl, v_ieee1609dot2_signed_and_encrypted_data); + v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers)); + f_http_send(v_headers, v_response); + v_result := true; + } + [] tc_ac.timeout { + log("f_await_dc_request_send_response: Expected message not received ***"); + } + } // End of 'alt' statement + + return v_result; + } // End of function f_await_dc_request_send_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 SecurityAlg 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; + // FIXME Huge issue, certificate is BP256 and PX_VE_ALG is e_brainpool_p384_r1, so v_hash & p_private_key are 32 bytes length not 48 + // ==> Need to sign with v_certificate_id capabilities not with PX_VE_ALG :( + 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_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 (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 (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 SecurityAlg 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 (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 (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 SecurityAlg 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_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 (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; + + // 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 + 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_recipientId := f_hashedId8FromSha256(f_hashWithSha256(p_aes_sym_key)); + 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 + + /** + * @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, + in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data, + in boolean p_check_security := true, + out Oct16 p_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 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= ", p_issuer); + 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); + p_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); + 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)); + log("f_verify_pki_request_message: v_msg= ", v_msg); + if (p_issuer == ''O) { // self + log("f_verify_pki_request_message: Issuer is self, check outer signature using IUT public key (PICS_ITS_S_SIGN_xxx_PUBLIC_KEY)"); + var PublicVerificationKey v_verification_key; + + log("f_verify_pki_request_message: PX_VE_ALG=", PX_VE_ALG); + if (PX_VE_ALG == e_nist_p256) { + if (PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY[0] == '02'O) { + v_verification_key.ecdsaNistP256.compressed_y_0 := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); + } else { + v_verification_key.ecdsaNistP256.compressed_y_1 := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); + } + } else if (PX_VE_ALG == e_brainpool_p256_r1) { + if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '02'O) { + v_verification_key.ecdsaBrainpoolP256r1.compressed_y_0 := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); + } else { + v_verification_key.ecdsaBrainpoolP256r1.compressed_y_1 := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); + } + } else if (PX_VE_ALG == e_brainpool_p384_r1) { + if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '02'O) { + v_verification_key.ecdsaBrainpoolP384r1.compressed_y_0 := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); + } else { + v_verification_key.ecdsaBrainpoolP384r1.compressed_y_1 := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); + } + } + log("f_verify_pki_request_message: v_verification_key=", v_verification_key); + if (f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_signed_data.content.signedData.signature_, v_verification_key) == false) { + if (p_check_security == true) { + return false; + } + } + //return false; + } else { + if (f_getCertificateFromDigest(f_hashedId8FromSha256(p_issuer), v_certificate, v_certificate_id) == false) { + if (p_check_security == true) { + return false; + } + } + log("f_verify_pki_request_message: v_certificate= ", v_certificate); + if (f_verifyEcdsa(v_msg, p_issuer, v_ieee1609dot2_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { + if (p_check_security == true) { + return false; + } + } + } + + // 4. 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_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 + + /** + * @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 + ) return boolean { + var bitstring v_encoded_cert; + var Oct32 v_ec_cert_hash; + var HashedId8 v_ec_cert_hashed_id8; + + // Calculate the HashedId8 of the whole certificate + v_encoded_cert := encvalue(p_ec_certificate); + v_ec_cert_hash := f_hashWithSha256(bit2oct(v_encoded_cert)); + log("f_verify_ec_certificate: ==> EC certificate Hash: ", v_ec_cert_hash); + v_ec_cert_hashed_id8 := f_hashedId8FromSha256(v_ec_cert_hash); + log("f_verify_ec_certificate: ==> EC certificate HashedId8: ", v_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_ec_certificate: Ssp permissions not verified"); + return false; + } + + return true; + } // End of function f_verify_at_certificate + + } // End of group inner_ec_xxx + + group security_function { // TODO To be moved in LibItsSecurity_Function module + + function f_extract_enc_key( + in Certificate p_certificate, + out octetstring p_public_enc_key, + out integer p_compressed_enc_key_mode + ) return boolean { + log(">>> f_extract_enc_key: ", p_certificate); + + if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256)) { + if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { + p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0; + p_compressed_enc_key_mode := 0; + } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) { + p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1; + p_compressed_enc_key_mode := 1; + } else { + log("f_extract_enc_key: Non canonical certificate: ", p_certificate); + return false; + } + } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1)) { + if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) { + p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0; + p_compressed_enc_key_mode := 0; + } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) { + p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1; + p_compressed_enc_key_mode := 0; + } else { + log("f_extract_enc_key: Non canonical certificate: ", p_certificate); + return false; + } + } else { + log("f_extract_enc_key: Invalid certificate: ", p_certificate); + return false; + } + + return true; + } // End of function f_extract_enc_key + + } // End of group security_function + + 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_response + ) runs on ItsPkiHttp { + [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response { + log("a_await_ec_http_request_from_iut: Received message on httpPort"); + } + [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_response { + 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_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_response + ) runs on ItsPkiHttp { + [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response { + log("a_await_dc_http_request_from_iut: Received message on httpPort"); + } + [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_response { + log("a_await_dc_http_request_from_iut: Received message on httpEcPort"); + } + } // End of altstep a_await_dc_http_request_from_iut + + } // End of group altsteps + +} // End of module LibItsPki_Functions diff --git a/lib/LibItsPki_Pics.ttcn b/lib/LibItsPki_Pics.ttcn new file mode 100755 index 0000000..8c683b8 --- /dev/null +++ b/lib/LibItsPki_Pics.ttcn @@ -0,0 +1,250 @@ +module LibItsPki_Pics { + + /** + * @desc Does the IUT act as ITS-S device? + */ + modulepar boolean PICS_IUT_ITS_S_ROLE := false; + + /** + * @desc Does the IUT act as EA device? + */ + modulepar boolean PICS_IUT_EA_ROLE := true; + + /** + * @desc Does the IUT act as AA device? + */ + modulepar boolean PICS_IUT_AA_ROLE := true; + + /** + * @desc Does the IUT act as CA device? + */ + modulepar boolean PICS_IUT_CA_ROLE := true; + + /** + * @desc Does the IUT act as TLM device? + */ + modulepar boolean PICS_IUT_TLM_ROLE := true; + + /** + * @desc Does the IUT support enrolment? + */ + modulepar boolean PICS_SECPKI_ENROLMENT := true; + + /** + * @desc Does the IUT support autorization? + */ + modulepar boolean PICS_SECPKI_AUTHORIZATION := true; + + /** + * @desc Is a re-enrolment request? + */ + modulepar boolean PICS_SECPKI_REENROLMENT := false; + + /** + * @desc ? + */ + modulepar boolean PICS_SECPKI_CRL := false; + + /** + * @desc Do the Authorization Request use SignedWithPop mechanism? + */ + modulepar boolean PICS_PKI_AUTH_POP := true; + + /** + * @desc Certificate used by the IUT acting as ITS-S + */ + modulepar charstring PICS_IUT_CERTIFICATE_ID := "CERT_IUT_A_AT"; + + /** + * @desc Certificate used by the IUT acting as EA + */ + modulepar charstring PICS_IUT_EA_CERTIFICATE_ID := "CERT_IUT_A_EA"; + + /** + * @desc Certificate used by the IUT acting as AA + */ + modulepar charstring PICS_IUT_AA_CERTIFICATE_ID := "CERT_IUT_A_AA"; + + /** + * @desc Certificate used by the IUT acting as AA + */ + modulepar charstring PICS_IUT_CA_CERTIFICATE_ID := "CERT_IUT_A_RCA"; + + /** + * @desc Certificate used by the Test System acting as ITS-S + */ + modulepar charstring PICS_TS_CERTIFICATE_ID := "CERT_TS_A_AT"; + + /** + * @desc Certificate used by the Test System acting as EA + */ + modulepar charstring PICS_TS_EA_CERTIFICATE_ID := "CERT_TS_A_EA"; + + /** + * @desc Certificate used by the Test System acting as AA + */ + modulepar charstring PICS_TS_AA_CERTIFICATE_ID := "CERT_TS_A_AA"; + + /** + * @desc Certificate used by the Test System acting as EA + */ + modulepar charstring PICS_TS_CA_CERTIFICATE_ID := "CERT_TS_RCA_A"; + + /** + * @desc Set to true if different end points are used for EC and AT + */ + modulepar boolean PICS_MULTIPLE_END_POINT := false; + + /** + * @desc End point for the enrolment + */ + modulepar charstring PICS_HEADER_HOST_EC := "www.its.ec.org"; + + /** + * @desc End point for the authorization validation + */ + modulepar charstring PICS_HEADER_HOST_ATV := "www.its.atv.org"; + + /** + * @desc End point for the authorization + */ + modulepar charstring PICS_HEADER_HOST_AT := "www.its.at.org"; + + /** + * @desc End point for the CA + */ + modulepar charstring PICS_HEADER_HOST_CA := "www.its.ca.org"; + + /** + * @desc End point for the TLM + */ + modulepar charstring PICS_HEADER_HOST_TLM := "www.its.tlm.org"; + + /** + * @desc + */ + modulepar charstring PICS_HTTP_POST_URI_DC := "www.its.ec.org"; + + /** + * @desc Certificate used by the Test System + */ + modulepar charstring PICS_HTTP_POST_URI := "/its/inner_ec_request"; + + /** + * @desc ITS-S with privacy + */ + modulepar boolean PICS_ITS_S_WITH_PRIVACY := true; + + /** + * @desc Set to true if the PKI configuration authorize to configure an external EA entity + */ + + modulepar boolean PICS_SIMULATE_EA_ENTITY := false; + + /** + * @desc Set to true if the PKI configuration authorize to configure an external AA entity + */ + modulepar boolean PICS_SIMULATE_AA_ENTITY := false; + + /** + * @desc HTTP POST URI for InnerECRequest + */ + modulepar charstring PICS_HTTP_POST_URI_EC := "/enrolment"; + + /** + * @desc HTTP POST URI for InnerATRequest + */ + modulepar charstring PICS_HTTP_POST_URI_AT := "/authorize"; + + /** + * @desc HTTP POST URI for authorization validation + */ + modulepar charstring PICS_HTTP_POST_URI_ATV := "/authorize_validate"; + + /** + * @desc HTTP GET URI for Certificate Trusted List + */ + modulepar charstring PICS_HTTP_GET_URI_CTL := "/dc/getctl"; + + /** + * @desc HTTP GET URI for Certificate Trusted List + */ + modulepar charstring PICS_HTTP_GET_URI_CRL := "/dc/getcrl"; + + /** + * @desc HTTP GET URI for Certificate Trusted List + */ + modulepar charstring PICS_HTTP_GET_URI_ECTL := "/tlm/getectl"; + + /** + * @desc Factory private key for verification Nist P256 + */ + modulepar octetstring PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY := '5C25F97607DFC62972A147FAD8B7A7C939569F0F95ECD4C641724A68B51836E5'O; + + /** + * @desc Factory compressed public key for verification Nist P256 + */ + modulepar octetstring PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY := '020144E5174B0AFDA86BDB8B643B68D40030F5BDB9A9F090C64852CC3C20C9D5AD'O; + + /** + * @desc Factory private key for encryption Nist P256 + */ + modulepar octetstring PICS_ITS_S_ENC_NITSP256_PRIVATE_KEY := 'EDEBEADCAA9514CD4B30256126FB7DF958B911C6EB58CCF702983C3DCD3DECBD'O; + + /** + * @desc Factory compressed public key for encryption Nist P256 + */ + modulepar octetstring PICS_ITS_S_ENC_NISTP256_PUBLIC_KEY := '023A4ADDCDD5EE66DAB2116B0C3AB47CCEDAE92CD9ACE98A84B10EB63A9DCA798C'O; + + /** + * @desc Factory private key for encryption Brainpool P256 r1 + */ + modulepar octetstring PICS_ITS_S_ENC_BRAINPOOLP256r1_PRIVATE_KEY := '9F155D40B6C920BA45D8027093C8ADADAF3AA6F9F71F0CC0F8279FF0146A8A48'O; + + /** + * @desc Factory compressed public key for encryption Brainpool P256 r1 + */ + modulepar octetstring PICS_ITS_S_ENC_BRAINPOOLP256r1_PUBLIC_KEY := '038602F468BD334EA4D2BA416295E204D58BD1F42C85FB9BE57237C74544F6A69A'O; + + /** + * @desc Factory private key for verification Brainpool P256 r1 + */ + modulepar octetstring PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY := '2CCBC88C6AD0FBB78AE50DA63366E64445F069369CED4605485442F524A0791E'O; + + /** + * @desc Factory compressed public key for verification Brainpool P256 r1 + */ + modulepar octetstring PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY := '02A7A21F8FEE8DF454B7AF80A7C78CBC506C16F491C72BDC54F0CE98F20C15C59B'O; + + /** + * @desc Factory private key for encryption Brainpool P384 r1 + */ + modulepar octetstring PICS_ITS_S_ENC_BRAINPOOLP384r1_PRIVATE_KEY := '6B4B4392511B252C904801466F5DA0A7F28E038E6656800CBB0CDCB3D32F862CA4D59CBDC1A19E98E9191582AF1DB3D7'O; + + /** + * @desc Factory private key for verification Brainpool P384 r1 + */ + modulepar octetstring PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY := '0F94E957F915B39E545FE845A8B4681D52F9D144353FFE36879F3DC9AFDE4001EDE55D5234EB977425E44D95BD6D3328'O; + + /** + * @desc Factory compressed public key for verification Brainpool P384 r1 + */ + modulepar octetstring PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY := '0210E2B13DCC736F22A1E9C6E156177BD0CB106D34897EF8D596CF3A7AC4034003AD2BB3FA4F65C723F665BEF089858C4F'O; + + /** + * @desc Canonical ITSS-S identifier + */ + modulepar octetstring PICS_ITS_S_CANONICAL_ID := '455453492D4954532D303031'O; + + /** + * @desc Invalid Canonical ITSS-S identifier + */ + modulepar octetstring PICS_INVALID_ITS_S_CANONICAL_ID := '455453492D4954532D30303145454545'O; + + /** + * @desc Set to true if the IUT support CertificateId shall be set to the choice name + * @see ETSI TS 103 097 Clause 7.2.2 Enrolment credential + */ + modulepar boolean PICS_EC_SUBJECT_ATTRIBUT_ID := false; + +} // End of module LibItsPki_Pics diff --git a/lib/LibItsPki_Pixits.ttcn b/lib/LibItsPki_Pixits.ttcn new file mode 100755 index 0000000..b9c8ecd --- /dev/null +++ b/lib/LibItsPki_Pixits.ttcn @@ -0,0 +1,79 @@ +module LibItsPki_Pixits { + + // LibCommon + import from LibCommon_BasicTypesAndValues all; + import from LibCommon_DataStrings all; + + // LibIts + import from Ieee1609Dot2BaseTypes language "ASN.1:1997" all; + + // LibItsPki + import from LibItsPki_TypesAndValues all; + + /** + * @desc Do the encryption keys be included in Authorization Request? + */ + modulepar boolean PX_INCLUDE_ENCRYPTION_KEYS := true; + + /** + * @desc Contains the private key for the EC certificate, used in case of re-enrolment + */ + modulepar Oct32 PX_EC_PRIVATE_KEY := int2oct(0, 32); + + /** + * @desc Contains the hashed id8 of the EC certificate, used in case of re-enrolment + */ + modulepar HashedId8 PX_EC_HASHED_ID8 := int2oct(0, 8); + + /** + * @desc Contains the hash of the EC certificate, used in case of re-enrolment + */ + modulepar Oct32 PX_EC_HASH := int2oct(0, 32); + + /** + * @desc Indicate which encryption algorithem to be used for Enrolment Credencial + */ + modulepar SecurityAlg PX_EC_ALG_FOR_EC := e_nist_p256; // TODO Use RCA to determine encryption algorithm? + /** + * @desc Indicate which encryption algorithem to be used for Authorization Request (AA certificate of the IUT) + */ + modulepar SecurityAlg PX_EC_ALG_FOR_AT := e_nist_p256; + /** + * @desc Indicate which encryption algorithem to be used for Authorization Validation Request (EA certificate of the IUT) + */ + modulepar SecurityAlg PX_EC_ALG_FOR_ATV := e_nist_p256; + /** + * @desc Indicate which encryption algorithem to be used for EcSignature (EA certificate of the IUT) + */ + modulepar SecurityAlg PX_EC_ALG_FOR_EC_SIGN := e_nist_p256; + + /** + * @desc Indicate which verification algorithem to be used + */ + modulepar SecurityAlg PX_VE_ALG := e_nist_p256; + + modulepar Int16 PX_GENERATED_CERTIFICATE_DURATION := 120; + + modulepar SubjectAssurance PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL := '00'O; + + modulepar CountryOnly PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1 := 250; + + modulepar CountryOnly PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2 := 380; + + modulepar octetstring PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR := '01C0'O; + + modulepar octetstring PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR := '01FF'O; + + modulepar octetstring PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR_WRONG_VERSION := '00C0'O; + + modulepar octetstring PX_INNER_EC_CERTFICATE_INCORRECT_BITMAP_SSP_SCR_WRONG_SSP_BIT := '0180'O; + + modulepar octetstring PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM := '830001'O; + + modulepar octetstring PX_INNER_EC_CERTFICATE_BITMAP_SSP_DENM := '830001'O; + + modulepar octetstring PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM := '01FFFC'O; + + modulepar octetstring PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM := '01FFFFFF'O; + +} // End of module LibItsPki_Pixits diff --git a/lib/LibItsPki_Templates.ttcn b/lib/LibItsPki_Templates.ttcn new file mode 100755 index 0000000..b24a2b7 --- /dev/null +++ b/lib/LibItsPki_Templates.ttcn @@ -0,0 +1,671 @@ +/** + * @author ETSI / STF545 + * @version $Url$ + * $Id$ + * @desc Module containing templates for IT PKI Protocol + * @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_Templates { + + // LibCommon + import from LibCommon_BasicTypesAndValues all; + import from LibCommon_DataStrings all; + + // LibItsCommon + import from LibItsCommon_TypesAndValues all; + import from LibItsCommon_Functions all; + import from LibItsCommon_TypesAndValues all; + import from LibItsCommon_ASN1_NamedNumbers 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; + + // LibItsSecurity + import from LibItsSecurity_TypesAndValues all; + import from LibItsSecurity_Templates all; + + // LibItsPki + import from LibItsPki_TypesAndValues all; + + template (value) EtsiTs102941Data m_etsiTs102941Data_inner_ec_request_signed_for_pop( + in template (value) InnerEcRequestSignedForPop p_inner_ec_request_signed_for_pop + ) := { + version := PkiProtocolVersion, + content := { + enrolmentRequest := p_inner_ec_request_signed_for_pop + } + } // End of template m_etsiTs102941Data_inner_ec_request_signed_for_pop + + template (value) EtsiTs102941Data m_etsiTs102941Data_inner_ec_response( + in template (value) InnerEcResponse p_inner_ec_response + ) := { + version := PkiProtocolVersion, + content := { + enrolmentResponse := p_inner_ec_response + } + } // End of template m_etsiTs102941Data_inner_ec_response + + template (value) EtsiTs102941Data m_etsiTs102941Data_inner_at_response( + in template (value) InnerAtResponse p_inner_at_response + ) := { + version := PkiProtocolVersion, + content := { + authorizationResponse := p_inner_at_response + } + } // End of template m_etsiTs102941Data_inner_at_response + + template (present) EtsiTs102941Data mw_etsiTs102941Data_inner_ec_response( + template (present) InnerEcResponse p_inner_ec_response := ? + ) := { + version := PkiProtocolVersion, + content := { + enrolmentResponse := p_inner_ec_response + } + } // End of template mw_etsiTs102941Data_inner_ec_response + + template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_request( + in template (value) InnerAtRequest p_inner_at_request + ) := { + version := PkiProtocolVersion, + content := { + authorizationRequest := p_inner_at_request + } + } // End of template m_etsiTs102941Data_authorization_request + + template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_response( + in template (value) InnerAtResponse p_inner_at_response + ) := { + version := PkiProtocolVersion, + content := { + authorizationResponse := p_inner_at_response + } + } // End of template m_etsiTs102941Data_authorization_response + + template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_validation_request( + in template (value) AuthorizationValidationRequest p_authorization_validation_request + ) := { + version := PkiProtocolVersion, + content := { + authorizationValidationRequest := p_authorization_validation_request + } + } // End of template m_etsiTs102941Data_authorization_validation_request + + template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_validation_response( + in template (value) AuthorizationValidationResponse p_authorization_validation_response + ) := { + version := PkiProtocolVersion, + content := { + authorizationValidationResponse := p_authorization_validation_response + } + } // End of template m_etsiTs102941Data_authorization_validation_response + + template (present) EtsiTs103097Data/*EnrolmentRequestMessage*/mw_enrolmentRequestMessage( + template (present) EncryptedData p_encryptedData := ? + ) modifies mw_etsiTs103097Data_encrypted := { + } // End of template mw_enrolmentRequestMessage + + template (present) EtsiTs103097Data/*EnrolmentResponseMessage*/mw_enrolmentResponseMessage( + template (present) EncryptedData p_encryptedData := ? + ) modifies mw_etsiTs103097Data_encrypted := { + } // End of template mw_enrolmentResponseMessage + + template (value) EtsiTs103097Data m_authorizationValidationRequestMessage( + in template (value) EncryptedData p_encryptedData + ) modifies m_etsiTs103097Data_encrypted := { + } // End of template m_authorizationValidationRequestMessage + + template (present) EtsiTs103097Data mw_authorizationValidationResponseMessage( + template (present) EncryptedData p_encryptedData := ? + ) modifies mw_etsiTs103097Data_encrypted := { + } // End of template mw_authorizationValidationResponseMessage + + template (value) EtsiTs103097Data/*AuthorizationRequestMessage*/ m_authorizationRequestMessage( + in template (value) EncryptedData p_encryptedData + ) modifies m_etsiTs103097Data_encrypted := { + } // End of template m_authorizationRequestMessage + + template (present) EtsiTs103097Data/*AuthorizationRequestMessage*/ mw_authorizationRequestMessage( + template (present) EncryptedData p_encryptedData := ? + ) modifies mw_etsiTs103097Data_encrypted := { + } // End of template mw_authorizationRequestMessage + + template (value) EtsiTs103097Data/*AuthorizationResponseMessage*/ m_authorizationResponseMessage( + in template (value) EncryptedData p_encryptedData + ) modifies m_etsiTs103097Data_encrypted := { + } // End of template m_authorizationResponseMessage + + template (present) EtsiTs103097Data/*AuthorizationResponseMessage*/ mw_authorizationResponseMessage( + template (present) EncryptedData p_encryptedData := ? + ) modifies mw_etsiTs103097Data_encrypted := { + } // End of template mw_authorizationResponseMessage + + template (value) EtsiTs102941Data m_etsiTs102941Data_to_be_signed_rca_ctl( + in template (value) ToBeSignedRcaCtl p_to_be_signed_rca_ctl + ) := { + version := PkiProtocolVersion, + content := { + certificateTrustListRca := p_to_be_signed_rca_ctl + } + } // End of template m_etsiTs102941Data_to_be_signed_rca_ctl + + template (present) EtsiTs102941Data mw_etsiTs102941Data_to_be_signed_rca_ctl( + template (present) ToBeSignedRcaCtl p_to_be_signed_rca_ctl := ? + ) := { + version := PkiProtocolVersion, + content := { + certificateTrustListRca := p_to_be_signed_rca_ctl + } + } // End of template mw_etsiTs102941Data_to_be_signed_rca_ctl + + template (present) EtsiTs102941Data mw_etsiTs102941Data_to_be_signed_crl( + template (present) ToBeSignedCrl p_to_be_signed_crl := ? + ) := { + version := PkiProtocolVersion, + content := { + certificateRevocationList := p_to_be_signed_crl + } + } // End of template mw_etsiTs102941Data_to_be_signed_crl + + template (present) EtsiTs102941Data mw_etsiTs102941Data_to_be_signed_tlm_ctl( + template (present) ToBeSignedTlmCtl p_to_be_signed_tlm := ? + ) := { + version := PkiProtocolVersion, + content := { + certificateTrustListTlm := p_to_be_signed_tlm + } + } // End of template mw_etsiTs102941Data_to_be_signed_crl + + template (value) EtsiTs102941DataContent m_enrolmentRequest( + in template (value) InnerEcRequestSignedForPop p_enrolmentRequest + ) := { + enrolmentRequest := p_enrolmentRequest + } // End of template m_enrolmentRequest + + template (present) EtsiTs102941DataContent mw_enrolmentRequest( + template (present) InnerEcRequestSignedForPop p_enrolmentRequest := ? + ) := { + enrolmentRequest := p_enrolmentRequest + } // End of template mw_enrolmentRequest + + template (present) InnerEcRequestSignedForPop mw_innerEcRequestSignedForPop( + template (present) SignedData p_signedData := ? + ) modifies mw_etsiTs103097Data_signed := { + } // End of template mw_innerEcRequestSignedForPop + + template (present) EtsiTs102941DataContent mw_enrolmentResponse( + template (present) InnerEcResponse p_enrolmentResponse := ? + ) := { + enrolmentResponse := p_enrolmentResponse + } // End of template mw_enrolmentResponse + + template (value) EtsiTs102941DataContent m_authorizationRequest( + in template (value) InnerAtRequest p_authorizationRequest + ) := { + authorizationRequest := p_authorizationRequest + } // End of template m_authorizationRequest + + template (present) EtsiTs102941DataContent mw_authorizationRequest( + in template (present) InnerAtRequest p_authorizationRequest := ? + ) := { + authorizationRequest := p_authorizationRequest + } // End of template mw_authorizationRequest + + template (present) EtsiTs102941DataContent mw_authorizationResponse( + template (present) InnerAtResponse p_authorizationResponse := ? + ) := { + authorizationResponse := p_authorizationResponse + } // End of template mw_authorizationResponse + + template (present) EtsiTs102941DataContent mw_authorizationValidationRequest( + template (present) AuthorizationValidationRequest p_authorization_validation_request := ? + ) := { + authorizationValidationRequest := p_authorization_validation_request + } // End of template mw_authorizationValidationRequest + + template (present) EtsiTs102941DataContent mw_authorizationValidationResponse( + template (present) AuthorizationValidationResponse p_authorization_validation_response := ? + ) := { + authorizationValidationResponse := p_authorization_validation_response + } // End of template mw_authorizationValidationResponse + + template (value) InnerEcRequest m_innerEcRequest( + in template (value) octetstring p_itsId, + in template (value) PublicKeys p_publicKeys, + in template (value) CertificateSubjectAttributes p_requestedSubjectAttributes + ) := { + itsId := p_itsId, + certificateFormat := 1, + publicKeys := p_publicKeys, + requestedSubjectAttributes := p_requestedSubjectAttributes + } // End of template m_innerEcRequest + + template (present) InnerEcRequest mw_innerEcRequest( + template (present) octetstring p_itsId := ?, + template (present) PublicKeys p_publicKeys := ?, + template (present) CertificateSubjectAttributes p_requestedSubjectAttributes := ? + ) := { + itsId := p_itsId, + certificateFormat := 1, + publicKeys := p_publicKeys, + requestedSubjectAttributes := p_requestedSubjectAttributes + } // End of template mw_innerEcRequest + + template (value) InnerAtRequest m_innerAtRequest( + in template (value) PublicKeys p_publicKeys, + in template (value) Oct32 p_hmacKey, + in template (value) SharedAtRequest p_sharedAtRequest, + in template (value) EcSignature p_ecSignature + ) := { + publicKeys := p_publicKeys, + hmacKey := p_hmacKey, + sharedAtRequest := p_sharedAtRequest, + ecSignature := p_ecSignature + } // End of template m_innerAtRequest + + template (present) InnerAtRequest mw_innerAtRequest( + template (present) PublicKeys p_publicKeys := ?, + template (present) Oct32 p_hmacKey := ?, + template (present) SharedAtRequest p_sharedAtRequest := ?, + template (present) EcSignature p_ecSignature := ? + ) := { + publicKeys := p_publicKeys, + hmacKey := p_hmacKey, + sharedAtRequest := p_sharedAtRequest, + ecSignature := p_ecSignature + } // End of template mw_innerAtRequest + + template (omit) PublicKeys m_publicKeys( + in template (value) PublicVerificationKey p_verificationKey, + in template (omit) PublicEncryptionKey p_encryptionKey := omit + ) := { + verificationKey := p_verificationKey, + encryptionKey := p_encryptionKey + } // End of template m_publicKeys + + template PublicKeys mw_publicKeys( + template (present) PublicVerificationKey p_verificationKey := ?, + template PublicEncryptionKey p_encryptionKey := * + ) := { + verificationKey := p_verificationKey, + encryptionKey := p_encryptionKey + } // End of template mw_publicKeys + + template (omit) CertificateSubjectAttributes m_certificateSubjectAttributes_id_none( + in template (value) SequenceOfPsidSsp p_appPermissions, + in template (omit) ValidityPeriod p_validityPeriod := omit, + in template (omit) GeographicRegion p_region := omit, + in template (omit) SubjectAssurance p_assuranceLevel := omit + ) := { + id := { none_ := NULL }, + validityPeriod := p_validityPeriod, + region := p_region, + assuranceLevel := p_assuranceLevel, + appPermissions := p_appPermissions, + certIssuePermissions := omit + } // End of template m_certificateSubjectAttributes_id_none + + template (omit) CertificateSubjectAttributes m_certificateSubjectAttributes_id_omit( + in template (value) SequenceOfPsidSsp p_appPermissions, + in template (omit) ValidityPeriod p_validityPeriod := omit, + in template (omit) GeographicRegion p_region := omit, + in template (omit) SubjectAssurance p_assuranceLevel := omit + ) modifies m_certificateSubjectAttributes_id_none := { + id := omit + } // End of template m_certificateSubjectAttributes_id_omit + + template (omit) CertificateSubjectAttributes m_certificateSubjectAttributes_id_name( + in template (value) Hostname p_name, + in template (value) SequenceOfPsidSsp p_appPermissions, + in template (omit) ValidityPeriod p_validityPeriod := omit, + in template (omit) GeographicRegion p_region := omit, + in template (omit) SubjectAssurance p_assuranceLevel := omit + ) := { + id := { name := p_name }, + validityPeriod := p_validityPeriod, + region := p_region, + assuranceLevel := p_assuranceLevel, + appPermissions := p_appPermissions, + certIssuePermissions := omit + } // End of template m_certificateSubjectAttributes_id_name + + template (value) InnerEcResponse m_innerEcResponse_ok( + in template (value) Oct16 p_requestHash, + in template (value) EtsiTs103097Certificate p_certificate + ) := { + requestHash := p_requestHash, + responseCode := ok, + certificate := p_certificate + } // End of template m_innerEcResponse_ok + + template (present) InnerEcResponse mw_innerEcResponse_ok( + template (present) Oct16 p_requestHash := ?, + template (present) EtsiTs103097Certificate p_certificate := ? + ) := { + requestHash := p_requestHash, + responseCode := ok, + certificate := p_certificate + } // End of template mw_innerEcResponse_ok + + template (value) InnerEcResponse m_innerEcResponse_ko( + in template (value) Oct16 p_requestHash, + in template (value) EnrolmentResponseCode p_responseCode + ) := { + requestHash := p_requestHash, + responseCode := p_responseCode, + certificate := omit + } // End of template m_innerEcResponse_ko + + template (present) InnerEcResponse mw_innerEcResponse_ko( + template (present) Oct16 p_requestHash := ?, + template (present) EnrolmentResponseCode p_responseCode := complement(ok) + ) := { + requestHash := p_requestHash, + responseCode := p_responseCode, + certificate := omit + } // End of template mw_innerEcResponse_ko + + template (value) InnerAtResponse m_innerAtResponse_ok( + in template (value) Oct16 p_requestHash, + in template (value) EtsiTs103097Certificate p_certificate + ) := { + requestHash := p_requestHash, + responseCode := ok, + certificate := p_certificate + } // End of template m_innerAtResponse_ok + + template (present) InnerAtResponse mw_innerAtResponse_ok( + template (present) Oct16 p_requestHash := ?, + template (present) EtsiTs103097Certificate p_certificate := ? + ) := { + requestHash := p_requestHash, + responseCode := ok, + certificate := p_certificate + } // End of template mw_innerAtResponse_ok + + template (value) InnerAtResponse m_innerAtResponse_ko( + in template (value) Oct16 p_requestHash, + in template (value) AuthorizationResponseCode p_responseCode + ) := { + requestHash := p_requestHash, + responseCode := p_responseCode, + certificate := omit + } // End of template m_innerAtResponse_ko + + template (present) InnerAtResponse mw_innerAtResponse_ko( + template (present) Oct16 p_requestHash := ?, + template (present) AuthorizationResponseCode p_responseCode := complement(ok) + ) := { + requestHash := p_requestHash, + responseCode := p_responseCode, + certificate := omit + } // End of template mw_innerAtResponse_ko + + template (value) AuthorizationValidationRequest m_authorization_validation_request( + in template (value) SharedAtRequest p_sharedAtRequest, + in template (value) EcSignature p_ecSignature + ) := { + sharedAtRequest := p_sharedAtRequest, + ecSignature := p_ecSignature + } // End of template m_authorization_validation_request + + template (present) AuthorizationValidationRequest mw_authorization_validation_request( + template (present) SharedAtRequest p_sharedAtRequest := ?, + template (present) EcSignature p_ecSignature := ? + ) := { + sharedAtRequest := p_sharedAtRequest, + ecSignature := p_ecSignature + } // End of template mw_authorization_validation_request + + template (value) AuthorizationValidationResponse m_authorizationValidationResponse_ok( + template (value) Oct16 p_requestHash, + template (value) CertificateSubjectAttributes p_confirmedSubjectAttributes + ) := { + requestHash := p_requestHash, + responseCode := ok, + confirmedSubjectAttributes := p_confirmedSubjectAttributes + } // End of template m_authorizationValidationResponse_ok + + template (present) AuthorizationValidationResponse mw_authorizationValidationResponse_ok( + template (present) Oct16 p_requestHash := ?, + template (present) CertificateSubjectAttributes p_confirmedSubjectAttributes := ? + ) := { + requestHash := p_requestHash, + responseCode := ok, + confirmedSubjectAttributes := p_confirmedSubjectAttributes + } // End of template mw_authorizationValidationResponse_ok + + template (value) AuthorizationValidationResponse m_authorizationValidationResponse_ko( + in template (value) Oct16 p_requestHash, + in template (value) AuthorizationValidationResponseCode p_responseCode + ) := { + requestHash := p_requestHash, + responseCode := p_responseCode, + confirmedSubjectAttributes := omit + } // End of template m_authorizationValidationResponse_ko + + template (present) AuthorizationValidationResponse mw_authorizationValidationResponse_ko( + template (present) Oct16 p_requestHash := ? + ) := { + requestHash := p_requestHash, + responseCode := complement(ok), + confirmedSubjectAttributes := omit + } // End of template mw_authorizationValidationResponse_ko + + template (value) SharedAtRequest m_shared_at_request( + in template (value) HashedId8 p_eaId, + in template (value) Oct16 p_keyTag, + in template (value) CertificateSubjectAttributes p_requestedSubjectAttributes + ) := { + eaId := p_eaId, + keyTag := p_keyTag, + certificateFormat := 1, + requestedSubjectAttributes := p_requestedSubjectAttributes + } // End of template m_shared_at_request + + template (present) SharedAtRequest mw_shared_at_request( + template (present) HashedId8 p_eaId := ?, + template (present) Oct16 p_keyTag := ?, + template (present) CertificateSubjectAttributes p_requestedSubjectAttributes := ? + ) := { + eaId := p_eaId, + keyTag := p_keyTag, + certificateFormat := 1, + requestedSubjectAttributes := p_requestedSubjectAttributes + } // End of template mw_shared_at_request + + template (value) EcSignature m_ec_signature( + in template (value) EtsiTs103097Data p_encryptedEcSignature + ) := { + encryptedEcSignature := p_encryptedEcSignature + } // End of template m_ec_signature + + template (present) EcSignature mw_ec_signature( + template (present) EtsiTs103097Data p_encryptedEcSignature := ? + ) := { + encryptedEcSignature := p_encryptedEcSignature + } // End of template mw_ec_signature + + template (value) EcSignature m_ec_signature_ext_payload( + in template (value) EtsiTs103097Data p_ecSignature + ) := { + ecSignature := p_ecSignature + } // End of template m_ec_signature_ext_payload + + template (present) EcSignature mw_ec_signature_ext_payload( + template (present) EtsiTs103097Data p_ecSignature := ? + ) := { + ecSignature := p_ecSignature + } // End of template mw_ec_signature_ext_payload + + template (omit) CertificateSubjectAttributes m_certificate_subject_attributes( + in template (value) SequenceOfPsidSsp p_appPermissions, + in template (value) SequenceOfPsidGroupPermissions p_certIssuePermissions, + in template (omit) CertificateId p_id := omit, + in template (omit) ValidityPeriod p_validityPeriod := omit, + in template (omit) GeographicRegion p_region := omit, + in template (omit) SubjectAssurance p_assuranceLevel := omit + ) := { + id := p_id, + validityPeriod := p_validityPeriod, + region := p_region, + assuranceLevel := p_assuranceLevel, + appPermissions := p_appPermissions, + certIssuePermissions := p_certIssuePermissions + } // End of template m_certificate_subject_attributes + + template CertificateSubjectAttributes mw_certificate_subject_attributes( + template (present) SequenceOfPsidSsp p_appPermissions := ?, + template CertificateId p_id := *, + template (present) ValidityPeriod p_validityPeriod := ?, + template SubjectAssurance p_assuranceLevel := *, + template GeographicRegion p_region := *, + template SequenceOfPsidGroupPermissions p_certIssuePermissions := omit + ) := { + id := p_id ifpresent, + validityPeriod := p_validityPeriod, + region := p_region, + assuranceLevel := p_assuranceLevel, + appPermissions := p_appPermissions, + certIssuePermissions := p_certIssuePermissions + } // End of template mw_certificate_subject_attributes + + template CertificateSubjectAttributes mw_certificate_subject_attributes_optional_assuranceLevel( + template (present) SequenceOfPsidSsp p_appPermissions := ?, + template (present) CertificateId p_id := ?, + template (present) ValidityPeriod p_validityPeriod := ?, + template SubjectAssurance p_assuranceLevel := *, + template GeographicRegion p_region := *, + template SequenceOfPsidGroupPermissions p_certIssuePermissions := omit + ) := { + id := p_id, + validityPeriod := p_validityPeriod, + region := p_region, + assuranceLevel := p_assuranceLevel, + appPermissions := p_appPermissions, + certIssuePermissions := p_certIssuePermissions + } // End of template mw_certificate_subject_attributes + + template (value) ToBeSignedRcaCtl m_to_be_signed_rca_full_ctl( + in Time32 p_next_update, + in UInt8 p_ctl_sequence, + in CtlCommands p_ctl_commands +) := { + version := 1, + nextUpdate := p_next_update, + isFullCtl := true, + ctlSequence := p_ctl_sequence, + ctlCommands := p_ctl_commands + } // End of template m_to_be_signed_rca_ful_ctl + + template (present) ToBeSignedRcaCtl mw_to_be_signed_rca_full_ctl := { + version := 1, + nextUpdate := ?, + isFullCtl := true, + ctlSequence := ?, + ctlCommands := ? + } // End of template mw_to_be_signed_rca_ful_ctl + + template (present) ToBeSignedRcaCtl mw_to_be_signed_rca_delta_ctl := { + version := 1, + nextUpdate := ?, + isFullCtl := false, + ctlSequence := ?, + ctlCommands := ? + } // End of template mw_to_be_signed_rca_delta_ctl + + template (value) ToBeSignedCrl m_to_be_signed_crl( + in Time32 p_this_update, + in Time32 p_next_update, + in CrlEntries p_entries + ) := { + version := 1, + thisUpdate := p_this_update, + nextUpdate := p_next_update, + entries := p_entries + } // End of template m_to_be_signed_crl + + template (present) ToBeSignedCrl mw_to_be_signed_crl := { + version := 1, + thisUpdate := ?, + nextUpdate := ?, + entries := ? + } // End of template mw_to_be_signed_crl + + template (present) TlmEntry mw_tlm_entry( + template (present) EtsiTs103097Certificate p_selfSignedTLMCertificate := ?, + template (present) Url p_accessPoint := ? + ) := { + selfSignedTLMCertificate := p_selfSignedTLMCertificate, + linkTLMCertificate := *, + accessPoint := p_accessPoint + } // End of template mw_tlm_entry + + template (value) RootCaEntry m_root_ca_entry( + in template (value) EtsiTs103097Certificate p_selfsignedRootCa + ) := { + selfsignedRootCa := p_selfsignedRootCa, + linkRootCaCertificate := omit + } // End of template m_root_ca_entry + + template (present) RootCaEntry mw_root_ca_entry( + template (present) EtsiTs103097Certificate p_selfsignedRootCa := ? + ) := { + selfsignedRootCa := p_selfsignedRootCa, + linkRootCaCertificate := * + } // End of template mw_root_ca_entry + + template (value) EaEntry m_ea_entry( + in template (value) EtsiTs103097Certificate p_eaCertificate, + in template (value) Url p_aaAccessPoint + ) := { + eaCertificate := p_eaCertificate, + aaAccessPoint := p_aaAccessPoint, + itsAccessPoint := omit + } // End of template m_ea_entry + + template (present) EaEntry mw_ea_entry( + template (present) EtsiTs103097Certificate p_eaCertificate := ?, + template (present) Url p_aaAccessPoint := ? + ) := { + eaCertificate := p_eaCertificate, + aaAccessPoint := p_aaAccessPoint, + itsAccessPoint := * + } // End of template mw_ea_entry + + template (value) AaEntry m_aa_entry( + in template (value) EtsiTs103097Certificate p_aaCertificate, + in template (value) Url p_accessPoint + ) := { + aaCertificate := p_aaCertificate, + accessPoint := p_accessPoint + } // End of template m_aa_entry + + template (present) AaEntry mw_aa_entry( + template (present) EtsiTs103097Certificate p_aaCertificate := ?, + template (present) Url p_accessPoint := ? + ) := { + aaCertificate := p_aaCertificate, + accessPoint := p_accessPoint + } // End of template mw_aa_entry + + template (present) DcEntry mw_dc_entry( + template (present) Url p_url := ?, + template (present) HashedId8s p_cert := ? + ) := { + url := p_url, + cert := p_cert + } // End of template mw_dc_entry + +} // End of module LibItsPki_Templates diff --git a/lib/LibItsPki_TestSystem.ttcn b/lib/LibItsPki_TestSystem.ttcn new file mode 100755 index 0000000..77fb7be --- /dev/null +++ b/lib/LibItsPki_TestSystem.ttcn @@ -0,0 +1,124 @@ +/** + * @author ETSI / STF545 + * @version $Url$ + * $Id$ + * @desc Test System module for ITS PKI + * @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_TestSystem { + + // LibCommon + import from LibCommon_Sync all; + import from LibCommon_Time 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 EtsiTs103097Module language "ASN.1:1997" all; + + // LibItsCommon + import from LibItsCommon_TestSystem all; + import from LibItsCommon_TypesAndValues all; + + // LibItsPki + import from LibItsPki_TypesAndValues all; + + // LibItsGeoNetworking + import from LibItsGeoNetworking_TestSystem all; + + // LibItsSecurity + import from LibItsSecurity_TestSystem all; + + // LibItsHttp + import from LibItsHttp_TestSystem all; + + group portDefinitions { + + /** + * @desc Upper Tester port + */ + type port UpperTesterPkiPort message { + out UtPkiInitialize, UtPkiTrigger; + in UtPkiResults; + } // End of UpperTesterPort + + type port InfoPort message { + inout InfoPortData + } with { + extension "internal" + } // End of InfoPort + + } // End of group portDefinitions + + group componentDefinitions { + + /** + * @desc System component + */ + type component ItsPkiHttpSystem extends HttpTestAdapter{ + /** Use httPort when EC and AT are served by the same end point */ + port HttpPort httpEcPort; /** Enrolment end point */ + port HttpPort httpAtVPort; /** Authorization Validation end point */ + port HttpPort httpAtPort; /** Authorization end point */ + port HttpPort httpCaPort; /** CA CTL/CRL end point */ + port HttpPort httpTlmPort; /** TLM ECTL end point */ + } // End of component ItsPkiHttpSystem + + type component ItsPkiItssSystem extends ItsPkiHttpSystem { + port UpperTesterPkiPort utPort; + port GeoNetworkingPort geoNetworkingPort; + } // End of component ItsPkiItssSystem + + /** + * @desc Test component for PKI entities execpt ITS-S + */ + type component ItsPkiHttp extends ItsSecurityBaseComponent, HttpComponent { + /** Use httPort when EC and AT are served by the same end point */ + port HttpPort httpEcPort; /** Enrolment end point */ + port HttpPort httpAtVPort; /** Authorization Validation end point */ + port HttpPort httpAtPort; /** Authorization end point */ + port HttpPort httpCaPort; /** CA CTL/CRL end point */ + port HttpPort httpTlmPort; /** TLM ECTL end point */ + + port InfoPort infoPort; + + var Certificate vc_eaCertificate; /** Test Adapter EA certificate */ + var octetstring vc_eaPrivateKey; /** Test Adapter EA private key for signature */ + var octetstring vc_eaPrivateEncKey; /** Test Adapter EA private key for encryption */ + var octetstring vc_eaWholeHash; /** Test Adapter EA whole-hash for signature check */ + var octetstring vc_eaWholeHash256; /** Test Adapter EA whole-hash using SHA 256 for encryption because of encryption key size == 32 */ + var HashedId8 vc_eaHashedId8; /** Test Adapter EA HashedId8 for decryption of IUT's response */ + var octetstring vc_aaPrivateKey; /** Test Adapter AA private key for signature */ + var octetstring vc_aaPrivateEncKey; /** Test Adapter AA private key for encryption */ + var HashedId8 vc_aaHashedId8; /** Test Adapter AA HashedId8 for decryption of IUT's response */ + var octetstring vc_aaWholeHash; /** Test Adapter AA whole-hash for signature check */ + var octetstring vc_aaWholeHash256; /** Test Adapter AA whole-hash using SHA 256 for encryption because of encryption key size == 32 */ + + var PrivateEcKeys vc_ec_private_keys; + var PublicCompressedEcKeys vc_ec_public_compressed_key; + var EcCompressedModes vc_ec_compressed_modes; + var EcHashedId8 vc_ec_hashed_id8; + var EcCertificates vc_ec_certificates; + var integer vc_ec_keys_counter; + } // End of component ItsPkiHttp + + /** + * @desc Test component for ITS-S entity + */ + type component ItsPkiItss extends ItsPkiHttp { + port UpperTesterPkiPort utPort; + port GeoNetworkingPort geoNetworkingPort; + } // End of component ItsPkiItss + + } // End of group componentDefinitions + +} // End of module LibItsPki_TestSystem diff --git a/lib/LibItsPki_TypesAndValues.ttcn b/lib/LibItsPki_TypesAndValues.ttcn new file mode 100755 index 0000000..29b3956 --- /dev/null +++ b/lib/LibItsPki_TypesAndValues.ttcn @@ -0,0 +1,153 @@ +/** + * @author ETSI / STF545 + * @version $Url$ + * $Id$ + * @desc Module containing templates for IT PKI Protocol + * @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_TypesAndValues { + + // LibCommon + import from LibCommon_BasicTypesAndValues all; + import from LibCommon_DataStrings all; + + // LibIts + import from Ieee1609Dot2BaseTypes language "ASN.1:1997" all; + import from EtsiTs103097Module language "ASN.1:1997" all; + import from EtsiTs102941TrustLists language "ASN.1:1997" all; + + group constants { + + const integer PkiProtocolVersion := 1; + + } // End of group constants + + type enumerated SecurityAlg { + e_nist_p256 (0), + e_brainpool_p256_r1 (1), + e_brainpool_p384_r1 (2) + } // End of type SecurityAlg + + type set of PublicVerificationKey ListOfPublicVerificationKey; + + group utPrimitives { + + /** + * @desc Upper Tester message to initialize ITS-S IUT + * @member hashedId8 In case of secured mode set, hashedId8 indicate which certificate the IUT shall use + */ + type record UtPkiInitialize { + Oct8 hashedId8 + } with { + variant "FIELDORDER(msb)" + } + + /** + * @desc Upper Tester results message of the PKI ITS-S IUT + */ + type union UtPkiResults { + boolean utPkiInitializeResult, + boolean utPkiTriggerResult + } with { + variant "" + } // End of type UtPkiResults + + /** + * @desc UT primitives for PKI ITS-S IUT + * @member triggerEnrolmentRequest Request to trigger an EnrolmentRequest + */ + type union UtPkiTrigger { + TriggerEnrolmentRequest triggerEnrolmentRequest, + TriggerAuthorizationRequest triggerAuthorizationRequest + } with { + variant "" + } // End of type UtPkiTrigger + + /** + * @desc Request to trigger an EnrolmentRequest + * @member cannonicalId The canonical identifier of the ITS-S + * @member encAlgorithm The encrypion algorithm to be used (Nist P256 or Brainpool P256) + * @member privateKey The private key to be used for signature of the requested EA certificate + * @member compressedPublickey The compressed public key to be used for signature of the requested EA certificate (format: [02|03] + */ + type record TriggerEnrolmentRequest { + octetstring cannonicalId, + Oct1 encAlgorithm, + octetstring privateKey, + octetstring compressedPublickey + } with { + variant "FIELDORDER(msb)" + } // End of type TriggerEnrolmentRequest + + type record TriggerAuthorizationRequest { + octetstring cannonicalId, + Oct1 encAlgorithm, + octetstring privateKey, + octetstring compressedPublickey + } with { + variant "FIELDORDER(msb)" + } // End of type TriggerAuthorizationRequest + + } with { + encode "UpperTester" + variant "" + } // End of group utPrimitives + + group acPrimitives { + + /** + * @desc TA primitives for Pki + */ + type union AcPkiPrimitive { + AcSetSecurityData acSetSecurityData + } with { + variant "" + } + + /** + * @desc Primitive for receiveing response from TA + */ + type union AcPkiResponse { + boolean result + } with { + variant "" + } + + type record AcSetSecurityData { + charstring certificateId, + charstring peer_certificateId, + octetstring private_key, + octetstring public_key_compressed, + integer public_key_compressed_mode + } with { + variant "" + encode "LibItsPki" + } // AcSetSecurityData + + } with { + variant "" + encode "AdapterControl" + } // End of group acPrimitives + + type record InfoPortData { + octetstring hashed_id8, + EtsiTs103097Certificate at_certificate + } // End of type InfoPortData + + type record of CrlEntry CrlEntries; + + type record of CtlCommand CtlCommands; + + type record of octetstring PrivateEcKeys; + type record of octetstring PublicCompressedEcKeys; + type record of integer EcCompressedModes; + type record of HashedId8 EcHashedId8; + type record of EtsiTs103097Certificate EcCertificates; +} +with { + variant "" + encode "LibItsPki" +} // End of module LibItsPki_TypesAndValues diff --git a/lib/asn1 b/lib/asn1 new file mode 160000 index 0000000..9150f3c --- /dev/null +++ b/lib/asn1 @@ -0,0 +1 @@ +Subproject commit 9150f3c03746cff77adf241429eaf4a3ca480374 diff --git a/lib/module.mk b/lib/module.mk new file mode 100755 index 0000000..2e3fd1c --- /dev/null +++ b/lib/module.mk @@ -0,0 +1,31 @@ +sources := LibItsPki_EncdecDeclarations.ttcn \ + LibItsPki_Functions.ttcn \ + LibItsPki_Pics.ttcn \ + LibItsPki_Pixits.ttcn \ + LibItsPki_Templates.ttcn \ + LibItsPki_TestSystem.ttcn \ + LibItsPki_TypesAndValues.ttcn \ + asn1/EtsiTs102941BaseTypes.asn \ + asn1/EtsiTs102941MessagesCa.asn \ + asn1/EtsiTs102941TrustLists.asn \ + asn1/EtsiTs102941TypesAuthorization.asn \ + asn1/EtsiTs102941TypesAuthorizationValidation.asn \ + asn1/EtsiTs102941TypesCaManagement.asn \ + asn1/EtsiTs102941TypesEnrolment.asn \ + asn1/EtsiTs102941TypesLinkCertificate.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Crl.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2CrlBaseTypes.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1AcaEeInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1AcaLaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1AcaMaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1AcaRaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1Acpc.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1CamRaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1CertManagement.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1EcaEeInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1EeMaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1EeRaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1LaMaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1LaRaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1MaRaInterface.asn \ + asn1/ieee_1609.2.1/Ieee1609Dot2Dot1Protocol.asn \ diff --git a/module.mk b/module.mk new file mode 100755 index 0000000..5621b7a --- /dev/null +++ b/module.mk @@ -0,0 +1,53 @@ +suite := AtsPki + +sources := ItsPki_Pixits.ttcn \ + ItsPki_TestCases.ttcn \ + ItsPki_TestControl.ttcn \ + ../AtsCAM/lib/asn1/CAM_PDU_Descriptions.asn \ + ../AtsDENM/lib/asn1/DENM_PDU_Descriptions.asn \ + + +modules := lib \ + ../LibCommon \ + ../LibIts \ + ../AtsGeoNetworking/lib \ + ../AtsIpv6OverGeoNetworking/lib \ + ../AtsSecurity/lib \ + ../LibIts/ttcn/Http \ + /ccsrc/Ports/LibIts_ports \ + /ccsrc/Ports/LibIts_ports/Http_ports \ + /ccsrc/Ports/LibIts_ports/Pki_ports \ + /ccsrc/Ports/LibIts_ports/GN_ports \ + /ccsrc/Ports/LibIts_ports/IPv6oGN_ports \ + /ccsrc/EncDec \ + /ccsrc/Framework \ + /ccsrc/Externals \ + /ccsrc/loggers \ + /ccsrc/geospacial \ + /ccsrc/Asn1c \ + /ccsrc/Protocols/UpperTester \ + /ccsrc/Protocols/Http \ + /ccsrc/Protocols/Security \ + /ccsrc/Protocols/GeoNetworking \ + ../modules/titan.TestPorts.HTTPmsg + +# ../LibIts/asn1/CAM \ +# ../LibIts/asn1/DENM \ +# ../LibIts/asn1/IS \ +# ../LibIts/asn1/Security \ + +# ../LibIts/ttcn/CAM \ +# ../LibIts/ttcn/DENM \ +# ../LibIts/ttcn/BTP \ +# ../../ccsrc/Ports/LibIts_ports/CAM_ports \ +# ../../ccsrc/Protocols/Pcap \ +# ../../ccsrc/Protocols/ETH \ +# ../../ccsrc/Protocols/BTP \ +# ../../ccsrc/Protocols/CAM \ +# ../../ccsrc/Protocols/DENM \ +# ../../ccsrc/Protocols/IVIM \ +# ../../ccsrc/Protocols/MapemSpatem \ +# ../../ccsrc/Protocols/SremSsem \ + +#includes := \ +# ../../ccsrc/Ports/LibIts_ports/BTP_ports -- GitLab From a67680956ddfc7620177c6823ae3c608cad9126b Mon Sep 17 00:00:00 2001 From: Denis Filatov Date: Wed, 29 Sep 2021 13:24:00 +0200 Subject: [PATCH 2/9] use new 1609.2 version --- lib/asn1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/asn1 b/lib/asn1 index 9150f3c..627a96f 160000 --- a/lib/asn1 +++ b/lib/asn1 @@ -1 +1 @@ -Subproject commit 9150f3c03746cff77adf241429eaf4a3ca480374 +Subproject commit 627a96f331082767c8315a7c78f585df4e8a26a5 -- GitLab From 72e46c9092bfa4fc1cc0634b4d1b2ca7871e540b Mon Sep 17 00:00:00 2001 From: Denis Filatov Date: Wed, 29 Sep 2021 14:31:13 +0200 Subject: [PATCH 3/9] IPv6 lib case error --- module.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.mk b/module.mk index 5621b7a..49e66c9 100755 --- a/module.mk +++ b/module.mk @@ -11,7 +11,7 @@ modules := lib \ ../LibCommon \ ../LibIts \ ../AtsGeoNetworking/lib \ - ../AtsIpv6OverGeoNetworking/lib \ + ../AtsIPv6OverGeoNetworking/lib \ ../AtsSecurity/lib \ ../LibIts/ttcn/Http \ /ccsrc/Ports/LibIts_ports \ -- GitLab From c01079ac74847609d5c9279185ede68d3a05e88b Mon Sep 17 00:00:00 2001 From: Denis Filatov Date: Thu, 7 Oct 2021 13:50:21 +0200 Subject: [PATCH 4/9] align with the current version of ASN.1 files --- lib/LibItsPki_Functions.ttcn | 2 +- lib/LibItsPki_Templates.ttcn | 12 ++++++------ lib/asn1 | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/LibItsPki_Functions.ttcn b/lib/LibItsPki_Functions.ttcn index 9dbe69b..4137d49 100755 --- a/lib/LibItsPki_Functions.ttcn +++ b/lib/LibItsPki_Functions.ttcn @@ -4276,7 +4276,7 @@ module LibItsPki_Functions { -, mw_toBeSignedData( mw_signedDataPayload, - mw_ieee1609Dot2_headerInfo(c_its_aid_SCR) + mw_Ieee1609Dot2_headerInfo(c_its_aid_SCR) ) ) ))); diff --git a/lib/LibItsPki_Templates.ttcn b/lib/LibItsPki_Templates.ttcn index b24a2b7..36edec0 100755 --- a/lib/LibItsPki_Templates.ttcn +++ b/lib/LibItsPki_Templates.ttcn @@ -608,22 +608,22 @@ module LibItsPki_Templates { template (present) Url p_accessPoint := ? ) := { selfSignedTLMCertificate := p_selfSignedTLMCertificate, - linkTLMCertificate := *, - accessPoint := p_accessPoint + successorTo := *, + accessPoint := p_accessPoint } // End of template mw_tlm_entry template (value) RootCaEntry m_root_ca_entry( in template (value) EtsiTs103097Certificate p_selfsignedRootCa ) := { - selfsignedRootCa := p_selfsignedRootCa, - linkRootCaCertificate := omit + selfsignedRootCa := p_selfsignedRootCa, + successorTo := omit } // End of template m_root_ca_entry template (present) RootCaEntry mw_root_ca_entry( template (present) EtsiTs103097Certificate p_selfsignedRootCa := ? ) := { - selfsignedRootCa := p_selfsignedRootCa, - linkRootCaCertificate := * + selfsignedRootCa := p_selfsignedRootCa, + successorTo := * } // End of template mw_root_ca_entry template (value) EaEntry m_ea_entry( diff --git a/lib/asn1 b/lib/asn1 index 627a96f..a7c2093 160000 --- a/lib/asn1 +++ b/lib/asn1 @@ -1 +1 @@ -Subproject commit 627a96f331082767c8315a7c78f585df4e8a26a5 +Subproject commit a7c2093316a21613a68a6e43e5848055583ad2f1 -- GitLab From 75e8752737c295153343116f64cbde4bfd9b8d41 Mon Sep 17 00:00:00 2001 From: YannGarcia Date: Thu, 28 Oct 2021 11:46:15 +0200 Subject: [PATCH 5/9] Merging TTF002 in TTF011 - Phase1: AtsCAM, AtsDENM, AtsGeoNetworking, AtsSecurity, AtsPki --- ItsPki_Pixits.ttcn | 0 ItsPki_TestCases.ttcn | 4781 ++++++++++++++++++++++++- ItsPki_TestControl.ttcn | 24 +- lib/LibItsPki_EncdecDeclarations.ttcn | 16 +- lib/LibItsPki_Functions.ttcn | 637 +++- lib/LibItsPki_Pics.ttcn | 13 +- lib/LibItsPki_Pixits.ttcn | 2 + lib/LibItsPki_Templates.ttcn | 130 +- lib/LibItsPki_TestSystem.ttcn | 6 + lib/LibItsPki_TypesAndValues.ttcn | 28 +- lib/module.mk | 0 module.mk | 28 +- 12 files changed, 5552 insertions(+), 113 deletions(-) mode change 100755 => 100644 ItsPki_Pixits.ttcn mode change 100755 => 100644 ItsPki_TestCases.ttcn mode change 100755 => 100644 ItsPki_TestControl.ttcn mode change 100755 => 100644 lib/LibItsPki_EncdecDeclarations.ttcn mode change 100755 => 100644 lib/LibItsPki_Functions.ttcn mode change 100755 => 100644 lib/LibItsPki_Pics.ttcn mode change 100755 => 100644 lib/LibItsPki_Pixits.ttcn mode change 100755 => 100644 lib/LibItsPki_Templates.ttcn mode change 100755 => 100644 lib/LibItsPki_TestSystem.ttcn mode change 100755 => 100644 lib/LibItsPki_TypesAndValues.ttcn mode change 100755 => 100644 lib/module.mk mode change 100755 => 100644 module.mk diff --git a/ItsPki_Pixits.ttcn b/ItsPki_Pixits.ttcn old mode 100755 new mode 100644 diff --git a/ItsPki_TestCases.ttcn b/ItsPki_TestCases.ttcn old mode 100755 new mode 100644 index 302a93d..b364a33 --- a/ItsPki_TestCases.ttcn +++ b/ItsPki_TestCases.ttcn @@ -42,7 +42,12 @@ module ItsPki_TestCases { import from LibItsGeoNetworking_Functions all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_Pics all; + import from LibItsGeoNetworking_Pixits all; import from LibItsGeoNetworking_TestSystem all; + + // LibItsCam + import from LibItsCam_TypesAndValues all; + import from LibItsCam_Templates all; // LibItsSecurity import from LibItsSecurity_TypesAndValues all; @@ -67,12 +72,13 @@ module ItsPki_TestCases { import from LibItsPki_TestSystem all; import from LibItsPki_Pics all; import from LibItsPki_Pixits all; + import from LibItsPki_EncdecDeclarations all; // ItsPki import from ItsPki_Pixits all; /** - * @desc 5.2 ITS-S behaviour + * @desc 5.2 ITS-S behaviour */ group itss_behavior { @@ -1760,13 +1766,13 @@ module ItsPki_TestCases { // Preamble // Initial state: No CAM shall be emitted - geoNetworkingPort.clear; + geoNetworkingPort.clear; tc_noac.start; - alt { + alt { [] geoNetworkingPort.receive { log("No CA message expected"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); - } + } [] tc_noac.timeout { f_sendUtTriggerEnrolmentRequestPrimitive(); log("*** " & testcasename() & ": PASS: No CA message received ***"); @@ -1816,7 +1822,7 @@ module ItsPki_TestCases { // Preamble if (PX_TRIGGER_EC_BEFORE_AT) { - if (f_await_ec_request_send_response(v_inner_ec_response) == true) { + if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } else { @@ -2222,79 +2228,4639 @@ module ItsPki_TestCases { } // End of group f_TC_SECPKI_ITSS_AUTH_04_BV /** - * @desc Check that the Authozation request protocol version is set to 1. + * @desc Check that the Authozation request protocol version is set to 1. + *
+       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
+       * Initial conditions: 
+       *     with {
+       *         the IUT being in the "operational state"
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to requested a new Authorization Ticket (AT)
+       *         }
+       *         then {
+       *             the IUT sends EtsiTs103097Data to the AA
+       *                 containing version
+       *                     indicating value 1
+       *                 and containing content
+       *                     containing autihorizationRequest
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_ITSS_AUTH_05_BV + * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 + */ + testcase TC_SECPKI_ITSS_AUTH_05_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_05_BV + + } // End of group itss_authorization_request + + group itss_authorization_response { + // Void + } // End of group itss_authorization_response + + group itss_authorization_request_repetition { + + /** + * @desc Check that IUT repeats an authorization request when response has not been received + *
+       * Pics Selection: PICS_SECPKI_AUTHORIZATION_RETRY
+       * Initial conditions: {
+       *     the IUT being in the 'enrolled' state
+       *     and the IUT already sent the Authorization Request at the time T1
+       *     and the IUT has not yet received the Authorization Response
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT local time is reached the T1 + PIXIT_AUTH_TIMEOUT_TH1 
+       *         }
+       *         then {
+       *             the IUT sends to EA an AuthorizationRequestMessage
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_AUTH_REP_01_BV + * @reference ETSI TS 103 601, clause 5.2 + */ + testcase TC_SECPKI_ITSS_AUTH_REP_01_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_REP_01_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_REP_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_REP_01_BV + + group f_TC_SECPKI_ITSS_AUTH_REP_01_BV { + + function f_TC_SECPKI_ITSS_AUTH_REP_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + var InfoPortData v_info_port_data; + var boolean v_start_awaiting := false; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + f_sendUtTriggerAuthorizationRequestPrimitive(); + tc_ac.start; + alt { + [v_start_awaiting == true] a_await_cam_with_current_cert( + v_info_port_data.at_certificate + ) { + log("*** " & testcasename() & ": PASS: IUT started to send CA message using new AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] geoNetworkingPort.receive { + log("*** " & testcasename() & ": FAIL: IUT started to send CA message using wrong AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] infoPort.receive(InfoPortData:?) -> value v_info_port_data { + log("*** " & testcasename() & ": INFO: Received new AT certificate ***"); + v_start_awaiting := true; + repeat; + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_01_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_REP_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_request; + var InnerEcResponse v_inner_ec_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PX_TRIGGER_EC_BEFORE_AT) { + f_await_ec_request_send_error_response(v_request); + log("*** " & testcasename() & ": INFO: Reply with 400 Bad Request error message ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + // Wait for the repetition + if (PX_TRIGGER_EC_BEFORE_AT) { + if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerAtRequest v_inner_at_request; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_response.certificate, v_inner_at_request, v_inner_at_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + var octetstring v_msg; + var octetstring v_hashed_id8; + + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + v_msg := bit2oct(encvalue(v_inner_at_response.certificate)); + if (ischosen(v_inner_at_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { + v_hashed_id8 := f_hashedId8FromSha384(f_hashWithSha384(v_msg)); + } else { + v_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(v_msg)); + } + infoPort.send(InfoPortData : { hashed_id8 := v_hashed_id8, at_certificate := v_inner_at_response.certificate }); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_REP_01_BV + + /** + * @desc Check that IUT uses the same message to perform authorization retry + *
+       * Pics Selection: PICS_SECPKI_AUTHORIZATION_RETRY
+       * Initial conditions: {
+       *     the IUT being in the 'enrolled' state
+       *     and the IUT already sent the Authorization Request at the time T1
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to re-send an AuthorizationRequestMessage to AA
+       *         }
+       *         then {
+       *             the IUT sends M to AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_AUTH_REP_02_BV + * @reference ETSI TS 103 601, clause 5.1.2 + */ + testcase TC_SECPKI_ITSS_AUTH_REP_02_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_REP_02_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_REP_02_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_REP_02_BV + + group f_TC_SECPKI_ITSS_AUTH_REP_02_BV { + + function f_TC_SECPKI_ITSS_AUTH_REP_02_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + var InfoPortData v_info_port_data; + var boolean v_start_awaiting := false; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + f_sendUtTriggerAuthorizationRequestPrimitive(); + tc_ac.start; + alt { + [v_start_awaiting == true] a_await_cam_with_current_cert( + v_info_port_data.at_certificate + ) { + log("*** " & testcasename() & ": PASS: IUT started to send CA message using new AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] geoNetworkingPort.receive { + log("*** " & testcasename() & ": FAIL: IUT started to send CA message using wrong AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] infoPort.receive(InfoPortData:?) -> value v_info_port_data { + log("*** " & testcasename() & ": INFO: Received new AT certificate ***"); + v_start_awaiting := true; + repeat; + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_02_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_REP_02_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_initial_request; + var HttpMessage v_request; + var InnerEcResponse v_inner_ec_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PX_TRIGGER_EC_BEFORE_AT) { + f_await_ec_request_send_error_response(v_initial_request); + log("*** " & testcasename() & ": INFO: Reply with 400 Bad Request error message ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + // Wait for the repetition + if (PX_TRIGGER_EC_BEFORE_AT) { + if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + + // Test Body + if (f_verify_repeated_request(v_request, v_initial_request) == false) { + log("*** " & testcasename() & ": FAIL: Repeatition request are different ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: Repeatition request are different ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + // Postamble + // Process the next request + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerAtRequest v_inner_at_request; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + // Verify IUT response + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_response.certificate, v_inner_at_request, v_inner_at_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + var octetstring v_msg; + var octetstring v_hashed_id8; + + log("*** " & testcasename() & ": INFO: InnerEcRequest received ***"); + v_msg := bit2oct(encvalue(v_inner_at_response.certificate)); + if (ischosen(v_inner_at_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { + v_hashed_id8 := f_hashedId8FromSha384(f_hashWithSha384(v_msg)); + } else { + v_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(v_msg)); + } + infoPort.send(InfoPortData : { hashed_id8 := v_hashed_id8, at_certificate := v_inner_at_response.certificate }); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_02_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_REP_02_BV + + /** + * @desc Check that IUT stops sending the Authorization Request message if Authorization Response message has been received + *
+       * Pics Selection: PICS_SECPKI_AUTHORIZATION_RETRY
+       * Initial conditions: {
+       *     the IUT being in the 'enrolled' state
+       *     and the IUT has sent the Authorization Request more than 1 time
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT receives an Authorization Response
+       *         }
+       *         then {
+       *             the IUT stops sending Authorization Requests to AA
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_AUTH_REP_03_BV + * @reference ETSI TS 103 601, clause 5.1.2 + */ + testcase TC_SECPKI_ITSS_AUTH_REP_03_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_REP_03_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_REP_03_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_REP_03_BV + + group f_TC_SECPKI_ITSS_AUTH_REP_03_BV { + + function f_TC_SECPKI_ITSS_AUTH_REP_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + var InfoPortData v_info_port_data; + var boolean v_start_awaiting := false; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + f_sendUtTriggerAuthorizationRequestPrimitive(); + tc_ac.start; + alt { + [v_start_awaiting == true] a_await_cam_with_current_cert( + v_info_port_data.at_certificate + ) { + log("*** " & testcasename() & ": PASS: IUT started to send CA message using new AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + [] geoNetworkingPort.receive { + log("*** " & testcasename() & ": FAIL: IUT started to send CA message using wrong AT certificate ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + [] infoPort.receive(InfoPortData:?) -> value v_info_port_data { + log("*** " & testcasename() & ": INFO: Received new AT certificate ***"); + v_start_awaiting := true; + repeat; + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_03_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_REP_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_initial_request; + var HttpMessage v_request; + var InnerEcResponse v_inner_ec_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + if (PX_TRIGGER_EC_BEFORE_AT) { + f_await_ec_request_send_error_response(v_initial_request); + log("*** " & testcasename() & ": INFO: Reply with 400 Bad Request error message ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + + // Wait for the repetition + if (PX_TRIGGER_EC_BEFORE_AT) { + if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + + // Test Body + tc_ac.start; + alt { + [] a_await_at_http_response_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_recipientInfo_pskRecipInfo(vc_aaHashedId8), * }, + mw_SymmetricCiphertext_aes128ccm + )))))), + v_request + ) { + var HttpMessage v_response; + var integer v_result; + var InnerAtRequest v_inner_at_request; + var InnerAtResponse v_inner_at_response; + + tc_ac.stop; + + // Verify IUT response + if (f_verify_repeated_request(v_request, v_initial_request) == false) { + log("*** " & testcasename() & ": FAIL: Repeatition request are different ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } else { + f_verify_http_at_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_response.certificate, v_inner_at_request, v_inner_at_response, v_response, v_result); + // Send response + if (isvalue(v_response)) { + httpPort.send(v_response); + } + // Set verdict + if (v_result == 0) { + var octetstring v_msg; + var octetstring v_hashed_id8; + + log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); + v_msg := bit2oct(encvalue(v_inner_at_response.certificate)); + if (ischosen(v_inner_at_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) { + v_hashed_id8 := f_hashedId8FromSha384(f_hashWithSha384(v_msg)); + } else { + v_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(v_msg)); + } + infoPort.send(InfoPortData : { hashed_id8 := v_hashed_id8, at_certificate := v_inner_at_response.certificate }); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_03_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_REP_03_BV + + /** + * @desc Check that IUT stops sending the Authorization Request message if maximum number of retry has been reached + *
+       * Pics Selection: PICS_SECPKI_AUTHORIZATION_RETRY
+       * Initial conditions: {
+       *     the IUT being in the 'enrolled' state
+       *     and the IUT has sent the Authorization Request
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT sent the PIXIT_AUTH_MAX_N1 Authorization Request messages
+       *         }
+       *         then {
+       *             the IUT stops sending Authorization Requests
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_AUTH_REP_04_BV + * @reference ETSI TS 103 601, clause 5.1.2 + */ + testcase TC_SECPKI_ITSS_AUTH_REP_04_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_ea; + + // Test control + if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp01(v_itss, v_ea); + + // Start component + v_itss.start(f_TC_SECPKI_ITSS_AUTH_REP_04_BV_itss()); + v_ea.start(f_TC_SECPKI_ITSS_AUTH_REP_04_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown01(v_itss, v_ea); + + } // End of testcase TC_SECPKI_ITSS_AUTH_REP_04_BV + + group f_TC_SECPKI_ITSS_AUTH_REP_04_BV { + + function f_TC_SECPKI_ITSS_AUTH_REP_04_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var HashedId8 v_certificate_digest; + var EtsiTs103097Certificate v_certificate; + var InfoPortData v_info_port_data; + var boolean v_start_awaiting := false; + + // Test component configuration + vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + f_sendUtTriggerEnrolmentRequestPrimitive(); + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Test Body + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: No CA message received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_04_BV_itss + + function f_TC_SECPKI_ITSS_AUTH_REP_04_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_initial_request; + var HttpMessage v_request; + var InnerEcResponse v_inner_ec_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + for (var integer v_i := 0; v_i < PX_AUTH_MAX_N1; v_i := v_i + 1) { + if (PX_TRIGGER_EC_BEFORE_AT) { + f_await_ec_request_send_error_response(v_initial_request); + log("*** " & testcasename() & ": INFO: Reply with 400 Bad Request error message ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } else { + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + } // End of 'for' staement + + // Do not expect any repetition + if (PX_TRIGGER_EC_BEFORE_AT) { + if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + log("*** " & testcasename() & ": INFO: Enrolment not expected due to number of error ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": INCONC: No more enrolment request done ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } else { + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_04_BV_pki + + } // End of group f_TC_SECPKI_ITSS_AUTH_REP_04_BV + + } // End of group itss_authorization_request_repetition + + group itss_ctl_handling { + + /** + * @desc Check that the IUT trust the new RCA from the received ECTL + *
+       * Pics Selection:
+       * Initial conditions: {
+       *     the IUT does not trust the CERT_RCA_NEW
+       *     the IUT has received the TLM CTL
+       *         containing the CERT_RCA_NEW
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT received a CAM
+       *                 signed with AT certificate
+       *                     signed with AA certificate
+       *                         signed with CERT_RCA_NEW
+       *         }
+       *         then {
+       *             the IUT accepts this CAM
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTL_01_BV + * @reference ETSI TS 102 941, clause 6.3.5 + */ + testcase TC_SECPKI_ITSS_CTL_01_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_cpoc; + + // Test control + if (not PICS_IUT_ITS_S_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp03(v_itss, v_cpoc); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_CTL_01_BV_itss()); + v_cpoc.start(f_TC_SECPKI_ITSS_CTL_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_cpoc); + + } // End of testcase TC_SECPKI_ITSS_CTL_01_BV + + group f_TC_SECPKI_ITSS_CTL_01_BV { + + function f_TC_SECPKI_ITSS_CTL_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + var integer i; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) { + tc_ac.stop; + + f_sendUtTriggerUpdateEctl(""); // FIXME Create PIXIT for ETCL URI + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + v_securedGnPdu := f_sendSecuredCam(cc_ectl_rca_new); + // Check that the CAM message is forwarde to Facilies layer + f_sleep(PX_TAC); + for(i := 0; i < lengthof(vc_utInds) and not match(vc_utInds[i].rawPayload, valueof(v_securedGnPdu.gnPacket.packet.payload)); i := i + 1) { + // empty on purpose + } + if(i < lengthof(vc_utInds)) { + log("*** " & testcasename() & ": PASS: CA message was transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: CA message was not transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + // Postamble + f_cfDown_itss(); + + } // End of function f_TC_SECPKI_ITSS_CTL_01_BV_itss + + function f_TC_SECPKI_ITSS_CTL_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var HttpMessage v_response; + var Headers v_headers; + + // Test component configuration + f_cfHttpUp_tlm(); + + // Test adapter configuration + + // Preamble + tc_ac.start; + alt { + [] a_await_cpoc_http_request_from_iut( + mw_http_request( + mw_http_request_get( + PICS_HTTP_GET_URI_ECTL + )), + v_response + ) { + var HashedId8 v_rca_hashed_id8; // Used for signature + var Oct32 v_rca_private_key; + var EtsiTs103097Certificate v_rca_new; // The CERT_RCA_NEW + var bitstring v_enc_msg; + var ToBeSignedData v_tbs; + var bitstring v_tbs_enc; + var Oct32 v_tbs_signed; + var Signature v_signature; + var Ieee1609Dot2Data v_ieee1609dot2_signed_data; + + tc_ac.stop; + + // Read certificates + f_getCertificateHash(PICS_IUT_CA_CERTIFICATE_ID, v_rca_hashed_id8); + f_readSigningKey(PICS_IUT_CA_CERTIFICATE_ID, v_rca_private_key); + f_readCertificate(cc_ectl_rca_new, v_rca_new); + // Build the ToBeSignedTlmCtl data structure + v_enc_msg := encvalue( + valueof( + m_to_be_signed_tlm_full_ctl( + f_getCurrentTime() / 1000 + 3600, + 10, + { + m_ctrl_command_add( + m_ctl_entry_rca( + m_root_ca_entry( + v_rca_new + ))) + } + ))); + v_tbs := valueof( + m_toBeSignedData( + m_signedDataPayload( + m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg)) + ), + m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/) + )); + v_tbs_enc := encvalue(v_tbs); + // Sign the certificate + v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_rca_hashed_id8, v_rca_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) + ))); + log(testcasename() & ": v_signature= ", v_signature); + v_ieee1609dot2_signed_data := valueof( + m_etsiTs103097Data_signed( + m_signedData( + sha256, + v_tbs, + m_signerIdentifier_digest(v_rca_hashed_id8), + v_signature + ))); + // Send response with CERT_RCA_NEW + f_init_default_headers_list(-, "tlm_ectl", v_headers); + f_http_send( + v_headers, + m_http_response( + m_http_response_ok( + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_data + )), + v_headers + ))); + + log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfHttpDown_tlm(); + } // End of function f_TC_SECPKI_ITSS_CTL_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTL_01_BV + + /** + * @desc Check that the IUT untrust the RCA when it is deleted from ECTL + *
+       * Pics Selection:
+       * Initial conditions: {
+       *     the IUT does not trust the CERT_RCA
+       *     the IUT has received the TLM CTL
+       *         not containing the CERT_RCA
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT received a CAM
+       *                 signed with AT certificate
+       *                     signed with AA certificate
+       *                         signed with CERT_RCA
+       *         }
+       *         then {
+       *             the IUT rejects this CAM
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTL_02_BV + * @reference ETSI TS 102 941, clause 6.3.5 + */ + testcase TC_SECPKI_ITSS_CTL_02_BV() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + var integer i; + + // Test control + if (not PICS_IUT_ITS_S_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) { + tc_ac.stop; + + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + v_securedGnPdu := f_sendSecuredCam(cc_ectl_rca_untrust); + // Check that the CAM message is forwarde to Facilies layer + f_sleep(PX_TAC); + for(i := 0; i < lengthof(vc_utInds) and not match(vc_utInds[i].rawPayload, valueof(v_securedGnPdu.gnPacket.packet.payload)); i := i + 1) { + // empty on purpose + } + if(i < lengthof(vc_utInds)) { + log("*** " & testcasename() & ": FAIL: CA message was not transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: CA message was transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + + // Postamble + f_cfDown_itss(); + + } // End of testcase TC_SECPKI_ITSS_CTL_02_BV + + /** + * @desc Check that the IUT trust the AA when it is received in RCA CTL + *
+       * Pics Selection:
+       * Initial conditions: {
+       *     the IUT is trusting the CERT_AA_NEW
+       *     the IUT has received the RCA CTL
+       *         containing the CERT_AA_NEW
+       *         and signed by CERT_RCA
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT received a CAM
+       *                 signed with AT certificate
+       *                     signed with AA_NEW certificate
+       *         }
+       *         then {
+       *             the IUT accepts this CAM
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTL_03_BV + * @reference ETSI TS 102 941, clause 6.3.5 + */ + testcase TC_SECPKI_ITSS_CTL_03_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_dc; + + // Test control + if (not PICS_IUT_ITS_S_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp04(v_itss, v_dc); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_CTL_03_BV_itss()); + v_dc.start(f_TC_SECPKI_ITSS_CTL_03_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown04(v_itss, v_dc); + + } // End of testcase TC_SECPKI_ITSS_CTL_03_BV + + group f_TC_SECPKI_ITSS_CTL_03_BV { + + function f_TC_SECPKI_ITSS_CTL_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + var integer i; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) { + tc_ac.stop; + + f_sendUtTriggerRequestForRcaCtl(""); // FIXME Create PIXIT for RCA DC + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + v_securedGnPdu := f_sendSecuredCam(cc_ectl_aa_new); + // Check that the CAM message is forwarde to Facilies layer + f_sleep(PX_TAC); + for(i := 0; i < lengthof(vc_utInds) and not match(vc_utInds[i].rawPayload, valueof(v_securedGnPdu.gnPacket.packet.payload)); i := i + 1) { + // empty on purpose + } + if(i < lengthof(vc_utInds)) { + log("*** " & testcasename() & ": PASS: CA message was transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: CA message was not transmitted to upper layer ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_CTL_03_BV_itss + + function f_TC_SECPKI_ITSS_CTL_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var HttpMessage v_response; + var Headers v_headers; + + // Test component configuration + f_cfHttpUp_ca(); + + // Test adapter configuration + + // Preamble + tc_ac.start; + alt { + [] a_await_dc_http_request_from_iut( + mw_http_request( + mw_http_request_get( + PICS_HTTP_GET_URI_CA + )), + v_response + ) { + var HashedId8 v_aa_hashed_id8; // Used for signature + var Oct32 v_aa_private_key; + var EtsiTs103097Certificate v_aa_new; // The CERT_AA_NEW + var bitstring v_enc_msg; + var ToBeSignedData v_tbs; + var bitstring v_tbs_enc; + var Oct32 v_tbs_signed; + var Signature v_signature; + var Ieee1609Dot2Data v_ieee1609dot2_signed_data; + + tc_ac.stop; + + // Read certificates + f_getCertificateHash("CERT_IUT_AA", v_aa_hashed_id8); + f_readSigningKey("CERT_IUT_AA", v_aa_private_key); + f_readCertificate(cc_ectl_aa_new, v_aa_new); + // Build the ToBeSignedRcaCtl data structure + v_enc_msg := encvalue( + valueof( + m_to_be_signed_rca_full_ctl( + f_getCurrentTime() / 1000 + 3600, + 10, + { + m_ctrl_command_add( + m_ctl_entry_aa( + m_aa_entry( + v_aa_new, + "" // FIXME PICS_AA_ENTRY_URL + ))) + } + ))); + v_tbs := valueof( + m_toBeSignedData( + m_signedDataPayload( + m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg)) + ), + m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/) + )); + v_tbs_enc := encvalue(v_tbs); + // Sign the certificate + v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_aa_hashed_id8, v_aa_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) + ))); + log(testcasename() & ": v_signature= ", v_signature); + v_ieee1609dot2_signed_data := valueof( + m_etsiTs103097Data_signed( + m_signedData( + sha256, + v_tbs, + m_signerIdentifier_digest(v_aa_hashed_id8), + v_signature + ))); + // Send response with CERT_AA_NEW + f_init_default_headers_list(-, "ca_request", v_headers); + f_http_send( + v_headers, + m_http_response( + m_http_response_ok( + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_data + )), + v_headers + ))); + + log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfHttpDown_ca(); + } // End of function f_TC_SECPKI_ITSS_CTL_03_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTL_03_BV + + /** + * @desc Check that the IUT requests new ECTL when current one is expired + *
+       * Pics Selection:
+       * Initial conditions: {
+       *     the IUT already downloaded the TLM CTL
+       *         containing nextUpdate
+       *             indicating timestamp T1
+       *         and containing CPOC URL
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the T1 < CURRENT TIME
+       *         }
+       *         then {
+       *             the IUT sends a request to the CPOC for a new CTL
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTL_04_BV + * @reference ETSI TS 102 941, clause 6.3.5 + */ + testcase TC_SECPKI_ITSS_CTL_04_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_tlm; + + // Test control + if (not PICS_IUT_ITS_S_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp03(v_itss, v_tlm); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_CTL_04_BV_itss()); + v_tlm.start(f_TC_SECPKI_ITSS_CTL_04_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_tlm); + + } // End of testcase TC_SECPKI_ITSS_CTL_04_BV + + group f_TC_SECPKI_ITSS_CTL_04_BV { + + function f_TC_SECPKI_ITSS_CTL_04_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + var integer i; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) { + tc_ac.stop; + + f_sendUtTriggerRequestForRcaCtl(""); // FIXME Create PIXIT for RCA DC + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + log("*** " & testcasename() & ": PASS: Trigger was sent ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_CTL_04_BV_itss + + function f_TC_SECPKI_ITSS_CTL_04_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variables + var Headers v_headers; + var HttpMessage v_response; + var float v_t1 := 30.0; // nextUpdate expiry in second + // := (f_getCurrentTime()/* - 1072915200000*/) / 1000; // nextUpdate expiry in second + + // Test component configuration + f_cfHttpUp_tlm(); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "tlm_request", v_headers); + tc_ac.start; + alt { + [] a_await_cpoc_http_request_from_iut( + mw_http_request( + mw_http_request_get( + PICS_HTTP_GET_URI_ECTL + )), + v_response + ) { + var HashedId8 v_rca_hashed_id8; // Used for signature + var Oct32 v_rca_private_key; + var EtsiTs103097Certificate v_rca_new; // The CERT_RCA_NEW + var bitstring v_enc_msg; + var ToBeSignedData v_tbs; + var bitstring v_tbs_enc; + var Oct32 v_tbs_signed; + var Signature v_signature; + var Ieee1609Dot2Data v_ieee1609dot2_signed_data; + + tc_ac.stop; + + // Read certificates + f_getCertificateHash(PICS_IUT_CA_CERTIFICATE_ID, v_rca_hashed_id8); + f_readSigningKey(PICS_IUT_CA_CERTIFICATE_ID, v_rca_private_key); + f_readCertificate(cc_ectl_rca_new, v_rca_new); + // Build the ToBeSignedTlmCtl data structure + v_enc_msg := encvalue( + valueof( + m_to_be_signed_tlm_full_ctl( + f_getCurrentTime() / 1000 + 30, + 10, + { + m_ctrl_command_add( + m_ctl_entry_rca( + m_root_ca_entry( + v_rca_new + ))) + } + ))); + v_tbs := valueof( + m_toBeSignedData( + m_signedDataPayload( + m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg)) + ), + m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/) + )); + v_tbs_enc := encvalue(v_tbs); + // Sign the certificate + v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_rca_hashed_id8, v_rca_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) + ))); + log(testcasename() & ": v_signature= ", v_signature); + v_ieee1609dot2_signed_data := valueof( + m_etsiTs103097Data_signed( + m_signedData( + sha256, + v_tbs, + m_signerIdentifier_digest(v_rca_hashed_id8), + v_signature + ))); + // Send response with CERT_RCA_NEW + f_init_default_headers_list(-, "tlm_ectl", v_headers); + f_http_send( + v_headers, + m_http_response( + m_http_response_ok( + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data( + v_ieee1609dot2_signed_data + )), + v_headers + ))); + + log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***"); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + tc_wait.start(v_t1); + alt { + [] a_await_cpoc_http_request_from_iut( + mw_http_request( + mw_http_request_get( + PICS_HTTP_GET_URI_ECTL + )), + v_response + ) { + tc_wait.stop; + + // TODO Send an error response (400 Bad request?) + log("*** " & testcasename() & ": FAIL: ITSS TLM CTL request received before the tiemer expiry ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_error); + } + [] tc_wait.timeout { + log("*** " & testcasename() & ": PASS: No ITSS TLM CTL request done before the timer expiry ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + } // End of 'alt' statement + + // TODO Wait for the request after timer expiry + + // Postamble + f_cfHttpDown_tlm(); + + } // End of testcase TC_SECPKI_ITSS_CTL_04_BV + + } // End of group f_TC_SECPKI_ITSS_CTL_04_BV + + /** + * @desc Check that the IUT requests new RCA CTL when current one is expired + *
+       * Pics Selection:
+       * Initial conditions: {
+       *     the IUT already downloaded the RCA CTL
+       *         containing nextUpdate
+       *             indicating timestamp T1
+       *         and containing RCA DC URL
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the T1 < CURRENT TIME
+       *         }
+       *         then {
+       *             the IUT sends a request to the RCA DC for a new CTL
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTL_05_BV + * @reference ETSI TS 102 941, clause 6.3.5 + */ + testcase TC_SECPKI_ITSS_CTL_05_BV() runs on ItsMtc system ItsPkiItssSystem { + // Local variables + var ItsPkiItss v_itss; + var ItsPkiHttp v_dc; + + // Test control + if (not PICS_IUT_ITS_S_ROLE) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_cfMtcUp04(v_itss, v_dc); + + // Start components + v_itss.start(f_TC_SECPKI_ITSS_CTL_05_BV_itss()); + v_dc.start(f_TC_SECPKI_ITSS_CTL_05_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown04(v_itss, v_dc); + + } // End of testcase TC_SECPKI_ITSS_CTL_05_BV + + group f_TC_SECPKI_ITSS_CTL_05_BV { + + function f_TC_SECPKI_ITSS_CTL_05_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + var integer i; + + // Test component configuration + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) { + tc_ac.stop; + + f_sendUtTriggerRequestForRcaCtl(""); // FIXME Create PIXIT for RCA DC + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + log("*** " & testcasename() & ": PASS: Trigger was sent ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + + // Postamble + f_cfDown_itss(); + } // End of function f_TC_SECPKI_ITSS_CTL_05_BV_itss + + function f_TC_SECPKI_ITSS_CTL_05_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + // Local variable + var HttpMessage v_response; + var Headers v_headers; + var float v_t1 := 30.0; // nextUpdate expiry in second + // := (f_getCurrentTime()/* - 1072915200000*/) / 1000; // nextUpdate expiry in second + + // Test component configuration + f_cfHttpUp_ca(); + + // Test adapter configuration + + // Preamble + tc_ac.start; + alt { + [] a_await_dc_http_request_from_iut( + mw_http_request( + mw_http_request_get( + PICS_HTTP_GET_URI_CA + )), + v_response + ) { + var HashedId8 v_aa_hashed_id8; // Used for signature + var Oct32 v_aa_private_key; + var EtsiTs103097Certificate v_aa_new; // The CERT_AA_NEW + var bitstring v_enc_msg; + var ToBeSignedData v_tbs; + var bitstring v_tbs_enc; + var Oct32 v_tbs_signed; + var Signature v_signature; + var Ieee1609Dot2Data v_ieee1609dot2_signed_data; + + tc_ac.stop; + + // Read certificates + f_getCertificateHash("CERT_IUT_AA", v_aa_hashed_id8); + f_readSigningKey("CERT_IUT_AA", v_aa_private_key); + f_readCertificate(cc_ectl_aa_new, v_aa_new); + // Build the ToBeSignedRcaCtl data structure + v_enc_msg := encvalue( + valueof( + m_to_be_signed_rca_full_ctl( + f_getCurrentTime() / 1000 + 30, + 10, + { + m_ctrl_command_add( + m_ctl_entry_aa( + m_aa_entry( +