diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..9f836d5733bcbfd2c8ef58b2717605cf32498a00 --- /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 100644 index 0000000000000000000000000000000000000000..301885d353aa92efc2314d6ab70d582fe6449d87 --- /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 100644 index 0000000000000000000000000000000000000000..b364a336513a122d015a716048849588582129bd --- /dev/null +++ b/ItsPki_TestCases.ttcn @@ -0,0 +1,14029 @@ +/** + * @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_Pixits all; + import from LibItsGeoNetworking_TestSystem all; + + // LibItsCam + import from LibItsCam_TypesAndValues all; + import from LibItsCam_Templates 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; + import from LibItsPki_EncdecDeclarations 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, 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_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 { + // 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( + 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 + 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 RCA DC request received before the tiemer expiry ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_error); + } + [] tc_wait.timeout { + log("*** " & testcasename() & ": PASS: No RCA DC done before the timer expiry ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // TODO Wait for the request after timer expiry + + // Postamble + f_cfHttpDown_ca(); + + } // End of testcase TC_SECPKI_ITSS_CTL_05_BV + + } // End of group f_TC_SECPKI_ITSS_CTL_05_BV + + group f_TC_SECPKI_ITSS_CTL_xx { // FIXME Issue while trying to use CAM Template & EncDec functions because of CAM Test imported, need CAM port and UpperTester_CAM Port which are not part of the PKI Test Interface. Need to separate them. See ETSI TTF 011 + + /*group cam_templates { // FIXME Issue while trying to use CAM Template & EncDec functions because of CAM Test imported, need CAM port and UpperTester_CAM Port which are not part of the PKI Test Interface. Need to separate them. See ETSI TTF 011 + + function f_integer2Latitude(in integer p_latitude) return Latitude { + var Latitude v_latitude := f_abs(p_latitude); + return v_latitude; + } + function f_integer2Longitude(in integer p_longitude) return Longitude { + var Longitude v_longitude := f_abs(p_longitude); + return v_longitude; + } + + template (value) ReferencePosition m_tsPosition := { + latitude := f_integer2Latitude(f_getTsLatitude()), + longitude := f_integer2Longitude(f_getTsLongitude()), + positionConfidenceEllipse := { + semiMajorConfidence := LibItsCommon_ASN1_NamedNumbers.SemiAxisLength_oneCentimeter_, + semiMinorConfidence := LibItsCommon_ASN1_NamedNumbers.SemiAxisLength_oneCentimeter_, + semiMajorOrientation := LibItsCommon_ASN1_NamedNumbers.HeadingValue_wgs84North_ + }, + altitude := { + altitudeValue := LibItsCommon_ASN1_NamedNumbers.AltitudeValue_referenceEllipsoidSurface_, + altitudeConfidence := unavailable + } + } + + template (value) CAM m_camMsg_vehicle_HF_BV( + StationID p_stationId, + GenerationDeltaTime p_generationTime, + template (value) ReferencePosition p_referencePosition + ) := { + header := { + protocolVersion := LibItsCommon_ASN1_NamedNumbers.ItsPduHeader_protocolVersion_currentVersion_, + messageID := LibItsCommon_ASN1_NamedNumbers.ItsPduHeader_messageID_cam_, + stationID := p_stationId + }, + cam := { + generationDeltaTime := p_generationTime, + camParameters := { + basicContainer := { + stationType := LibItsCommon_ASN1_NamedNumbers.StationType_passengerCar_, + referencePosition := p_referencePosition + }, + highFrequencyContainer := { + basicVehicleContainerHighFrequency := { + heading := { + headingValue := LibItsCommon_ASN1_NamedNumbers.HeadingValue_wgs84North_, //0 + headingConfidence := 10 + }, + speed := { + speedValue := 45, + speedConfidence := 5 + }, + driveDirection := forward, + vehicleLength := { + vehicleLengthValue := 50, + vehicleLengthConfidenceIndication := noTrailerPresent + }, + vehicleWidth := 21, + longitudinalAcceleration := { + longitudinalAccelerationValue := LibItsCommon_ASN1_NamedNumbers.LongitudinalAccelerationValue_unavailable_, + longitudinalAccelerationConfidence := LibItsCommon_ASN1_NamedNumbers.AccelerationConfidence_unavailable_ + }, + curvature := { + curvatureValue := LibItsCommon_ASN1_NamedNumbers.CurvatureValue_straight_, + curvatureConfidence := unavailable + }, + curvatureCalculationMode := yawRateUsed, + yawRate := { + yawRateValue := LibItsCommon_ASN1_NamedNumbers.YawRateValue_straight_, + yawRateConfidence := unavailable + }, + accelerationControl := omit, + lanePosition := omit, + steeringWheelAngle := omit, + lateralAcceleration := omit, + verticalAcceleration := omit, + performanceClass := omit, + cenDsrcTollingZone := omit + } + }, + lowFrequencyContainer := omit, + specialVehicleContainer := omit + } + } + } // End of template m_camMsg_vehicle_HF_BV + + template (value) CAM m_camMsg_vehicle( + StationID p_stationId, + GenerationDeltaTime p_generationTime, + template (value) ReferencePosition p_referencePosition + ) modifies m_camMsg_vehicle_HF_BV := { + cam := { + camParameters := { + lowFrequencyContainer := { + basicVehicleContainerLowFrequency := { + vehicleRole := default_, + exteriorLights := LibItsCommon_ASN1_NamedNumbers.ExteriorLights_daytimeRunningLightsOn_, + pathHistory := {} + } + } + } + } + } // End of template m_camMsg_vehicle + + }*/ // End of group cam_templates + + function f_sendSecuredCam(in charstring p_certificate_id) runs on ItsPkiItss return GeoNetworkingPdu { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + + v_securedGnPdu := f_prepareSecuredCam(p_certificate_id, valueof(m_headerInfo_cam(-, (f_getCurrentTime() * 1000)/*us*/)), valueof(m_signerIdentifier_digest), f_getTsStationId()); + log("f_sendSecuredCam: v_securedGnPdu= ", v_securedGnPdu); + geoNetworkingPort.send(valueof(m_geoNwReq_linkLayerBroadcast(v_securedGnPdu))); + return v_securedGnPdu; + } + + function f_prepareSecuredCam( + in charstring p_configId, + in HeaderInfo p_headerInfo, + in SignerIdentifier p_signerIdentifier, + in template (value) StationID p_station_id := f_getTsStationId() + ) runs on ItsPkiItss return GeoNetworkingPdu { + // Local variables + var GnNonSecuredPacket v_gnNonSecuredPacket; + var octetstring v_gnPayload; + var EtsiTs103097Data v_securedMessage; + var LongPosVector v_longPosVector := valueof(m_dummyLongPosVector); + + log(">>> f_prepareSecuredCam"); + + // Build signed Ieee1609Dot2Data + v_longPosVector.latitude := f_getTsLatitude(); + v_longPosVector.longitude := f_getTsLongitude(); + v_longPosVector.gnAddr := f_getTsGnLocalAddress(c_compNodeB); + v_gnNonSecuredPacket := valueof(m_geoNwShbPacket( + v_longPosVector + )); + // Encode CAM payload + v_gnPayload := valueof( + bit2oct( + encvalue( + m_camMsg_vehicle_HF_BV( + valueof(p_station_id), + f_getCurrentTime() mod 65536, // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime + m_tsPosition + )))); + // Add BTP/CAM payload + v_gnNonSecuredPacket.payload := int2oct(2001, 2) & int2oct(0, 2) & v_gnPayload; + // Encode it + log("f_prepareSecuredCam: v_gnNonSecuredPacket= ", v_gnNonSecuredPacket); + v_gnPayload := bit2oct( + encvalue( + v_gnNonSecuredPacket + ) + ); + log("f_prepareSecuredCam: v_gnPayload= ", v_gnPayload); + f_buildGnSecuredCam( + v_securedMessage, + valueof(m_toBeSignedData( + m_signedDataPayload( + m_etsiTs103097Data_unsecured( + v_gnPayload + )), + p_headerInfo + )), + p_signerIdentifier, + p_configId + ); + + // Return secured Gn packet + return valueof(m_geoNwSecPdu(v_gnNonSecuredPacket, v_securedMessage)); + } // End of function f_prepareSecuredCam + + } // End of group f_TC_SECPKI_ITSS_CTL_xx + + } // End of group itss_ctl_handling + + group itss_ctl_distribution { + + /** + * @desc Check that the IUT retransmits the newly received Delta CTL + *
+       * Pics Selection: PICS_UC_SEC_05_2
+       * Initial conditions: {
+       *     the IUT is configured to redistribute the Delta CTL
+       *     and the IUT doesn’t contain an CTL information
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT has received the Delta CTL
+       *         }
+       *         then {
+       *             the IUT is started to broadcast the received Delta CTL
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_01_BV + * @reference ETSI TS 103 601, clause 4.2.1.4 + */ + testcase TC_SECPKI_ITSS_CTLDIST_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 or not PICS_UC_SEC_05_2) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 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_CTLDIST_01_BV_itss()); + v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_01_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_cpoc); + + } // End of testcase TC_SECPKI_ITSS_CTLDIST_01_BV + + group f_TC_SECPKI_ITSS_CTLDIST_01_BV { + + function f_TC_SECPKI_ITSS_CTLDIST_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingInd v_geonetworking_message; + + // 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 + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) -> value v_geonetworking_message { + tc_ac.stop; + + if (f_verify_broadcasted_delta_ctl(v_geonetworking_message.msgIn) == false) { + log("*** " & testcasename() & ": FAIL: Delta CTL was not successfully broadcasted ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + + } // End of function TC_SECPKI_ITSS_CTLDIST_01_BV_itss + + function f_TC_SECPKI_ITSS_CTLDIST_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_CTLDIST_01_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTLDIST_01_BV + + /** + * @desc Check that the IUT retransmits the updated Delta CTL + *
+       * Pics Selection: PICS_UC_SEC_05_2
+       * Initial conditions: {
+       *     the IUT is configured to redistribute the Delta CTL
+       *     and the IUT contains an CTL information
+       *         containing ctlSequence (SN)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT has received the Delta CTL
+       *                 containing ctlSequence
+       *                    indicating value greater than SN
+       *         }
+       *         then {
+       *             the IUT is started to broadcast the received Delta CTL
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_02_BV + * @reference ETSI TS 103 601, clause 4.2.1.4 + */ + testcase TC_SECPKI_ITSS_CTLDIST_02_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 or not PICS_UC_SEC_05_2) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 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_CTLDIST_02_BV_itss()); + v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_02_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_cpoc); + + } // End of testcase TC_SECPKI_ITSS_CTLDIST_02_BV + + group f_TC_SECPKI_ITSS_CTLDIST_02_BV { + + function f_TC_SECPKI_ITSS_CTLDIST_02_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingInd v_geonetworking_message; + + // 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 + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) -> value v_geonetworking_message { + tc_ac.stop; + + if (f_verify_broadcasted_delta_ctl(v_geonetworking_message.msgIn) == false) { + log("*** " & testcasename() & ": FAIL: Delta CTL was not successfully broadcasted ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + + } // End of function TC_SECPKI_ITSS_CTLDIST_02_BV_itss + + function f_TC_SECPKI_ITSS_CTLDIST_02_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_CTLDIST_02_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTLDIST_02_BV + + /** + * @desc Check that the IUT is using the proper BTP port to broadcast the Delta CTL + *
+       * Pics Selection: PICS_UC_SEC_05_2
+       * Initial conditions: {
+       *     the IUT is configured to support P2P X_DISTRIBUTION distribution
+       *     and the IUT has received the Delta X_DISTRIBUTION message
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT is triggered to broadcast the Delta X_DISTRIBUTION message
+       *         }
+       *         then {
+       *             the IUT sends the X_MESSAGE
+       *                 using the BTP port 2014
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_03_BV + * @reference ETSI TS 103 601, clause 5.4.4 + */ + testcase TC_SECPKI_ITSS_CTLDIST_03_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 or not PICS_UC_SEC_05_2) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 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_CTLDIST_03_BV_itss()); + v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_03_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_cpoc); + + } // End of testcase TC_SECPKI_ITSS_CTLDIST_03_BV + + group f_TC_SECPKI_ITSS_CTLDIST_03_BV { + + function f_TC_SECPKI_ITSS_CTLDIST_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingInd v_geonetworking_message; + var octetstring v_payload; + + // 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 + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) -> value v_geonetworking_message { + tc_ac.stop; + + if (f_verify_and_extract_payload(v_geonetworking_message.msgIn, -, v_payload) == false) { + log("*** " & testcasename() & ": INCONC: Failed to verifiy payload ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } else { + // TODO Check payload + if (substr(v_payload, 0, 2) == int2oct(2014, 2)) { // TODO Reorganize CAM/DENM/BTP test suites + log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted on the correct BTP port ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Delta CTL was not broadcasted on BTP port 114 ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + + } // End of function TC_SECPKI_ITSS_CTLDIST_03_BV_itss + + function f_TC_SECPKI_ITSS_CTLDIST_03_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_CTLDIST_03_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTLDIST_03_BV + + /** + * @desc Check that the IUT stops to redistribute the Delta CTL if anorther node is also sending it + *
+       * Pics Selection: PICS_UC_SEC_05_2
+       * Initial conditions: {
+       *     the IUT is configured to support P2P Delta X_DISTRIBUTION distribution
+       *     and the IUT has started broadcasting the Delta X_DISTRIBUTION message
+       *         signed with X_CERTIFICATE
+       *         and containing ctlSequence (SN)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the IUT has received the Delta X_DISTRIBUTION
+       *                 signed with X_CERTIFICATE
+       *                 and containing ctlSequence
+       *                     indicating value equal or higher than SN
+       *         }
+       *         then {
+       *             the IUT stops broadfcasting the Delta X_DISTRIBUTION
+       *                 signed with X_CERTIFICATE
+       *                 and containing ctlSequence (SN)
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_04_BV + * @reference ETSI TS 103 601, clause 5.4.4 + */ + testcase TC_SECPKI_ITSS_CTLDIST_04_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 or not PICS_UC_SEC_05_2) { + log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 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_CTLDIST_04_BV_itss()); + v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_04_BV_pki()); + + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + + // Cleanup + f_cfMtcDown03(v_itss, v_cpoc); + + } // End of testcase TC_SECPKI_ITSS_CTLDIST_04_BV + + group f_TC_SECPKI_ITSS_CTLDIST_04_BV { + + function f_broadcast_delta_ctl( + in charstring p_certificate_id, + out Ieee1609Dot2Data p_delta_ctl + ) runs on ItsPkiItss return GeoNetworkingPdu { + // Local variables + var GeoNetworkingPdu v_securedGnPdu; + + log(">>> f_broadcast_delta_ctl"); + + v_securedGnPdu := f_prepareSecuredCam(p_certificate_id, valueof(m_headerInfo_cam(-, (f_getCurrentTime() * 1000)/*us*/)), valueof(m_signerIdentifier_digest), f_getTsStationId()); + log("f_sendSecuredCam: v_securedGnPdu= ", v_securedGnPdu); + geoNetworkingPort.send(valueof(m_geoNwReq_linkLayerBroadcast(v_securedGnPdu))); + + return v_securedGnPdu; + } // End of function f_broadcast_delta_ctl + + function f_TC_SECPKI_ITSS_CTLDIST_04_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + // Local variables + var GeoNetworkingInd v_geonetworking_message; + var octetstring v_payload; + var Ieee1609Dot2Data v_delta_ctl; + + // 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 + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } + } // End of 'alt' statement + // Check that the IUT is boradcasting the Delta CTL + geoNetworkingPort.clear; + tc_ac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) -> value v_geonetworking_message { + tc_ac.stop; + + if (f_verify_and_extract_payload(v_geonetworking_message.msgIn, -, v_payload) == false) { + log("*** " & testcasename() & ": INCONC: Failed to verifiy payload ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + // TODO Check payload + if (substr(v_payload, 0, 2) == int2oct(2014, 2)) { // TODO Reorganize CAM/DENM/BTP test suites + log("*** " & testcasename() & ": INFO: Delta CTL was successfully broadcasted on the correct BTP port ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } else { + log("*** " & testcasename() & ": INCONC: Delta CTL was not broadcasted on BTP port 114 ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: Expected message not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Test Body + // Delta CTL boradcasting from another node + f_broadcast_delta_ctl(cc_ectl_rca_new, v_delta_ctl); + // Check that the IUT stops broadcasting Delta CTL + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive( + mw_geoNwInd( + mw_geoNwSecPdu( + mw_etsiTs103097Data_signed( + mw_signedData + )))) -> value v_geonetworking_message { + tc_noac.stop; + + if (f_verify_and_extract_payload(v_geonetworking_message.msgIn, -, v_payload) == false) { + log("*** " & testcasename() & ": INCONC: Failed to verifiy payload ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } else { + // TODO Check payload + if (substr(v_payload, 0, 2) == int2oct(2014, 2)) { // TODO Reorganize CAM/DENM/BTP test suites + log("*** " & testcasename() & ": FAIL: The IUT shall not continue Delta CTL broadcasting ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } else { + tc_noac.start; + repeat; + } + } + } + [] tc_noac.timeout { + log("*** " & testcasename() & ": PASS: IUT stops broadcasting Delta CTL ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); + } + } // End of 'alt' statement + + // Postamble + f_cfDown_itss(); + + } // End of function TC_SECPKI_ITSS_CTLDIST_04_BV_itss + + function f_TC_SECPKI_ITSS_CTLDIST_04_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_CTLDIST_04_BV_pki + + } // End of group f_TC_SECPKI_ITSS_CTLDIST_04_BV + + + + + + + + + + + + + + + + + + + + } // End of group itss_ctl_distribution + + group itss_crl_handling { + // TODO To be done after validation of itss_ctl_handling group as CTL and CRL are close + } // End of group itss_crl_handling + + group itss_crl_distribution { + // TODO To be done after validation of itss_ctl_distribution group as CTL and CRL are close + } // End of group itss_crl_distribution + + } // End of group itss_behavior + + group ca_behaviour { + + /** + * @desc Check that the issuing certificate has version 3 + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing version
+     *                     indicating value 3
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_01_BV + * @reference ETSI TS 103 097 [2], clause 6 + * IEEE Std 1609.2 [3], clause 6.4.3 + */ + testcase TC_SECPKI_CA_CERTGEN_01_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_01_BV + + /** + * @desc Check that the issuing certificate has type explicit + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         CA is initialized with the explicit certificate (CERT_IUT_A_CA)
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing version
+     *                     indicating value 3
+     *                 and containing type
+     *                      indicating 'explicit'
+     *                 and containing toBeSigned
+     *                      containing verifyKeyIndicator
+     *                          containing verificationKey
+     *                 and containing signature
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_02_BV_01 + * @reference ETSI TS 103 097 [2], clause 6 + * IEEE Std 1609.2 [3], clause 6.4.3 + */ + testcase TC_SECPKI_CA_CERTGEN_02_BV_01() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES)) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_02_BV_01 + + /** + * @desc Check that the CA, been authorized using explicit certificate, is able to issue an implicit certificate + *
+       * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES
+       * Initial conditions: 
+       *     with {
+       *         CA is in 'operational' state
+       *         CA is initialized with the explicit certificate (CERT_IUT_A_CA)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the CA is requested to issue the implicit certificate
+       *         }
+       *         then {
+       *             this certificate is of type EtsiTs103097Certificate
+       *                 containing version
+       *                     indicating value 3
+       *                 and containing type
+       *                      indicating 'implicit'
+       *                 and containing toBeSigned
+       *                      containing verifyKeyIndicator
+       *                          containing reconstructionValue
+       *                 and not containing signature
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_02_BV_02 + * @reference ETSI TS 103 097 [2], clause 6 + * IEEE Std 1609.2 [3], clause 6.4.3 + */ + testcase TC_SECPKI_CA_CERTGEN_02_BV_02() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) or not(PICS_SEC_IMPLICIT_CERTIFICATES)) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, true, true, true) == false) { // implicit, reconstructionKey and no signature + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_02_BV_02 + + /** + * @desc Check that the CA, been authorized using explicit certificate, is able to issue an implicit certificate + *
+       * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES
+       * Initial conditions: 
+       *     with {
+       *         CA is in 'operational' state
+       *         CA is initialized with the explicit certificate (CERT_IUT_I_AA)
+       *     }
+       * Expected behaviour:
+       *     ensure that {
+       *         when {
+       *             the CA is requested to issue the implicit certificate
+       *         }
+       *         then {
+       *             this certificate is of type EtsiTs103097Certificate
+       *                 containing version
+       *                     indicating value 3
+       *                 and containing type
+       *                      indicating 'implicit'
+       *                 and containing toBeSigned
+       *                      containing verifyKeyIndicator
+       *                          containing reconstructionValue
+       *                 and not containing signature
+       *         }
+       *     }
+       * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_02_BV_03 + * @reference ETSI TS 103 097 [2], clause 6 + * IEEE Std 1609.2 [3], clause 6.4.3 + */ + testcase TC_SECPKI_CA_CERTGEN_02_BV_03() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) or not(PICS_SEC_IMPLICIT_CERTIFICATES)) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate("CERT_IUT_I_AA", -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate("CERT_IUT_I_AA", v_root_certificate) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_02_BV_03 + + /** + * @desc Check that the CA, been authorized using implicit certificate, does not issue an explicit certificate + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         CA is initialized with the explicit certificate (CERT_IUT_I_AA)
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             the CA doesn’t issue the certificate
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_02_BO_01 + * @reference ETSI TS 103 097 [2], clause 6 + * IEEE Std 1609.2 [3], clause 6.4.3 + */ + testcase TC_SECPKI_CA_CERTGEN_02_BO_01() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) or not(PICS_SEC_IMPLICIT_CERTIFICATES)) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and PICS_SEC_IMPLICIT_CERTIFICATES required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + + // Test Body + v_result := f_get_root_ca_certificate("CERT_IUT_I_AA", true, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": PASS: No root certificate was generated ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + log("*** " & testcasename() & ": FAIL: Root certificate shll not be generated ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_02_BO_01 + + /** + * @desc Check that CA issues certificate conformed to ETSI TS 103 097 [1], clause 6 + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         CA is initialized with the explicit certificate (CERT_IUT_I_AA)
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBesigned
+     *                     containing id
+     *                          indicating 'none' or 'name'
+     *                 and containing cracaId
+     *                      indicating '000000'H
+     *                 and containing crlSeries
+     *                      indicating '0'D
+     *                 and not containing certRequestPermissions
+     *                 and not containing canRequestRollover
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_03_BV + * @reference ETSI TS 103 097 [2], clause 6 + */ + testcase TC_SECPKI_CA_CERTGEN_03_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate("CERT_IUT_I_AA", -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate("CERT_IUT_I_AA", v_root_certificate) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_03_BV + + /** + * @desc Check that the certificate issuer of certificates is referenced using digest + * Check that right digest field is used to reference to the certificate + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         CA is initialized with the explicit certificate (C_ISSUER)
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing issuer
+     *                     containing self
+     *                     or containing X_DIGEST
+     *                         indicating last 8 bytes of the hash of the certificate calculated using X_ALGORITHM
+     *                             referenced to certificate
+     *                 and containing toBeSigned
+     *                     containing verifyKeyIndicator
+     *                         containing verificationKey
+     *                             containing X_KEY
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_04_BV + * @reference ETSI TS 103 097 [2], clause 6 + */ + testcase TC_SECPKI_CA_CERTGEN_04_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var charstring v_authorized_certificate; + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1 and not PICS_SEC_BRAINPOOL_P384R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 or PICS_SEC_BRAINPOOL_P384R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_authorized_certificate := "CERT_IUT_I_AA"; + v_result := f_get_root_ca_certificate(v_authorized_certificate, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(v_authorized_certificate, v_root_certificate) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_04_BV + + /** + * @desc Check that the CA is able to issue the certificate with the well-formed circular region validity restriction + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_CIRCULAR_REGION
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         the CA is authorized with CA certificate 
+     *             containing toBeSigned
+     *                 containing region
+     *                     indicating REGION
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *                 containing circular region restriction
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing region
+     *                         containing circularRegion
+     *                             containing center
+     *                                 indicating a point inside the REGION
+     *                             and containing radius
+     *                                 indicating a value when all points of the circle are inside the REGION
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_05_BV + * @reference IEEE Std 1609.2 [2], clauses 6.4.20, 6.4.17, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_05_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_CIRCULAR_REGION) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_CIRCULAR_REGION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_05_BV + + /** + * @desc Check that the CA is able to issue the certificate with the well-formed rectangular region validity restriction + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_RECTANGULAR_REGION
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         the CA is authorized with CA certificate 
+     *             containing toBeSigned
+     *                 containing region
+     *                     indicating REGION
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *                 containing rectangular region restriction
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing region
+     *                         containing rectangularRegion
+     *                             containing items of type RectangularRegion
+     *                                containing northwest
+     *                                     indicating a point inside the REGION
+     *                                 and containing southeast
+     *                                     indicating a point on the south and east from northwest
+     *                                     and inside the REGION
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_06_BV + * @reference IEEE Std 1609.2 [2], clauses 6.4.20, 6.4.17, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_06_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_RECTANGULAR_REGION) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_RECTANGULAR_REGION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_06_BV + + /** + * @desc Check that the CA is able to issue the certificate with the well-formed polygonal region validity restriction + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_POLYGONAL_REGION
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         the CA is authorized with CA certificate 
+     *             containing toBeSigned
+     *                 containing region
+     *                     indicating REGION
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *                 containing polygonal region restriction
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing region
+     *                         containing polygonalRegion
+     *                             containing more than 2 items of type TwoDLocation
+     *                                indicating points inside the REGION
+     *                                 and indicating unintercepting segments
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_07_BV + * @reference IEEE Std 1609.2 [2], clauses 6.4.20, 6.4.17, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_07_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_POLYGONAL_REGION) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_POLYGONAL_REGION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_07_BV + + /** + * @desc Check that the CA is able to issue the certificate with identified region validity restriction contains values that correspond to numeric country codes as defined by United Nations Statistics Division [5] + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_IDENTIFIED_REGION
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         the CA is authorized with CA certificate 
+     *             containing toBeSigned
+     *                 containing region
+     *                     indicating REGION
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *                 containing identified region validity restriction
+     *                     indicating country or area COUNTRY
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing region
+     *                         containing identifiedRegion
+     *                             containing 1 entry of type IdentifiedRegion
+     *                                 containing countryOnly
+     *                                     indicating integer representation of the identifier of country or area COUNTRY
+     *                             or containing countryAndRegions
+     *                                 containing countryOnly
+     *                                     indicating integer representation of the identifier of country or area COUNTRY
+     *                             or containing countryAndSubregions
+     *                                 containing country
+     *                                     indicating integer representation of the identifier of country or area COUNTRY
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_08_BV + * @reference IEEE Std 1609.2 [2], clauses 6.4.23 + */ + testcase TC_SECPKI_CA_CERTGEN_08_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_IDENTIFIED_REGION) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_IDENTIFIED_REGION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_08_BV + + /** + * @desc Check that the identified region validity restriction of the subordinate certificate is included in the identified region validity restriction of the issuing certificate + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_IDENTIFIED_REGION
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         the CA is authorized with CA certificate
+     *             containing toBeSigned
+     *                 containing region
+     *                     containing identifiedRegion
+     *                         containing countryOnly
+     *                             indicating COUNTRY
+     *                          or containing countryAndRegions
+     *                             containing countryOnly
+     *                          indicating COUNTRY
+     *                             and containing regions
+     *                                indicating REGIONS
+     *                          or containing countryAndSubregions
+     *                             containing country
+     *                                indicating COUNTRY
+     *                             and containing regionAndSubregions
+     *                                indicating REGIONS and SUBREGIONS
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the certificate
+     *                 containing identifiedRegion
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing region
+     *                         containing identifiedRegion
+     *                             containing countryOnly
+     *                                 indicating value = COUNTRY
+     *                             or containing countryAndRegions
+     *                                 containing countryOnly
+     *                                    indicating value = COUNTRY
+     *                             and containing regions
+     *                                 containing region identifiers contained in REGIONS
+     *                             or containing countryAndSubregions
+     *                                 containing country
+     *                                    indicating value = COUNTRY
+     *                                 and containing regionAndSubregions
+     *                                    containing region identifiers contained in REGIONS
+     *                                    and containing subRegion identifiers contained in SUBREGIONS for every region
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_09_BV + * @reference IEEE Std 1609.2 [2], clauses 6.4.17, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_09_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if (not PICS_IUT_CA_ROLE and not PICS_SEC_IDENTIFIED_REGION) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_IDENTIFIED_REGION required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_09_BV + + /** + * @desc Check that the certificate signature contains ECC point of type set to either compressed_lsb_y_0, compressed_lsb_y_1 or x_coordinate_only + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing signature
+     *                     containing X_SIGNATURE
+     *                         containing rSig
+     *                             containing x-only
+     *                             or containing compressed-y-0
+     *                             or containing compressed-y-1
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_10_BV + * @reference IEEE Std 1609.2 [3], clause 6.3.29, 6.3.30, 6.3.31 + */ + testcase TC_SECPKI_CA_CERTGEN_10_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1 and not PICS_SEC_BRAINPOOL_P384R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 or PICS_SEC_BRAINPOOL_P384R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_10_BV + + /** + * @desc Check that the certificate verification key contains ECC point of type set to either compressed_lsb_y_0, compressed_lsb_y_1 or uncompressed + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing verifyKeyIndicator
+     *                     containing verificationKey
+     *                         containing X_KEY
+     *                             containing x-only
+     *                             or containing compressed-y-0
+     *                             or containing compressed-y-1
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_11_BV + * @reference IEEE Std 1609.2 [3], clause 6.3.38 + */ + testcase TC_SECPKI_CA_CERTGEN_11_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1 and not PICS_SEC_BRAINPOOL_P384R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 or PICS_SEC_BRAINPOOL_P384R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_11_BV + + /** + * @desc Check that the certificate encryption key contains ECC point of type set to either compressed_lsb_y_0, compressed_lsb_y_1 or uncompressed + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing encryptionKey
+     *                         containing publicKey
+     *                             containing X_KEY
+     *                                 containing uncompressed
+     *                                 or containing compressed-y-0
+     *                                 or containing compressed-y-1
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_12_BV + * @reference IEEE Std 1609.2 [3], clause 6.3.38 + */ + testcase TC_SECPKI_CA_CERTGEN_12_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_12_BV + + /** + * @desc Check the explicit certificate signature + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         and the CA is authorized with explicit certificate
+     *             containing toBeSigned
+     *                 containing verifyKeyIndicator
+     *                     containing verificationKey
+     *                         containing X_KEY
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is requested to issue the explicit certificate
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing issuer
+     *                     referencing the certificate
+     *                         containing toBeSigned
+     *                             containing verifyKeyIndicator
+     *                                 containing verificationKey
+     *                                     containing X_KEY
+     *                                         indicating KEY
+     *                 and containing signature
+     *                     containing X_SIGNATURE
+     *                         verifiable using KEY
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_13_BV_01 + * @reference ETSI TS 103 097 [1], clause 6 + */ + testcase TC_SECPKI_CA_CERTGEN_13_BV_01() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1 and not PICS_SEC_BRAINPOOL_P384R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 or PICS_SEC_BRAINPOOL_P384R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_13_BV_01 + + /** + * @desc Check the explicit certificate signature + *
+     * Pics Selection: PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         and the CA is authorized with explicit certificate
+     *             containing toBeSigned
+     *                 containing verifyKeyIndicator
+     *                     containing verificationKey
+     *                         containing X_KEY
+     *         and the CA issued the implicit certificate of type EtsiTs103097Certificate (CERT)
+     *             not containing signature
+     *             and containing issuer
+     *                 referencing the certificate
+     *                     containing toBeSigned
+     *                         containing verifyKeyIndicator
+     *                             containing reconstructionValue
+     *                                 indicating VALUE
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA is calculated the digital signature
+     *                 using the private key associated with the CERT
+     *         }
+     *         then {
+     *             this signature can be verified using public key
+     *                 reconstructed using VALUE and KEY
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_13_BV_02 + * @reference ETSI TS 103 097 [1], clause 6 + */ + testcase TC_SECPKI_CA_CERTGEN_13_BV_02() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // Test control + if ((not PICS_IUT_CA_ROLE) or not(PICS_SEC_EXPLICIT_CERTIFICATES) and not PICS_SEC_SHA256 and not PICS_SEC_BRAINPOOL_P256R1 and not PICS_SEC_BRAINPOOL_P384R1) { + log("*** " & testcasename() & ": PICS_IUT_CA_ROLE and PICS_SEC_EXPLICIT_CERTIFICATES and (PICS_SEC_SHA256 or PICS_SEC_BRAINPOOL_P256R1 or PICS_SEC_BRAINPOOL_P384R1 required for executing the TC ***"); + setverdict(inconc); + stop; + } + + // Test component configuration + f_connect4SelfOrClientSync(); + + // Test adapter configuration + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, true, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_13_BV_02 + + /** + * @desc Check that all PSID entries of the appPermissions component of the certificate are unique + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA issued the certificate
+     *                 containing toBeSigned
+     *                     containing appPermissions
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing appPermissions
+     *                         containing items of type PsidSsp
+     *                             containing psid
+     *                                 indicating unique values in this sequence
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_14_BV + * @reference ETSI TS 103 097 [1], clauses 6.4.28, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_14_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_14_BV + + /** + * @desc Check that all PSID entries of the appPermissions component of the certificate are also contained in the certIssuePermissions component in the issuing certificate + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA issued the certificate
+     *                 containing toBeSigned
+     *                     containing appPermissions
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing issuer
+     *                     referenced to the certificate
+     *                         containing toBeSigned
+     *                             containing certIssuePermissions
+     *                                 containing items of type PsidGroupPermissions
+     *                                     containing eeType
+     *                                         indicating app(0)
+     *                                     and containing subjectPermissions
+     *                                         containing explicit
+     *                                             containing items of type PsidSspRange
+     *                                                 indicating X_PSID_RANGE_LIST
+     *                                         or containing all
+     *                         and containing toBeSigned
+     *                             containing appPermissions
+     *                                 containing items of type PsidSsp
+     *                                     containing psid
+     *                                         contained in the X_PSID_RANGE_LIST
+     *                                             as a psid
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_15_BV + * @reference ETSI TS 103 097 [1], clauses 6.4.28, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_15_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_15_BV + + /** + * @desc Check that all PSID entries of the certIssuePermissions component of the certificate are unique + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA issued the certificate
+     *                 containing toBeSigned
+     *                     containing certIssuePermissions
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing issuer
+     *                     containing toBeSigned
+     *                         containing certIssuePermissions
+     *                             containing items of type PsidGroupPermissions
+     *                                 containing subjectPermissions
+     *                                     containing explicit
+     *                                     and containing items of type PsidSspRange
+     *                                         containing psid
+     *                                             indicating unique values in this sequence
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_16_BV + * @reference ETSI TS 103 097 [1], clauses 6.4.28, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_16_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_16_BV + + /** + * @desc Check that SSP field in each entry of the appPermissions component of the AT certificate is equal to or a subset of the SSP Range in the corresponding issuing entry + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA issued the certificate
+     *                 containing toBeSigned
+     *                     containing certIssuePermissions
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing issuer
+     *                     referenced to the certificate
+     *                         containing toBeSigned
+     *                             containing certIssuePermissions
+     *                                 containing items of type PsidGroupPermissions
+     *                                       containing eeType
+     *                                         indicating app(0)
+     *                                       and containing subjectPermissions
+     *                                         containing explicit
+     *                                             containing items of type PsidSspRange
+     *                                                 containing psid
+     *                                                     indicating X_PSID_AA
+     *                                                 containing sspRange
+     *                                                     indicating X_SSP_AA [ X_PSID_AA ]
+     *                                             or containing all
+     *                 and containing toBeSigned
+     *                         containing appPermissions
+     *                             containing items of type PsidSsp
+     *                                 containing psid
+     *                                     indicating value equal to X_PSID_AA
+     *                                 containing ssp
+     *                                     indicating value permitted by X_SSP_AA [ X_PSID_AA ]
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_17_BV + * @reference ETSI TS 103 097 [1], clauses 6.4.28, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_17_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_17_BV + + /** + * @desc Check that the validityPeriod of the subordinate certificate is inside the validityPeriod of the issuing certificate + *
+     * Pics Selection: PICS_IUT_CA_ROLE
+     * Initial conditions: 
+     *     with {
+     *         CA is in 'operational' state
+     *         and the CA is authorized with CA certificate
+     *             containing toBeSigned
+     *                 containing validityPeriod
+     *                     containing start
+     *                         indicating X_START_VALIDITY_CA
+     *                     containing duration
+     *                         indicating X_DURATION_CA
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the CA issued the certificate
+     *                 containing toBeSigned
+     *                     containing certIssuePermissions
+     *         }
+     *         then {
+     *             this certificate is of type EtsiTs103097Certificate
+     *                 containing toBeSigned
+     *                     containing validityPeriod
+     *                         containing start
+     *                             indicating X_START_VALIDITY ( X_START_VALIDITY >= X_START_VALIDITY_CA )
+     *                         and containing duration
+     *                             indicating value <= X_START_VALIDITY_CA + X_DURATION_CA - X_START_VALIDITY
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 v1.1.4 SECPKI_CA_CERTGEN_18_BV + * @reference ETSI TS 103 097 [1], clauses 6.4.28, 5.1.2.4 + */ + testcase TC_SECPKI_CA_CERTGEN_18_BV() runs on ItsMtc system ItsPkiHttpSystem { + // Local variables + var integer v_result; + var Certificate v_root_certificate; + + // 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_connect4SelfOrClientSync(); + + // Test adapter configuration + if (not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { + log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); + stop; + } + + // Preamble + v_result := f_get_root_ca_certificate(-, -, v_root_certificate); + if (v_result == -1) { + log("*** " & testcasename() & ": INCONC: Fail to retrive the RCA ***"); + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); + } else { + f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); + } + + // Test Body + if (f_verify_rca_certificate(-, v_root_certificate, -, -, -, -, -, -, -, true) == false) { + log("*** " & testcasename() & ": FAIL: Failed to verify RCA message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + log("*** " & testcasename() & ": PASS: ToBeSignedRcaCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } + + // Postamble + f_disconnect4SelfOrClientSync(); + + } // End of testcase TC_SECPKI_CA_CERTGEN_18_BV + + } // End of group ca_behaviour + + 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 + + group cpoc_behavior { + + /** + * @desc Check that the TLM CTL is published and accessible when issued + *
+     * Pics Selection: 
+     * Initial conditions: 
+     *         the TLM issued a new CTL
+     *     }
+     * Expected behaviour:
+     *     ensure that {
+     *         when {
+     *             the ITS-S asked the IUT for the newly issued CTL
+     *         }
+     *         then {
+     *             the IUT is answered with this CTL
+     *         }
+     *     }
+     * 
+ * + * @see ETSI TS 103 525-2 TP SECPKI_CPOC_LISTDIST_01_BV + * @reference ETSI TS 102 941, Clauses 6.3.2 and 6.3.3 + */ + testcase TC_SECPKI_CPOC_LISTDIST_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem { + // Local variable + var Headers v_headers; + var HttpMessage v_response; + + // Test component configuration + f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); + + // Test adapter configuration + + // Preamble + f_init_default_headers_list(-, "cpoc_request", v_headers); + f_http_send( + v_headers, + m_http_request( + m_http_request_get( + PICS_HTTP_GET_URI_ECTL, + v_headers + ))); + f_selfOrClientSyncAndVerdict(c_prDone, e_success); + + // Test Body + 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 + ) + ))))))) -> 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 ECTL message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ectl(v_to_be_signed_tlm_ectl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedTlmCtl received ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); + } else { + log("*** " & testcasename() & ": FAIL: Receive unexpected message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } + } + } + [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 + ) + ))))))) -> 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 ECTL message ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error); + } else { + if (f_verify_full_ectl(v_to_be_signed_tlm_ectl) == true) { + log("*** " & testcasename() & ": PASS: ToBeSignedTlmCtl 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_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of testcase TC_SECPKI_CPOC_LISTDIST_01_BV + + } // End of group cpoc_behavior + +} // End of module ItsPki_TestCases diff --git a/ItsPki_TestControl.ttcn b/ItsPki_TestControl.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..9ac3e721510c359bdcb835636f5a966f6ec021d3 --- /dev/null +++ b/ItsPki_TestControl.ttcn @@ -0,0 +1,123 @@ +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_CA_ROLE) { + execute(TC_SECPKI_CA_CERTGEN_01_BV()); + execute(TC_SECPKI_CA_CERTGEN_02_BV_01()); + execute(TC_SECPKI_CA_CERTGEN_02_BV_02()); + execute(TC_SECPKI_CA_CERTGEN_02_BV_03()); + execute(TC_SECPKI_CA_CERTGEN_02_BO_01()); + execute(TC_SECPKI_CA_CERTGEN_03_BV()); + execute(TC_SECPKI_CA_CERTGEN_04_BV()); + execute(TC_SECPKI_CA_CERTGEN_05_BV()); + execute(TC_SECPKI_CA_CERTGEN_06_BV()); + execute(TC_SECPKI_CA_CERTGEN_07_BV()); + execute(TC_SECPKI_CA_CERTGEN_08_BV()); + execute(TC_SECPKI_CA_CERTGEN_09_BV()); + execute(TC_SECPKI_CA_CERTGEN_10_BV()); + execute(TC_SECPKI_CA_CERTGEN_11_BV()); + execute(TC_SECPKI_CA_CERTGEN_12_BV()); + execute(TC_SECPKI_CA_CERTGEN_13_BV_01()); + execute(TC_SECPKI_CA_CERTGEN_13_BV_02()); + execute(TC_SECPKI_CA_CERTGEN_14_BV()); + execute(TC_SECPKI_CA_CERTGEN_15_BV()); + } + + 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 100644 index 0000000000000000000000000000000000000000..95d146653bd5fe09f0a755302135b4f9a60d1acc --- /dev/null +++ b/lib/LibItsPki_EncdecDeclarations.ttcn @@ -0,0 +1,144 @@ +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 EtsiTs102941TrustLists language "ASN.1:1997" all; + + // LibItsPki + 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)"} + + external function fx_enc_CtlFormat(in EtsiTs102941TrustLists.CtlFormat p) return bitstring + with {extension "prototype(convert) encode(PER)"} + + external function fx_dec_CtlFormat(inout bitstring b, out EtsiTs102941TrustLists.CtlFormat p) return integer + with {extension "prototype(sliding) decode(PER)"} + +} // End of module LibItsPki_EncdecDeclarations diff --git a/lib/LibItsPki_Pics.ttcn b/lib/LibItsPki_Pics.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..090018b9b3c40dbbcbd38d1d9cfbb1c0cfb8853b --- /dev/null +++ b/lib/LibItsPki_Pics.ttcn @@ -0,0 +1,261 @@ +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_CA := "/dc/getctl"; + + /** + * @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; + + modulepar boolean PICS_SEC_IMPLICIT_CERTIFICATES := false; + + modulepar boolean PICS_SEC_EXPLICIT_CERTIFICATES := true; + + modulepar boolean PICS_UC_SEC_05_2 := true; + +} // End of module LibItsPki_Pics diff --git a/lib/LibItsPki_Pixits.ttcn b/lib/LibItsPki_Pixits.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..1bf0d04a2f6f7e3c7f6fd3ec33af4aa02de06f41 --- /dev/null +++ b/lib/LibItsPki_Pixits.ttcn @@ -0,0 +1,81 @@ +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; + + modulepar integer PX_AUTH_MAX_N1 := 10; + +} // End of module LibItsPki_Pixits diff --git a/lib/LibItsPki_Templates.ttcn b/lib/LibItsPki_Templates.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..749599af716f9a6f831cb9c773596f3f191092a3 --- /dev/null +++ b/lib/LibItsPki_Templates.ttcn @@ -0,0 +1,755 @@ +/** + * @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 template (value) 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_full_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_full_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) ToBeSignedTlmCtl m_to_be_signed_tlm_full_ctl( + in Time32 p_next_update, + in UInt8 p_ctl_sequence, + in template (value) 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_tlm_full_ctl + + template (value) ToBeSignedTlmCtl m_to_be_signed_tlm_delta_ctl( + in Time32 p_next_update, + in UInt8 p_ctl_sequence, + in template (value) CtlCommands p_ctl_commands + ) := { + version := 1, + nextUpdate := p_next_update, + isFullCtl := false, + ctlSequence := p_ctl_sequence, + ctlCommands := p_ctl_commands + } // End of template m_to_be_signed_tlm_delta_ctl + + template (present) ToBeSignedTlmCtl mw_to_be_signed_tlm_full_ctl( + template (present) Time32 p_next_update := ?, + template (present) UInt8 p_ctl_sequence := ?, + template (present) CtlCommands p_ctl_commands := ? + ) := { + version := 1, + nextUpdate := p_next_update, + isFullCtl := true, + ctlSequence := p_ctl_sequence, + ctlCommands := p_ctl_commands + } // End of template mw_to_be_signed_tlm_full_ctl + + template (present) ToBeSignedTlmCtl mw_to_be_signed_tlm_delta_ctl( + template (present) Time32 p_next_update := ?, + template (present) UInt8 p_ctl_sequence := ?, + template (present) CtlCommands p_ctl_commands := ? + ) := { + version := 1, + nextUpdate := p_next_update, + isFullCtl := false, + ctlSequence := p_ctl_sequence, + ctlCommands := p_ctl_commands + } // End of template mw_to_be_signed_tlm_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 (value) CtlCommand m_ctrl_command_add( + in template (value) CtlEntry p_add + ) := { + add := p_add + } // End of template m_ctrl_command_add + + template (value) CtlCommand m_ctrl_command_delete( + in template (value) CtlDelete p_delete + ) := { + delete := p_delete + } // End of template m_ctrl_command_delete + + template (value) CtlEntry m_ctl_entry_rca( + in template (value) RootCaEntry p_rca + ) := { + rca := p_rca + } // End of template m_ctl_entry_rca + + template (present) CtlEntry mw_ctl_entry_rca( + template (present) RootCaEntry p_rca := ? + ) := { + rca := p_rca + } // End of template mw_ctl_entry_rca + + template (value) CtlEntry m_ctl_entry_aa( + in template (value) AaEntry p_aa + ) := { + aa := p_aa + } // End of template m_ctl_entry_aa + + template (present) CtlEntry mw_ctl_entry_aa( + template (present) AaEntry p_aa := ? + ) := { + aa := p_aa + } // End of template mw_ctl_entry_aa + + template (present) TlmEntry mw_tlm_entry( + template (present) EtsiTs103097Certificate p_selfSignedTLMCertificate := ?, + template (present) Url p_accessPoint := ? + ) := { + selfSignedTLMCertificate := p_selfSignedTLMCertificate, + 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, + successorTo := omit + } // End of template m_root_ca_entry + + template (present) RootCaEntry mw_root_ca_entry( + template (present) EtsiTs103097Certificate p_selfsignedRootCa := ? + ) := { + selfsignedRootCa := p_selfsignedRootCa, + successorTo := * + } // End of template mw_root_ca_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 (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 (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_TypesAndValues.ttcn b/lib/LibItsPki_TypesAndValues.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..78c40e72540631a196d1c439da440e3d08763f95 --- /dev/null +++ b/lib/LibItsPki_TypesAndValues.ttcn @@ -0,0 +1,175 @@ +/** + * @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; + + // LibItsGeoNetworking + import from LibItsGeoNetworking_TypesAndValues all; + + group constants { + + const integer PkiProtocolVersion := 1; + + const charstring cc_ectl_rca_new := "CERT_RCA_NEW"; + const charstring cc_ectl_rca_untrust := "CERT_RCA_UNTRUST"; + const charstring cc_ectl_aa_new := "CERT_AA_NEW"; + + } // 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, + TriggerUpdateEctl triggerUpdateEctl, + TriggerRequestForTlmCtl triggerRequestForTlmCtl, + TriggerRequestForRcaCtl triggerRequestForRcaCtl + } 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 + + type record TriggerUpdateEctl { + charstring ectl_uri + } // End of type TriggerUpdateEctl + + type record TriggerRequestForTlmCtl { + charstring tlm_ctl_uri + } // End of type TriggerRequestForTlmCtl + + type record TriggerRequestForRcaCtl { + charstring tlm_ctl_uri + } // End of type TriggerRequestForRcaCtl + + } 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 0000000000000000000000000000000000000000..39a50de38ac029c554bb832609d1a3f128279bc4 --- /dev/null +++ b/lib/asn1 @@ -0,0 +1 @@ +Subproject commit 39a50de38ac029c554bb832609d1a3f128279bc4 diff --git a/lib/module.mk b/lib/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..bfcd5657935fc737d6884d26e4563219cd8dfe05 --- /dev/null +++ b/lib/module.mk @@ -0,0 +1,29 @@ +sources := LibItsPki_EncdecDeclarations.ttcn \ + LibItsPki_Pics.ttcn \ + LibItsPki_Pixits.ttcn \ + LibItsPki_Templates.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/lib_system/LibItsPki_Functions.ttcn b/lib_system/LibItsPki_Functions.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..a5f95110c32004900be8a8bff0bdb0153a24f493 --- /dev/null +++ b/lib_system/LibItsPki_Functions.ttcn @@ -0,0 +1,5475 @@ +/** + * @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 + + function f_cfMtcUp03( + out ItsPkiHttp p_itss, + out ItsPkiHttp p_tlm + ) runs on ServerSyncComp { + p_itss := ItsPkiItss.create("ITS-S") alive; + p_tlm := ItsPkiHttp.create("TLM") alive; + + connect(self:syncPort, mtc:syncPort); + connect(p_itss:syncPort, self:syncPort); + connect(p_tlm:syncPort, self:syncPort); + } // End of function f_cfMtcUp03 + + function f_cfMtcUp04( + out ItsPkiHttp p_itss, + out ItsPkiHttp p_dc + ) runs on ServerSyncComp { + p_itss := ItsPkiItss.create("ITS-S") alive; + p_dc := ItsPkiHttp.create("DC") alive; + + connect(self:syncPort, mtc:syncPort); + connect(p_itss:syncPort, self:syncPort); + connect(p_dc:syncPort, self:syncPort); + } // End of function f_cfMtcUp04 + + /** + * @desc Setups default configuration + * @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT + */ + function f_cfHttpUp( + in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant + in charstring p_aa_certificate_id := "CERT_TS_A_AA" + ) runs on ItsPkiHttp system ItsPkiHttpSystem { + + if (PICS_MULTIPLE_END_POINT == false) { + map(self:httpPort, system:httpPort); + } else { + map(self:httpEcPort, system:httpEcPort); + map(self:httpAtVPort, system:httpAtVPort); + map(self:httpAtPort, system:httpAtPort); + } + f_connect4SelfOrClientSync(); + + f_initialiseSecuredMode(p_ea_certificate_id, p_aa_certificate_id); // TODO To be removed??? + + // TODO Duplicate code, use a function + + // Setup EA certificate shared with PKI EA entity + f_readCertificate(p_ea_certificate_id, vc_eaCertificate); + f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed + f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); + f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8); + f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash); + f_getCertificateHash256(p_ea_certificate_id, vc_eaWholeHash256); + log("f_cfHttpUp: vc_eaPrivateKey= ", vc_eaPrivateKey); + log("f_cfHttpUp: vc_eaPrivateEncKey= ", vc_eaPrivateEncKey); + log("f_cfHttpUp: vc_eaHashedId8= ", vc_eaHashedId8); + log("f_cfHttpUp: vc_eaWholeHash= ", vc_eaWholeHash); + log("f_cfHttpUp: vc_eaWholeHash256= ", vc_eaWholeHash256); + + // Setup AA certificate shared with PKI AA entity + f_readCertificate(p_aa_certificate_id, vc_aaCertificate); + f_readSigningKey(p_aa_certificate_id, vc_aaPrivateKey); // Required for AuthorizationValidation request + f_readEncryptingKey(p_aa_certificate_id, vc_aaPrivateEncKey); + f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8); + f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash); + f_getCertificateHash256(p_aa_certificate_id, vc_aaWholeHash256); + log("f_cfHttpUp: vc_aaPrivateKey= ", vc_aaPrivateKey); + log("f_cfHttpUp: vc_aaPrivateEncKey= ", vc_aaPrivateEncKey); + log("f_cfHttpUp: vc_aaHashedId8= ", vc_aaHashedId8); + log("f_cfHttpUp: vc_aaWholeHash= ", vc_aaWholeHash); + log("f_cfHttpUp: vc_aaWholeHash256= ", vc_aaWholeHash256); + + // Storage of enrolment keys in case of re-enrolment + vc_ec_keys_counter := 0; + vc_ec_private_keys := {}; + vc_ec_public_compressed_key := {}; + vc_ec_compressed_modes := {}; + vc_ec_hashed_id8 := {}; + vc_ec_certificates := {}; + + if (PICS_MULTIPLE_END_POINT == false) { + activate(a_default_pki_http()); + } else { + activate(a_default_pki_http_ec()); + activate(a_default_pki_http_atv()); + activate(a_default_pki_http_at()); + } + } // End of function f_cfHttpUp + + /** + * @desc Setups default configuration + */ + function f_cfHttpUp_ca() runs on ItsPkiHttp system ItsPkiHttpSystem { // FIXME Rename into f_cfHttpUp_rca_dc + + if (PICS_MULTIPLE_END_POINT == false) { + map(self:httpPort, system:httpPort); + } else { + map(self:httpCaPort, system:httpCaPort); + } + f_connect4SelfOrClientSync(); + + f_initialiseSecuredMode(); + + if (PICS_MULTIPLE_END_POINT == false) { + activate(a_default_pki_http()); + } else { + activate(a_default_pki_http_ca()); + } + } // End of function f_cfHttpUp_ca + + /** + * @desc Setups default configuration + */ + function f_cfHttpUp_tlm() runs on ItsPkiHttp system ItsPkiHttpSystem { // FIXME Rename into f_cfHttpUp_cpoc + + if (PICS_MULTIPLE_END_POINT == false) { + map(self:httpPort, system:httpPort); + } else { + map(self:httpTlmPort, system:httpTlmPort); + } + f_connect4SelfOrClientSync(); + + f_initialiseSecuredMode(); + + if (PICS_MULTIPLE_END_POINT == false) { + activate(a_default_pki_http()); + } else { + activate(a_default_pki_http_tlm()); + } + } // End of function f_cfHttpUp_tlm + + /** + * @desc Setups default configuration + * @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT + */ + function f_cfHttpUp_itss( + in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant + in charstring p_aa_certificate_id := "CERT_TS_A_AA" + ) runs on ItsPkiHttp system ItsPkiHttpSystem { + + if (PICS_MULTIPLE_END_POINT == false) { + map(self:httpPort, system:httpPort); + } else { + map(self: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; + } + + function f_cfMtcDown03( + inout ItsPkiHttp p_itss, + inout ItsPkiHttp p_tlm + ) runs on ServerSyncComp { + disconnect(self:syncPort, mtc:syncPort); + disconnect(p_itss:syncPort, self:syncPort); + disconnect(p_tlm:syncPort, self:syncPort); + + p_itss.done; + p_tlm.done; + } + + function f_cfMtcDown04( + inout ItsPkiHttp p_itss, + inout ItsPkiHttp p_dc + ) runs on ServerSyncComp { + disconnect(self:syncPort, mtc:syncPort); + disconnect(p_itss:syncPort, self:syncPort); + disconnect(p_dc:syncPort, self:syncPort); + + p_itss.done; + p_dc.done; + } + + /** + * @desc Deletes default configuration + */ + function f_cfHttpDown() runs on ItsPkiHttp { + if (PICS_MULTIPLE_END_POINT == false) { + unmap(self:httpPort, system:httpPort); + } else { + unmap(self:httpEcPort, system:httpEcPort); + unmap(self:httpAtVPort, system:httpAtVPort); + unmap(self:httpAtPort, system:httpAtPort); + } + f_disconnect4SelfOrClientSync(); + f_uninitialiseSecuredMode(); + } // End of function f_cfHttpDown + + /** + * @desc Deletes default configuration + */ + function f_cfHttpDown_ca() runs on ItsPkiHttp { + if (PICS_MULTIPLE_END_POINT == false) { + unmap(self:httpPort, system:httpPort); + } else { + unmap(self:httpCaPort, system:httpCaPort); + } + f_disconnect4SelfOrClientSync(); + f_uninitialiseSecuredMode(); + } // End of function f_cfHttpDown_ca + + /** + * @desc Deletes default configuration + */ + function f_cfHttpDown_tlm() runs on ItsPkiHttp { + if (PICS_MULTIPLE_END_POINT == false) { + unmap(self:httpPort, system:httpPort); + } else { + unmap(self:httpTlmPort, system:httpTlmPort); + } + f_disconnect4SelfOrClientSync(); + f_uninitialiseSecuredMode(); + } // End of function f_cfHttpDown_tlm + + /** + * @desc Deletes default configuration + */ + function f_cfHttpDown_itss() runs on ItsPkiHttp { + if (PICS_MULTIPLE_END_POINT == false) { + unmap(self:httpPort, system:httpPort); + } else { + unmap(self: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 + + function f_sendUtTriggerUpdateEctl(template (value) charstring p_ectl_uri) runs on ItsPkiItss { + utPort.send(UtPkiTrigger: { triggerUpdateEctl := { ectl_uri := p_ectl_uri } }); + tc_wait.start; + alt { + [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { + tc_wait.stop; + log("*** f_sendUtTriggerUpdateEctl: INFO: IUT has updated ECTL ***"); + } + [] utPort.receive { + tc_wait.stop; + log("*** f_sendUtTriggerUpdateEctl: INFO: IUT could not update ECTL ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + [] tc_wait.timeout { + log("*** f_sendUtTriggerUpdateEctl: INFO: IUT could not update ECTL in time ***"); + f_selfOrClientSyncAndVerdict("error", e_timeout); + } + } + + } // End of function f_sendUtTriggerUpdateEctl + + function f_sendUtTriggerRequestForTlmCtl(template (value) charstring p_tlm_ctl_uri) runs on ItsPkiItss { + utPort.send(UtPkiTrigger: { triggerRequestForTlmCtl := { tlm_ctl_uri := p_tlm_ctl_uri } }); + tc_wait.start; + alt { + [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { + tc_wait.stop; + log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT has updated ECTL ***"); + } + [] utPort.receive { + tc_wait.stop; + log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT could not update ECTL ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + [] tc_wait.timeout { + log("*** f_sendUtTriggerRequestForTlmCtl: INFO: IUT could not update ECTL in time ***"); + f_selfOrClientSyncAndVerdict("error", e_timeout); + } + } + + } // End of function f_sendUtTriggerRequestForTlmCtl + + function f_sendUtTriggerRequestForRcaCtl(template (value) charstring p_tlm_ctl_uri) runs on ItsPkiItss { + utPort.send(UtPkiTrigger: { triggerRequestForRcaCtl := { tlm_ctl_uri := p_tlm_ctl_uri } }); + tc_wait.start; + alt { + [] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) { + tc_wait.stop; + log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT has updated ECTL ***"); + } + [] utPort.receive { + tc_wait.stop; + log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT could not update ECTL ***"); + f_selfOrClientSyncAndVerdict("error", e_error); + } + [] tc_wait.timeout { + log("*** f_sendUtTriggerRequestForRcaCtl: INFO: IUT could not update ECTL in time ***"); + f_selfOrClientSyncAndVerdict("error", e_timeout); + } + } + + } // End of function f_sendUtTriggerRequestForRcaCtl + + } // End of group ut_port + + group helpers { + + function f_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; + } + + /** + * @desc this function is used to retrieve the root certificate from SubCA entity + * @param p_certificate The root certificate + * @return 0 on success, -1 otherwise + */ + external function fx_get_root_ca_certificate( + in charstring p_iut_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_CA", + in boolean p_explicit_type := false, + out octetstring p_certificate + ) return integer; + + function f_get_root_ca_certificate( + in charstring p_iut_certificate := "CERT_IUT_A_CA", + in boolean p_explicit_type := false, + out Certificate p_certificate + ) return integer { + var octetstring v_os; + var bitstring v_msg_bit; + + log(">>> f_get_root_ca_certificate"); + + // Get root certificate + if (fx_get_root_ca_certificate(p_iut_certificate, p_explicit_type, v_os) != 0) { + log("f_get_root_ca_certificate: fail to get certificate"); + return -1; + } + log("f_get_root_ca_certificate: v_os=", v_os); + // Decode it + v_msg_bit := oct2bit(v_os); + if (decvalue(v_msg_bit, p_certificate) != 0) { + log("f_get_root_ca_certificate: fail to decode certificate"); + return -1; + } + log("<<< f_get_root_ca_certificate: ", p_certificate); + return 0; + } + + function f_verify_rca_certificate( + in charstring p_authorized_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_RCA", + in Certificate p_certificate, + in boolean p_check_implicit := false, + in boolean p_check_reconstruction_value := false, + in boolean p_check_no_signature := false, + in boolean p_check_region_restriction := false, + in boolean p_check_signature_content := false, + in boolean p_check_app_permissions := false, + in boolean p_check_app_ssps := false, + in boolean p_check_app_validity_period := false + ) return boolean { + var CertificateType v_type_ := explicit; + var template Signature v_signature_ := ?; + var template IssuerIdentifier v_issuer := ?; + var template PublicVerificationKey v_public_verification_key := ?; + + log(">>> f_verify_rca_certificate: p_authorized_certificate= ", p_authorized_certificate); + log(">>> f_verify_rca_certificate: p_certificate= ", p_certificate); + + if (p_check_implicit == true) { + v_type_ := implicit; + } + if (p_check_no_signature == true) { + v_signature_ := omit; + } + if (match(p_certificate, mw_etsiTs103097Certificate(-, -, v_signature_, v_type_)) == false) { + log("f_verify_rca_certificate: version/explicit mismatch"); + return false; + } + if (p_check_reconstruction_value == false) { + if (match(p_certificate, mw_etsiTs103097Certificate( + -, + mw_toBeSignedCertificate_ca( + (mw_certificateId_none, mw_certificateId_name), + -, + -, + mw_verificationKeyIndicator_verificationKey + ), + v_signature_ + )) == false) { + log("f_verify_rca_certificate: verificationKey mismatch"); + return false; + } + if (p_check_signature_content) { + var template PublicVerificationKey v_publicVerificationKey; + + if (PICS_SEC_SHA256) { + v_signature_ := mw_signature_ecdsaNistP256; + v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest); + v_public_verification_key := mw_publicVerificationKey_ecdsaNistP256; + } else if (PICS_SEC_BRAINPOOL_P256R1) { + v_signature_ := mw_signature_ecdsaBrainpoolP256r1; + v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest); + v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP256r1; + } else if (PICS_SEC_BRAINPOOL_P384R1) { + v_signature_ := mw_signature_ecdsaBrainpoolP384r1; + v_issuer := (mw_issuerIdentifier_self(sha384), mw_issuerIdentifier_sha384AndDigest); + v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP384r1; + } + if (match(p_certificate, mw_etsiTs103097Certificate( + v_issuer, + mw_toBeSignedCertificate_ca( + (mw_certificateId_none, mw_certificateId_name), + -, + -, + mw_verificationKeyIndicator_verificationKey(v_public_verification_key), + -, -, -, -, + -//mw_encryptionKey + ), + v_signature_ + )) == false) { + log("f_verify_rca_certificate: signature mismatch"); + return false; + } + // Verify Signature + if (ischosen(p_certificate.issuer.self_)) { + v_publicVerificationKey := p_certificate.toBeSigned.verifyKeyIndicator.verificationKey; + } else { + var HashedId8 v_digest; + var Certificate v_authorized_certificate; + var charstring v_cert; + + if (ischosen(p_certificate.issuer.sha256AndDigest)) { + v_digest := p_certificate.issuer.sha256AndDigest; + } else if (ischosen(p_certificate.issuer.sha384AndDigest)) { + v_digest := p_certificate.issuer.sha384AndDigest; + } else { + log("f_verify_rca_certificate: Invalid certificate issuer ", p_certificate.issuer); + return false; + } + if (f_getCertificateFromDigest(v_digest, v_authorized_certificate, v_cert) == false) { + log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); + return false; + } + v_publicVerificationKey := v_authorized_certificate.toBeSigned.verifyKeyIndicator.verificationKey + } + log("f_verify_rca_certificate: v_publicVerificationKey= ", v_publicVerificationKey); + if (f_verifyCertificateSignatureWithPublicKey(p_certificate, v_publicVerificationKey) == false) { + log("f_verify_rca_certificate: signature not verified"); + return false; + } + } + } else { + if (match(p_certificate, mw_etsiTs103097Certificate( + -, + mw_toBeSignedCertificate_ca( + (mw_certificateId_none, mw_certificateId_name), + -, + -, + mw_verificationKeyIndicator_reconstructionValue + ), + v_signature_ + )) == false) { + log("f_verify_rca_certificate: verificationKey mismatch"); + return false; + } + // TODO Verify Signature + } + + if (p_check_region_restriction == true) { + var Certificate v_authorized_certificate; + var template GeographicRegion v_geographic_region := ?; + + if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { + log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); + return false; + } + log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); + + if (PICS_SEC_CIRCULAR_REGION == true) { + v_geographic_region := mw_geographicRegion_circle; + } else if (PICS_SEC_RECTANGULAR_REGION == true) { + v_geographic_region := mw_geographicRegion_rectangular; + } else if (PICS_SEC_POLYGONAL_REGION == true) { + v_geographic_region := mw_geographicRegion_polygonal; + } else if (PICS_SEC_IDENTIFIED_REGION == true) { + v_geographic_region := mw_geographicRegion_identified( + { + (mw_identifiedRegion_country_only, mw_identifiedRegion_country_and_region) + } + ); + } + if (match(p_certificate, mw_etsiTs103097Certificate( + -, + mw_toBeSignedCertificate_ca( + -, + -, + -, + -, + -, + -, + v_geographic_region + ) + )) == false) { + log("f_verify_rca_certificate: Geographical region mismatch"); + return false; + } + // Check interception of area + if (f_checkRegionValidityRestiction(v_authorized_certificate, p_certificate) == false) { + log("f_verify_rca_certificate: Geographical region intersection mismatch"); + return false; + } + } + // Check appPermissions + if (p_check_app_permissions == true) { + var integer v_idx, v_jdx; + var charstring v_psid := ""; // 'psid' currently processed + var charstring v_psidsFound := ";"; // Used to build the list of the 'psid' already processed + var template charstring m_found_pattern; // Used in regex to verify that 'psid' was not found before + var Certificate v_authorized_certificate; + + if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { + log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); + return false; + } + log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); + if (match(v_authorized_certificate.toBeSigned.certIssuePermissions, { mw_psidGroupPermissions }) == false) { + log("f_verify_rca_certificate: eeType mismatch"); + return false; + } + + for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) { + log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]); + if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions) == false) { + log("f_verify_rca_certificate: PsidSsp mismatch"); + return false; + } + // Check uniqueness of PSIDs + v_psid := int2str(p_certificate.toBeSigned.appPermissions[v_idx].psid); + m_found_pattern := pattern "*({v_psid})*"; + if (regexp(v_psidsFound, m_found_pattern, 0) == v_psid) { + log("f_verify_rca_certificate: Psid uniqueness is not verified"); + return false; // v_psid exist at least 2 times, uniqueness is not verified + } + // v_psid non found, add it into the built list + v_psidsFound := v_psidsFound & v_psid & ";"; + // Check that 'psid' is in the certIssuePermissions component in the issuing certificate + if (match(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions, mw_subjectPermissions_explicit) == false) { + for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) { + if (int2str(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid) == v_psid) { + break; + } + } // End of 'for'statement + if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) { + log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate"); + return false; + } + } + } // End of 'for'statement + } + + if (p_check_app_ssps == true) { + var integer v_idx, v_jdx; + var Certificate v_authorized_certificate; + + if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { + log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); + return false; + } + log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); + for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) { + log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]); + if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions(-, ?)) == false) { + log("f_verify_rca_certificate: appPermissions mismatch"); + return false; + } + // Check that 'ssp' is in the certIssuePermissions component in the issuing certificate + for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) { + log("f_verify_rca_certificate: compare psid ", v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid, " - ", p_certificate.toBeSigned.appPermissions[v_idx].psid); + if (v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid == p_certificate.toBeSigned.appPermissions[v_idx].psid) { + break; + } + } // End of 'for'statement + if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) { + log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate"); + return false; + } else { + var BitmapSsp v_ssp_ca := substr(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue, 1, -1 + lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue)); + log("f_verify_rca_certificate: v_ssp_ca= ", v_ssp_ca, " - ssp= ", p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp); + if (v_ssp_ca != p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp) { + log("f_verify_rca_certificate: SSPs mismatch: CA"); + return false; + } + } + } // End of 'for'statement + } + + if (p_check_app_validity_period == true) { + var integer v_idx, v_jdx; + var Certificate v_authorized_certificate; + var UInt32 v_duration, v_duration_ca; + + if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) { + log("f_verify_rca_certificate: Fail to load p_authorized_certificate"); + return false; + } + log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate); + // Check start date (indicating X_START_VALIDITY ( X_START_VALIDITY >= X_START_VALIDITY_CA )) + if (p_certificate.toBeSigned.validityPeriod.start_ < v_authorized_certificate.toBeSigned.validityPeriod.start_) { + log("f_verify_rca_certificate: validityPeriod.start_ mismatch"); + return false; + } + // Check duration (value <= X_START_VALIDITY_CA + X_DURATION_CA - X_START_VALIDITY) + v_duration := duration_to_uint32(p_certificate.toBeSigned.validityPeriod.duration); + v_duration_ca := duration_to_uint32(v_authorized_certificate.toBeSigned.validityPeriod.duration); + if (v_duration > (v_authorized_certificate.toBeSigned.validityPeriod.start_ + v_duration_ca - p_certificate.toBeSigned.validityPeriod.start_)) { + log("f_verify_rca_certificate: validityPeriod.duration mismatch"); + return false; + } + } + + return true; + } + + function duration_to_uint32( + in Duration p_duration + ) return UInt32 { + if (ischosen(p_duration.microseconds)) { + return p_duration.microseconds * 1000000; + } + else if (ischosen(p_duration.milliseconds)) { + return p_duration.milliseconds * 1000; + } + else if (ischosen(p_duration.seconds)) { + return p_duration.seconds; + } + else if (ischosen(p_duration.minutes)) { + return p_duration.minutes * 60; + } + else if (ischosen(p_duration.hours)) { + return p_duration.hours * 3600; + } + else if (ischosen(p_duration.sixtyHours)) { + return p_duration.sixtyHours * 60 * 3600; + } + else if (ischosen(p_duration.sixtyHours)) { + return p_duration.sixtyHours * 60 * 3600; + } + // No choice! + return p_duration.years * 31536000; // One calendar common year has 365 days + } + + } // End of group 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; + } + + function f_verify_broadcasted_delta_ctl( + in GeoNetworkingPdu p_geonetworking_pdu, + in boolean p_check_security := true + ) return boolean { + + var EtsiTs103097Data v_secured_msg; + var bitstring v_etsi_ts_102941_data_msg; + var bitstring v_tbs; + var Certificate v_certificate; + var boolean v_result; + var EtsiTs102941Data v_etsi_ts_102941_data; + + log(">>> f_verify_broadcasted_delta_ctl: p_geonetworking_pdu= ", p_geonetworking_pdu); + + if (not(ispresent(p_geonetworking_pdu.gnPacket.securedMsg))) { + return false; + } + + v_secured_msg := p_geonetworking_pdu.gnPacket.securedMsg; + // 1. Verify signature + log("f_verify_broadcasted_delta_ctl: v_secured_msg= ", v_secured_msg); + v_tbs := encvalue(v_secured_msg.content.signedData.tbsData); + if (ischosen(v_secured_msg.content.signedData.signer.certificate)) { + v_certificate := v_secured_msg.content.signedData.signer.certificate[0]; + } else { + var charstring v_certificate_id; + if (f_getCertificateFromDigest(v_secured_msg.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { + log("f_verify_broadcasted_delta_ctl: Failed to retrieve certificate from digest ", v_secured_msg.content.signedData.signer.digest); + if (p_check_security == true) { + return false; + } + } + } + if (ischosen(v_secured_msg.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) { + v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); + } else { + v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); + } + if (v_result == false) { + log("f_verify_broadcasted_delta_ctl: Failed to verify signature"); + if (p_check_security == true) { + return false; + } + } + v_etsi_ts_102941_data_msg := oct2bit(v_secured_msg.content.signedData.tbsData.payload.data.content.unsecuredData); + if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) { + log("f_verify_broadcasted_delta_ctl: Failed to decode EtsiTs102941Data"); + return false; + } else { + log("f_verify_broadcasted_delta_ctl: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data); + // TODO + } + + return true; + } // End of function f_verify_broadcasted_delta_ctl + + function f_verify_and_extract_payload( + in GeoNetworkingPdu p_geonetworking_pdu, + in boolean p_check_security := true, + out octetstring p_payload + ) return boolean { + + var EtsiTs103097Data v_secured_msg; + var bitstring v_tbs; + var Certificate v_certificate; + var boolean v_result; + var EtsiTs102941Data v_etsi_ts_102941_data; + + log(">>> f_verify_and_extract_payload: p_geonetworking_pdu= ", p_geonetworking_pdu); + + if (not(ispresent(p_geonetworking_pdu.gnPacket.securedMsg))) { + return false; + } + + v_secured_msg := p_geonetworking_pdu.gnPacket.securedMsg; + // 1. Verify signature + log("f_verify_and_extract_payload: v_secured_msg= ", v_secured_msg); + v_tbs := encvalue(v_secured_msg.content.signedData.tbsData); + if (ischosen(v_secured_msg.content.signedData.signer.certificate)) { + v_certificate := v_secured_msg.content.signedData.signer.certificate[0]; + } else { + var charstring v_certificate_id; + if (f_getCertificateFromDigest(v_secured_msg.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) { + log("f_verify_and_extract_payload: Failed to retrieve certificate from digest ", v_secured_msg.content.signedData.signer.digest); + if (p_check_security == true) { + return false; + } + } + } + if (ischosen(v_secured_msg.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) { + v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); + } else { + v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), v_secured_msg.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey); + } + if (v_result == false) { + log("f_verify_and_extract_payload: Failed to verify signature"); + if (p_check_security == true) { + return false; + } + } + log("f_verify_and_extract_payload: v_etsi_ts_102941_data= ", v_secured_msg.content.signedData.tbsData.payload.data.content.unsecuredData); + // TODO + + return true; + } // End of function f_verify_and_extract_payload + + } // End of group tlm + + group awaiting_messages { + + function f_await_http_inner_ec_request_response( + out 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, + out HttpMessage p_request + ) runs on ItsPkiHttp return boolean { + 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 + )))))), + p_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, p_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_ec_request_send_error_response( + out HttpMessage p_request + ) runs on ItsPkiHttp { + var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var boolean v_result := false; + + log(">>> f_await_ec_request_send_error_response"); + + tc_ac.start; + alt { + [] a_await_ec_http_request_from_iut( + mw_http_request( + mw_http_request_post( + PICS_HTTP_POST_URI_EC, + -, + mw_http_message_body_binary( + mw_binary_body_ieee1609dot2_data( + mw_enrolmentRequestMessage( + mw_encryptedData( + -, + mw_SymmetricCiphertext_aes128ccm + )))))), + p_request + ) { + var template (value) HttpMessage v_response; + var Headers v_headers; + + tc_ac.stop; + + f_init_default_headers_list(-, "inner_ec_response", v_headers); + log("f_await_ec_request_send_error_response: Failed to verify PKI message ***"); + // Send error message + v_response := m_http_response(m_http_response_ko(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers, 400, "Bad request")); // Initialize v_reponse with an error message + f_http_send(v_headers, v_response); + } + [] tc_ac.timeout { + log("f_await_ec_request_send_error_response: Expected message not received ***"); + } + } // End of 'alt' statement + + } // End of function f_await_ec_request_send_error_response + + 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 + + function f_verify_repeated_request( + in HttpMessage p_request_1, + in HttpMessage p_request_2 + ) return boolean { + + return false; + } // End of function f_verify_repeated_request + + /** + * @desc Verify the EC certificate generated by the EA entity + * @param p_ec_certificate The new EC certificate + * @param p_ea_certificate The certificate issuer + * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerEcRequest + * @param p_compressed_mode The public compressed key mode + * @return true on success, false otherwise + */ + function f_verify_ec_certificate( + in Certificate p_ec_certificate, + in Certificate p_ea_certificate, + in HashedId8 p_ea_hashed_id8, + in octetstring p_public_key_compressed, + in integer p_compressed_mode + ) 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 + + altstep a_await_cpoc_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_cpoc_http_request_from_iut: Received message on httpPort"); + } + [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_response { + log("a_await_cpoc_http_request_from_iut: Received message on httpEcPort"); + } + } // End of altstep a_await_cpoc_http_request_from_iut + + } // End of group altsteps + +} // End of module LibItsPki_Functions diff --git a/lib_system/LibItsPki_TestSystem.ttcn b/lib_system/LibItsPki_TestSystem.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..d1bef904292fea31aa0e4d7bd9db1ffa7ca2c515 --- /dev/null +++ b/lib_system/LibItsPki_TestSystem.ttcn @@ -0,0 +1,130 @@ +/** + * @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; + import from LibItsGeoNetworking_TypesAndValues 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; + + // UT indications + var UtGnEventIndList vc_utInds := {}; + + var boolean vc_utDefaultActive := true; + } // End of component ItsPkiItss + + } // End of group componentDefinitions + +} // End of module LibItsPki_TestSystem diff --git a/lib_system/module.mk b/lib_system/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..38efe41f36b68fa317ff0ea1ec698c20eb99ccdf --- /dev/null +++ b/lib_system/module.mk @@ -0,0 +1,2 @@ +sources := LibItsPki_Functions.ttcn \ + LibItsPki_TestSystem.ttcn diff --git a/module.mk b/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..62472887ef734a80537da838e6294da79c734385 --- /dev/null +++ b/module.mk @@ -0,0 +1,43 @@ +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 \ + lib_system \ + ../LibCommon \ + ../LibIts \ + ../AtsGeoNetworking/lib \ + ../AtsGeoNetworking/lib_system \ + ../AtsIPv6OverGeoNetworking/lib \ + ../AtsIPv6OverGeoNetworking/lib_system \ + ../AtsSecurity/lib \ + ../AtsSecurity/lib_system \ + ../AtsBTP/lib \ + ../AtsBTP/lib_system \ + ../AtsCAM/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/Ports/LibIts_ports/BTP_ports \ + /ccsrc/EncDec \ + /ccsrc/Framework \ + /ccsrc/Externals \ + /ccsrc/loggers \ + /ccsrc/geospacial \ + /ccsrc/Asn1c \ + /ccsrc/Protocols/CAM \ + /ccsrc/Protocols/GeoNetworking \ + /ccsrc/Protocols/BTP \ + /ccsrc/Protocols/UpperTester \ + /ccsrc/Protocols/Http \ + /ccsrc/Protocols/Security \ + /ccsrc/Protocols/Pki \ + ../modules/titan.TestPorts.HTTPmsg