/** * @Author ETSI / STF545 / TTF T025 * @version $Url$ * $Id$ * @desc Testcases file for PKI/ITS-S 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 ItsPkiItss_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 Ieee1609Dot2Dot1AcaRaInterface language "ASN.1:1997" all; import from Ieee1609Dot2Dot1EeRaInterface language "ASN.1:1997" all; import from ETSI_ITS_CDD language "ASN.1:1997" all; import from CAM_PDU_Descriptions language "ASN.1:1997" all; // LibItsCommon import from LibItsCommon_TypesAndValues all; import from LibItsCommon_Functions all; import from LibItsCommon_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; // LibHttp import from LibHttp_TypesAndValues all; import from LibHttp_Templates all; import from LibHttp_Functions all; import from LibHttp_TestSystem all; import from LibHttp_Pics all; import from LibHttp_BinaryTemplates all; // LibHelpers import from LibHelpers_Functions 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_states { const charstring c_stInitial := "initial"; const charstring c_stEnrolled := "enrolled"; const charstring c_stAuthorized := "authorized"; } group itss_helpers { /** * @desc Send an HTTP error message 500 Internal error. * Note: To be refined */ function f_send_500_Internal_Error( in Headers p_headers, in template (omit) charstring p_error_message := omit ) runs on ItsPkiHttp { f_http_send( p_headers, m_http_response( m_http_response_500_internal_error( p_headers ))); } // End function f_send_500_Internal_Error const charstring c_nextTry := "nextTry"; /** * @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 (present) octetstring p_its_id := PICS_ITS_S_CANONICAL_ID, in template (present) 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 Ieee1609Dot2Data v_ieee1609dot2_signed_data; var EtsiTs102941Data v_etsi_ts_102941_data; var Oct16 v_request_hash; var HashedId8 v_bfk_hashed_id8; var Oct16 v_aes_enc_key; var template (value) HttpMessage v_response; var EtsiTs103097Certificate v_ec_certificate; var HashedId8 v_ec_certificate_hashed_id8; var PublicVerificationKey v_canonical_key; log(">>> f_verify_http_ec_request_from_iut_itss: ", p_request); p_result := 0; if(false == f_get_canonical_itss_key(v_canonical_key)){ log(">>> f_verify_http_ec_request_from_iut_itss: error getting canonical key"); v_response := m_http_response(m_http_response_500_internal_error(p_headers)); p_result := -1; return; } if(not(f_read_pki_request_message( p_request.body.binary_body.ieee1609dot2_data, vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, v_request_hash, v_aes_enc_key, v_ieee1609dot2_signed_data, v_etsi_ts_102941_data ))) { f_http_build_inner_ec_response(-, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); p_result := -1; goto L_Done; } 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 (false == match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))) { // Send error message f_http_build_inner_ec_response(-, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); // Set verdict p_result := -2; goto L_Done; } // Verify signature of mw_innerEcRequestSignedForPop if (false == f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request)) { // 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, v_ec_certificate, v_ec_certificate_hashed_id8, 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; goto L_Done; } 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 (false == match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)})))) { // 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, v_ec_certificate, v_ec_certificate_hashed_id8, 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; goto L_Done; } // 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) { // Send EC certificate with code ok log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter); f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256)) { if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0)) { vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0; vc_ec_compressed_modes[vc_ec_keys_counter] := 0; } else { vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_1; vc_ec_compressed_modes[vc_ec_keys_counter] := 1; } } else if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1)) { if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; vc_ec_compressed_modes[vc_ec_keys_counter] := 0; } else { vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; vc_ec_compressed_modes[vc_ec_keys_counter] := 1; } } else { log("*** " & testcasename() & ": FAIL: Not implemented yet ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8; vc_ec_keys_counter := vc_ec_keys_counter + 1; vc_ec_certificates[vc_ec_counter] := v_ec_certificate; vc_ec_counter := vc_ec_counter + 1; log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter); } else { log("f_verify_http_ec_request_from_iut_itss: Succeed but 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, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); } label L_Done; 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 template (omit) 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_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; var octetstring v_msg; log(">>> f_verify_http_at_request_from_iut_itss:", p_request); p_result := 0; // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data)); log(">>> f_verify_http_at_request_from_iut_itss: Encoded request: ", v_msg); v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); log(">>> f_verify_http_at_request_from_iut_itss: p_request_hash= ", v_request_hash); // 2. Decrypt the InnerAtRequest if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted vc_aaWholeHash, // salt v_ieee1609dot2_data, // decrypted message v_aes_enc_key)) { log("f_verify_http_at_request_from_iut_itss: Failed to decrypt message"); // Send error message, unable to decypt it p_response := valueof(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; return; } // check if signed var bitstring v_msg_bit; if(ispresent(v_ieee1609dot2_data.content.signedData)) { if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data) or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData)) { log("f_verify_http_at_request_from_iut_itss: Invalid message payload"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -1; return; } log("f_verify_http_at_request_from_iut_itss: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); } else { if(not ispresent(v_ieee1609dot2_data.content.unsecuredData)) { log("f_verify_http_at_request_from_iut_itss: Invalid message payload"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -1; return; } v_msg_bit := oct2bit(v_ieee1609dot2_data.content.unsecuredData); } if (decvalue(v_msg_bit, v_etsi_ts_102941_data) != 0) { log("f_verify_http_at_request_from_iut_itss: Can not decode v_etsi_ts_102941_data"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -1; return; } 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, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); // Set verdict p_result := -2; return; } 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, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers))); // Set verdict p_result := -3; return; } 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))); 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 authorization request f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers))); // Set verdict p_result := -4; return; } // Verify PoP signature of outer message if(ispresent(v_ieee1609dot2_data.content.signedData)){ log("f_verify_http_at_request_from_iut_itss: v_ieee1609dot2_data.content.signedData.tbsData= ", v_ieee1609dot2_data.content.signedData.tbsData); v_msg := bit2oct(encvalue(v_ieee1609dot2_data.content.signedData.tbsData)); log("f_verify_http_at_request_from_iut_itss: v_msg= ", v_msg); if (false == f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_data.content.signedData.signature_, p_inner_at_request.publicKeys.verificationKey)) { f_http_build_authorization_response(p_inner_at_request, invalidsignature, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers))); // Set verdict p_result := -6; return; } } 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, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers))); // Set verdict p_result := -5; return; } // 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_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_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, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); } p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers))); log("<<< f_verify_http_at_request_from_iut_itss: p_result: ", p_result); log("<<< f_verify_http_at_request_from_iut_itss: p_response: ", p_response); } // End of function f_verify_http_at_request_from_iut_itss /** * @desc The purpose of this function is verify the AT request and extract InnerAtRequest , verify ecSignature and build the InnerAtResponse for the HTTP response * Note: This function accepts additional parameters to alter the response */ function f_verify_http_at_request_from_iut_itss_for_ecSignature( 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, out boolean p_contains_ecsignature, 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_data; var EtsiTs102941Data v_etsi_ts_102941_data; var Ieee1609Dot2Data v_ieee1609dot2_signed_data; //new variable var HashedId8 v_ec_certificate_hashed_id8 //new variable // var EcHashedId8 vc_ec_hashed_id8; Already defined in LibItsPki_TestSystem var Oct16 v_request_hash; var HashedId8 v_bfk_hashed_id8; var Oct16 v_aes_enc_key; var template (value) HttpMessage v_response; var octetstring v_msg; log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature:", p_request); p_result := 0; // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data)); log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature: ", v_msg); v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature: p_request_hash= ", v_request_hash); // 2. Decrypt the InnerAtRequest if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted vc_aaWholeHash, // salt v_ieee1609dot2_data, // decrypted message v_aes_enc_key)) { log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Failed to decrypt message"); // Send error message, unable to decypt it p_response := valueof(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; return; } // check if signed var bitstring v_msg_bit; if(ispresent(v_ieee1609dot2_data.content.signedData)){ if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data) or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData)) { log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Invalid message payload"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -1; return; } log("f_verify_http_at_request_from_iut_itss_for_ecSignature: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); } else { log("f_verify_http_at_request_from_iut_itss_for_ecSignature: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // 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, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); // Set verdict p_result := -2; } else { // Extract InnerAtRequest and Verify signature of mw_innerATRequestSigned var InnerAtRequest v_inner_at_request := v_etsi_ts_102941_data.content.authorizationRequest; log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // to get the unmatching in log if (match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined // Send error message: No authorization 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -3; } else { // Check ecSignature if (ispresent(v_inner_at_request.ecSignature.ecSignature) == false) { // Send error message: No signed external payload present 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -4; // Verify ecSignature of mw_ec_signature (encrypted) } else { p_contains_ecsignature := true; v_ieee1609dot2_signed_data := v_inner_at_request.ecSignature.ecSignature; log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(v_inner_at_request.ecSignature,mw_ec_signature_ext_payload)) if (match(v_inner_at_request.ecSignature, mw_ec_signature_ext_payload) == false) { // Send error message: Present signed external payload doesnot match mw_ec_signature_ext_payload template 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -5; } else { // Check signer in ecSignature if (isvalue(v_ieee1609dot2_signed_data.content.signedData)) { // Verify digest of signerIdentifier_digest if (match(v_ieee1609dot2_signed_data.content.signedData.signer,mw_signerIdentifier_digest) == false) { var HashedId8 v_digest := v_ieee1609dot2_signed_data.content.signedData.signer.digest; // check if it is hashId8 //log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(p_ec_certificate.issuer, v_digest)); var bitstring v_enc_value; var octetstring v_ec_hash; var Oct8 v_ec_hashed_id8; 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); } if (match(v_ec_hashed_id8, v_digest) == false) { // Send error message: Signer not contains HashedId8 of the CERT_EC certificate 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -6; } else { // Check _signature in ecSignature if (isvalue(v_ieee1609dot2_signed_data.content.signedData.signature_)) { // var EtsiTs103097Certificate v_certificate; var EtsiTs102941Data v_etsi_ts_102941_ext_payload_data; var octetstring v_encoded_tbsData var Oct32 v_issuer; v_certificate := v_ieee1609dot2_signed_data.content.signedData.signer.certificate[0]; v_encoded_tbsData := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData)); var octetstring v_enc := bit2oct(encvalue(v_certificate)); v_issuer := f_hashWithSha256(v_enc); if (f_verifyEcdsa(v_encoded_tbsData,v_issuer,v_ieee1609dot2_signed_data.content.signedData.signature_,v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) { // Send error message: Unable to verfy signature using EC's verification public key f_http_build_authorization_response(p_inner_at_request, invalidsignature, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; } else { // Send OK message log("f_verify_http_at_request_from_iut_itss_for_ecSignature: 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_data); } else { log("f_verify_http_at_request_from_iut_itss_for_ecSignature: 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_data); } v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); } } } } } } } // Check } } } } /** * @desc The purpose of this function is verify the AT request and extract InnerAtRequest , verify encrypted ecSignature and build the InnerAtResponse for the HTTP response * Note: This function accepts additional parameters to alter the response */ function f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature( 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_data; var EtsiTs102941Data v_etsi_ts_102941_data; var EtsiTs103097Data p_decryptedSecuredMessage; var EncryptedData v_encrypted_data; var EtsiTs103097Data v_etsi_ts_103097_data; var Oct16 v_request_hash; var HashedId8 v_bfk_hashed_id8; var Oct16 v_aes_enc_key; var template (value) HttpMessage v_response; var octetstring v_msg; log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature:", p_request); p_result := 0; // 1. Calculate the request Hash v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data)); log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Encoded request: ", v_msg); v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: p_request_hash= ", v_request_hash); // 2. Decrypt the InnerAtRequest if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted vc_aaWholeHash, // salt v_ieee1609dot2_data, // decrypted message v_aes_enc_key)) { log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Failed to decrypt message"); // Send error message, unable to decypt it p_response := valueof(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; return; } // check if signed var bitstring v_msg_bit; if(ispresent(v_ieee1609dot2_data.content.signedData)){ if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data) or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData)) { log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Invalid message payload"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -2; return; } log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData); if (decvalue(v_msg_bit, v_etsi_ts_102941_data) != 0) { log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Can not decode v_etsi_ts_102941_data"); p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); p_result := -3; return; } } else { log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // 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_data); // Set verdict p_result := -4; return; } else { // Extract InnerAtRequest and Verify signature of mw_innerATRequest var InnerAtRequest v_inner_at_request := v_etsi_ts_102941_data.content.authorizationRequest; log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // to get the unmatching in log if (match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined // Send error message: No authorization 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -5; return; } else { // Check ecSignature var EcSignature v_ecsignature := v_inner_at_request.ecSignature; if (ischosen(v_ecsignature.encryptedEcSignature) == false) { // Send error message: No encrypted ecSignature present 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -6; return; // Verify ecSignature of mw_ec_signature (encrypted) } else { //v_encrypted_data := v_inner_at_request.ecSignature.encryptedEcSignature; v_encrypted_data := v_ecsignature.encryptedEcSignature.content.encryptedData; //var RecipientInfo v_recipientInfo := v_encrypted_data.content.encryptedData.recipients[0]; var RecipientInfo v_recipientInfo := v_encrypted_data.recipients[0]; var PKRecipientInfo v_pKRecipientInfo := v_recipientInfo.certRecipInfo; log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(v_ecsignature,mw_ec_signature)) if (match(v_ecsignature, mw_ec_signature) == false) { // Send error message: Present encrypted ecSignature doesnot matches with mw_ec_signature template 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; return; } else { // Check in encrypted ecSignature if (isvalue(v_ecsignature.encryptedEcSignature.content.encryptedData)) { var octetstring v_decryptedSecuredMessage; // Verify recipient if (not isvalue(v_encrypted_data.recipients[0]) and sizeof(v_encrypted_data.recipients) > 1) { // RecipientInfo should not contains certRecipInfo > 1 // Send error message: recipients containing more than one element of type RecipientInfo 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -8; return; } else { // RecipientInfo should contains certRecipInfo if (isvalue(v_recipientInfo.certRecipInfo)) { // verify that recipientId should be hashedId8 of EA_CERT log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(vc_eaHashedId8, v_pKRecipientInfo.recipientId)); if (match(vc_eaHashedId8, v_pKRecipientInfo.recipientId) == false) { // Send error message: recipientId not contains the HashedId8 of the CERT_EA 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -8; return; } else { // Further verify the encKey of supported type if (isvalue(v_pKRecipientInfo.encKey)) { if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) { var SymmetricCiphertext v_ciphertext := v_encrypted_data.ciphertext; var Oct16 p_aes_sym_enc_key; //var octetstring v_decryptedSecuredMessage; log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: v_ciphertext=", v_ciphertext); if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0)) { v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256( v_ciphertext.aes128ccm.ccmCiphertext, vc_eaPrivateEncKey, v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0, 0, v_pKRecipientInfo.encKey.eciesNistP256.c, v_pKRecipientInfo.encKey.eciesNistP256.t, v_ciphertext.aes128ccm.nonce, vc_eaWholeHash, p_aes_sym_enc_key ); } else if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1)) { v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256( v_ciphertext.aes128ccm.ccmCiphertext, vc_eaPrivateEncKey, v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1, 1, v_pKRecipientInfo.encKey.eciesNistP256.c, v_pKRecipientInfo.encKey.eciesNistP256.t, v_ciphertext.aes128ccm.nonce, vc_eaWholeHash, p_aes_sym_enc_key ); } else { // send error msg : Non canonical ephemeral encryption keys 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; return; } } else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1)) { var SymmetricCiphertext v_ciphertext := v_encrypted_data.ciphertext; //var octetstring v_decryptedSecuredMessage; var Oct16 p_aes_sym_enc_key; if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0)) { v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256( v_ciphertext.aes128ccm.ccmCiphertext, vc_eaPrivateEncKey, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0, 0, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t, v_ciphertext.aes128ccm.nonce, vc_eaWholeHash, p_aes_sym_enc_key ); } else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1)) { v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256( v_ciphertext.aes128ccm.ccmCiphertext, vc_eaPrivateEncKey, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1, 1, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c, v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t, v_ciphertext.aes128ccm.nonce, vc_eaWholeHash, p_aes_sym_enc_key ); } else { // send error msg : Non canonical ephemeral encryption keys 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; return; } } else { // send error message : encKey does not support any type 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; return; } } } } } // verify containing cyphertext if (ispresent(v_encrypted_data.ciphertext) == false){ // Send error message: ciphertext doesn't exist 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -8; return; } else { //v_ieee1609dot2_signed_data := v_encrypted_data.ciphertext; if (isbound(v_decryptedSecuredMessage)) { var bitstring v_decode := oct2bit(v_decryptedSecuredMessage); if (decvalue(v_decode, p_decryptedSecuredMessage) != 0) { log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***"); 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_data); v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); // Set verdict p_result := -7; return; } else { log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(p_decryptedSecuredMessage,mw_etsiTs103097Data_signed)); //check if encrypted data is of type if(match(p_decryptedSecuredMessage,mw_etsiTs103097Data_signed)){ // Send OK message log("f_verify_http_at_request_from_iut_itss_for_ecSignature: 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_data); } else { log("f_verify_http_at_request_from_iut_itss_for_ecSignature: 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_data); } v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)); } } } } } } } } } } } function f_verify_http_bfk_authorization_request( in Request p_request, in Headers p_headers, in EtsiTs103097Certificate p_ec_certificate, out EeRaCertRequest p_bfk_authorization_request, out RaEeCertInfo p_ra_ee_cert_info, 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 HashedId8 v_bfk_request_hash; var Oct16 v_aes_enc_key; var template (value) HttpMessage v_response; log(">>> f_verify_http_bfk_authorization_request: ", p_request); p_result := 0; if (f_verify_pki_request_message_with_certificate(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, p_ec_certificate, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_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 { // TODO Add checks on date, log("f_verify_http_bfk_authorization_request: match ", match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationRequest(mw_ee_ra_cert_request))); // TODO In TITAN, this is the only way to get the unmatching in log if (match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationRequest(mw_ee_ra_cert_request)) == false) { // Send error message f_http_build_butterfly_authorization_response_message(p_bfk_authorization_request/*Not required*/, v_bfk_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_ra_ee_cert_info, v_ieee1609dot2_signed_and_encrypted_data); // Set verdict p_result := -2; } else { // TODO Add checks p_bfk_authorization_request := v_etsi_ts_102941_data.content.butterflyAuthorizationRequest; f_http_build_butterfly_authorization_response_message(p_bfk_authorization_request, v_bfk_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_ra_ee_cert_info, v_ieee1609dot2_signed_and_encrypted_data); // vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8; // vc_ec_keys_counter := vc_ec_keys_counter + 1; // vc_ec_certificates[vc_ec_counter] := v_ec_certificate; // vc_ec_counter := vc_ec_counter + 1; // log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter); // // 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, v_ec_certificate, v_ec_certificate_hashed_id8, 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_bfk_authorization_request: 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, v_ec_certificate, v_ec_certificate_hashed_id8, 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_bfk_authorization_request: Receive ", p_inner_ec_request); // if (p_force_response_code == ok) { // // Send EC certificate with code ok // log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter); // f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data); // if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256)) { // if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0)) { // vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0; // vc_ec_compressed_modes[vc_ec_keys_counter] := 0; // } else { // vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_1; // vc_ec_compressed_modes[vc_ec_keys_counter] := 1; // } // } else if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1)) { // if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { // vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; // vc_ec_compressed_modes[vc_ec_keys_counter] := 0; // } else { // vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; // vc_ec_compressed_modes[vc_ec_keys_counter] := 1; // } // } else { // log("*** " & testcasename() & ": FAIL: Not implemented yet ***"); // f_selfOrClientSyncAndVerdict(c_prDone, e_error); // } // vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8; // vc_ec_keys_counter := vc_ec_keys_counter + 1; // vc_ec_certificates[vc_ec_counter] := v_ec_certificate; // vc_ec_counter := vc_ec_counter + 1; // log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter); // } else { // log("f_verify_http_bfk_authorization_request: Succeed but 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, v_ec_certificate, v_ec_certificate_hashed_id8, 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)); } } p_response := valueof(v_response); log("<<< f_verify_http_bfk_authorization_request: p_response: ", p_response); log("<<< f_verify_http_bfk_authorization_request: p_result: ", p_result); } // End of function f_verify_http_bfk_authorization_request /** * @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 // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.2.1 Enrollment request 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 v2.0.1 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 f_cfUp_itss(); // No AT certificate selected // Test adapter configuration // Preamble // Initial state: No CAM shall be emitted geoNetworkingPort.clear; tc_noac.start; alt { [] geoNetworkingPort.receive { log("*** " & testcasename() & "itss: FAIL: Unexpected GeoNet message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } [] tc_noac.timeout { log("*** " & testcasename() & "itss: INFO: No GeoNet message received. Continue ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body f_sendUtTriggerEnrolmentRequestPrimitive(); tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; log("*** " & testcasename() & "itss: INFO: IUT is in enrolment state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "itss: DBG: IUT state update not recieved. Assuming it was OK... ***"); //f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement tc_noac.start; alt { [] geoNetworkingPort.receive { log("*** " & testcasename() & "itss: FAIL: Unexpected GeoNet message received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] tc_noac.timeout { log("*** " & testcasename() & "itss: 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_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Oct16 v_request_hash; var Oct16 v_aes_enc_key; var Ieee1609Dot2Data v_outer_encrypted_message; var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; tc_ac.stop; if (not(f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request))) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": INCONC: Canonical key is not set properly ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); // to emulate inconc } else { f_send_500_Internal_Error(v_headers); // we dont care about response // Set verdict log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } } [] 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.2.1 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_02_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 group f_TC_SECPKI_ITSS_ENR_02_BV { function f_TC_SECPKI_ITSS_ENR_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); f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var Oct16 v_request_hash, v_aes_enc_key; var PublicVerificationKey v_canonical_key; tc_ac.stop; if( not f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request)) { log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_send_500_Internal_Error(v_headers); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if(not f_http_build_error_ec_response(unknownits, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message)) { log("*** " & testcasename() & ": INCOMC: Can't generate enrolment response***"); f_send_500_Internal_Error(v_headers); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } f_http_send( v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data( v_response_message)), v_headers))); if( not isvalue(v_inner_ec_request) ){ log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if(not match(v_inner_ec_request.itsId, LibItsPki_Pics.PICS_ITS_S_CANONICAL_ID)){ log("*** " & testcasename() & ": FAIL: Canonical ID mismatched ***"); log("*** " & testcasename() & ": FAIL: ", match(v_inner_ec_request.itsId, LibItsPki_Pics.PICS_ITS_S_CANONICAL_ID)); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not ischosen(v_decrypted_message.content.signedData)) { log("*** " & testcasename() & ": FAIL: EC request shall contain signed message ***"); log("*** " & testcasename() & ": FAIL: inner data content=", v_decrypted_message.content); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not ischosen(v_decrypted_message.content.signedData.signer.self_)) { log("*** " & testcasename() & ": FAIL: EC request shall be self-signed by cannonical key ***"); log("*** " & testcasename() & ": FAIL: signerInfo=", v_decrypted_message.content.signedData.signer); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not f_get_canonical_itss_key(v_canonical_key)){ log("*** " & testcasename() & ": INCONC: Unknown ITS-S canonical public key ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); // emulate inconc } if (not(f_verifyEcdsa(bit2oct(encvalue(v_decrypted_message.content.signedData.tbsData)), int2oct(0, 32), // issuer is emtpy string v_decrypted_message.content.signedData.signature_, v_canonical_key))){ log("*** " & testcasename() & ": FAIL: EC request signature verification failed ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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_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.2.1 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( in float p_delay := 0.0 ) runs on ItsPkiItss system ItsPkiItssSystem { // Test component configuration f_cfUp_itss(); // No AT certificate selected // Test adapter configuration // Preamble // Initial state: No CAM shall be emitted geoNetworkingPort.clear; tc_noac.start; alt { [] geoNetworkingPort.receive { log("*** " & testcasename() & "_itss: ERROR: Unexpected GeoNet message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } [] tc_noac.timeout { // Trigger the first enrolment log("*** " & testcasename() & "_itss: INFO: No GeoNet message received. Continue ***"); f_sendUtTriggerEnrolmentRequestPrimitive(); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body // Give time to the IUT to setup enrol state tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; log("*** " & testcasename() & "_itss: INFO: IUT is in enrolment state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved. Assuming it was OK... ***"); //f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement if(p_delay > 0.0){ log("*** " & testcasename() & "_itss: INFO: Wait for second enrolment trigger ***"); f_sleep(p_delay); } // Trigger the second enrolment f_sendUtTriggerEnrolmentRequestPrimitive(); log("*** " & testcasename() & "_itss: PASS: Re-enrolment trigger sent succesfully ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // 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 InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var HashedId8 v_ec_cert_digest; var octetstring v_ec_cert_hash; // 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); if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request))) { log("*** " & testcasename() & ": FAIL: First InnerEcRequest failed ***"); log("*** " & testcasename() & ": v_request := ", v_request); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } var HashAlgorithm ha := f_getHashAlgorithmOfVerificationKeyIndicator(v_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator); if (ha == sha256) { v_ec_cert_hash := f_hashWithSha256(bit2oct(encvalue(v_inner_ec_response.certificate))); } else if (ha == sha384) { v_ec_cert_hash := f_hashWithSha384(bit2oct(encvalue(v_inner_ec_response.certificate))); } else { log("*** " & testcasename() & ": FAIL: Unknown EC certificate hash alg=", ha); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } v_ec_cert_digest := substr(v_ec_cert_hash, lengthof(v_ec_cert_hash) - 8, 8); log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); log(">>>>> v_inner_ec_response=", v_inner_ec_response); log(">>>>> v_ec_cert_hash=", v_ec_cert_hash); f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var integer v_result; var Oct16 v_request_hash, v_aes_enc_key; var Ieee1609Dot2Data v_decrypted_message; var EtsiTs102941Data v_etsi_ts_102941_data; var InnerEcResponse v_inner_ec_response2; var Ieee1609Dot2Data v_response_message; tc_ac.stop; // Verify IUT response if (not(f_read_ec_request_from_iut_itss( v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_etsi_ts_102941_data, v_inner_ec_request))) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't parse enrolment request ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send error response to prevent enrolment repetition if( not f_http_build_error_ec_response(unknownits, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); if( not isvalue(v_inner_ec_request) ){ log("*** " & testcasename() & ": FAIL: Can't parse enrolment request ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not(match(v_inner_ec_request.itsId, v_ec_cert_digest))) { log("*** " & testcasename() & ": FAIL: ITS-S ID is not equal to the EC HashedId8 ***"); log("*** " & testcasename() & ": FAIL: ", match(v_inner_ec_request.itsId, v_ec_cert_digest)); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not(ischosen(v_decrypted_message.content.signedData))) { log("*** " & testcasename() & ": FAIL: EC request shall contain signed message ***"); log("*** " & testcasename() & ": FAIL: inner data content=", v_decrypted_message.content); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not(ischosen(v_decrypted_message.content.signedData.signer.digest))) { log("*** " & testcasename() & ": FAIL: re-keying EC request shall be signed by the previous EC certificate digest***"); log("*** " & testcasename() & ": FAIL: signerInfo=", v_decrypted_message.content.signedData.signer); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not(f_verifyEcdsa(bit2oct(encvalue(v_decrypted_message.content.signedData.tbsData)), v_ec_cert_hash, v_decrypted_message.content.signedData.signature_, v_inner_ec_response.certificate.toBeSigned.verifyKeyIndicator.verificationKey))) { log("*** " & testcasename() & ": FAIL: EC request signature verification failed ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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.2.1 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 // 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:
       * with
       * 	the IUT being in the 'enrolled' state
       * 	and the EC of the IUT expires 
       * ensure that
       * 	when
       *             the IUT is requested to send an EnrollmentRequestMessage
       * 	then
       *             the IUT sends an EtsiTs103097Data-Encrypted
       *               containing an encrypted EtsiTs103097Data-Signed
       *                 containing EtsiTs102941Data
       *                   containing InnerECRequestSignedForPOP
       *                     containing InnerEcRequest
       *                       containing itsId
       *                         indicating the canonical identifier of the ITS-S 
       * 
* * @see ETSI TS 103 525-2 v1.2.1 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 f_cfMtcUp01(v_itss, v_ea); // Start components v_itss.start(f_TC_SECPKI_ITSS_ENR_05_BV_itss()); // wait 15 sec before the second enrolment v_ea.start(f_TC_SECPKI_ITSS_ENR_05_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of TC_SECPKI_ITSS_ENR_05_BV group f_TC_SECPKI_ITSS_ENR_05_BV { function f_TC_SECPKI_ITSS_ENR_05_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { // Test component configuration f_cfUp_itss(); // No IT certificate selected // 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 log("*** " & testcasename() & "_itss: INFO: No CA message received ***"); } } // End of 'alt' statement log("*** " & testcasename() & "_itss: INFO: Trigger 1st emrolment ***"); f_sendUtTriggerEnrolmentRequestPrimitive(); // wait a couple of seconds and run second enrolment to check re-enrolment procedure f_sleep(PX_RE_ENROLMENT_DELAY); log("*** " & testcasename() & "_itss: INFO: Trigger 2nd emrolment ***"); f_sendUtTriggerEnrolmentRequestPrimitive(); // wait 5 seconds after expiration of EC cert f_sleep(PX_CERT_EXPIRATION_DELAY + 5.0); f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body // Trigger the 3rd enrolment log("*** " & testcasename() & "_itss: INFO: Trigger 3rd emrolment ***"); f_sendUtTriggerEnrolmentRequestPrimitive(); log("*** " & testcasename() & "_itss: PASS: Re-enrolment trigger sent succesfully ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_ENR_03_BV_itss function f_TC_SECPKI_ITSS_ENR_05_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var HashedId8 v_ec_cert_digest; var EtsiTs103097Certificate v_ec_cert; // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_init_default_headers_list(-, "inner_ec_response", v_headers); // Preamble if (not(f_await_ec_request_send_response(v_inner_ec_request, v_inner_ec_response, v_request, ok, m_certificateSubjectAttributes_id_omit( -, valueof(m_validityPeriod(f_getCurrentTime() / 1000, m_duration_in_seconds(float2int(PX_CERT_EXPIRATION_DELAY)))) )))) { log("*** " & testcasename() & ": FAIL: First InnerEcRequest failed ***"); log("*** " & testcasename() & ": v_request := ", v_request); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log(">>>>> 1st v_inner_ec_response=", v_inner_ec_response); v_ec_cert := v_inner_ec_response.certificate; v_ec_cert_digest := f_calculateDigestFromCertificate(v_ec_cert); if (not(ischosen(v_ec_cert.toBeSigned.validityPeriod.duration.seconds))) { log("*** " & testcasename() & ": INCONC: wrong EC certificate validity period error"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log("*** " & testcasename() & ": INFO: First InnerEcRequest processed. EC = " & oct2str(v_ec_cert_digest) & "***"); log("*** " & testcasename() & ": INFO: expires in " & int2str(v_ec_cert.toBeSigned.validityPeriod.start_ + v_ec_cert.toBeSigned.validityPeriod.duration.seconds - (f_getCurrentTime()/1000)) & " seconds ***" ); // Wait for 2nd request with EC data if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request, deniedrequest))) { log("*** " & testcasename() & ": FAIL: 2nd InnerEcRequest failed ***"); log("*** " & testcasename() & ": v_request := ", v_request); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log(">>>>> 2nd v_inner_ec_response=", v_inner_ec_response); if (not(match(v_inner_ec_request.itsId, v_ec_cert_digest))) { log("*** " & testcasename() & ": FAIL: ITS-S ID of 2nd request must be equal to the EC HashedId8 ***"); log("*** " & testcasename() & ": FAIL: ", match(v_inner_ec_request.itsId, v_ec_cert_digest)); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request, deniedrequest))){ log("*** " & testcasename() & ": FAIL: 3rd InnerEcRequest failed ***"); log("*** " & testcasename() & ": v_request := ", v_request); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } log(">>>>> 3rd v_inner_ec_response=", v_inner_ec_response); if(match(v_inner_ec_request.itsId, v_ec_cert_digest)){ if(v_ec_cert.toBeSigned.validityPeriod.start_ + v_ec_cert.toBeSigned.validityPeriod.duration.seconds < (f_getCurrentTime()/1000)){ log("*** " & testcasename() & ": INCONC: EC certificate is not expired yet ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } log("*** " & testcasename() & ": FAIL: ITS-S ID of 3rd request must NOT be equal to the expired EC HashedId8 ***"); log("*** " & testcasename() & ": FAIL: ", match(v_inner_ec_request.itsId, v_ec_cert_digest)); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_05_BV_pki } // End of group f_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.2.1 SECPKI_ITSS_ENR_06_BV * @reference ETSI TS 102 941, clause 6.1.3 */ testcase TC_SECPKI_ITSS_ENR_06_BV_1() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_06_BV_mtc(c_stInitial); } // End of TC_SECPKI_ITSS_ENR_06_BV_1 testcase TC_SECPKI_ITSS_ENR_06_BV_2() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_06_BV_mtc(c_stEnrolled); } // End of TC_SECPKI_ITSS_ENR_06_BV_2 group f_TC_SECPKI_ITSS_ENR_06_BV_mtc { function f_TC_SECPKI_ITSS_ENR_06_BV_mtc( in charstring p_state ) 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_06_BV_itss(PX_RE_ENROLMENT_COUNTER, p_state)); v_ea.start(f_TC_SECPKI_ITSS_ENR_06_BV_pki(PX_RE_ENROLMENT_COUNTER, p_state)); // Synchronization f_serverSyncClientsTimed(2, c_prDone, PX_TSYNC_TIME_LIMIT); for(var integer v_i := 0; v_i < PX_RE_ENROLMENT_COUNTER; v_i := v_i + 1){ f_serverSyncClientsTimed(2, c_nextTry, PX_TSYNC_TIME_LIMIT); } f_serverSyncClientsTimed(2, c_tbDone, PX_TSYNC_TIME_LIMIT); // Cleanup f_serverWaitForAllClientsToStop(); } // End of f_TC_SECPKI_ITSS_ENR_06_BV_mtc function f_TC_SECPKI_ITSS_ENR_06_BV_itss( integer p_max_try, charstring p_state ) runs on ItsPkiItss system ItsPkiItssSystem { // Local variables var EtsiTs103097Certificate v_certificate; // Test component configuration f_cfUp_itss(); // No IT certificate selected // 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() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body // Send first enrolment for(var integer v_i := 0; v_i < p_max_try; v_i := v_i + 1){ f_sleep(PX_RE_ENROLMENT_DELAY); f_sendUtTriggerEnrolmentRequestPrimitive(); f_clientSync(c_nextTry, e_success); } f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_ENR_06_BV_itss function f_TC_SECPKI_ITSS_ENR_06_BV_pki( integer p_max_try, charstring p_state ) runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var ListOfPublicVerificationKey v_generated_keys; // Test component configuration f_cfHttpUp(); // Test adapter configuration // Preamble f_init_default_headers_list(-, "inner_ec_response", v_headers); f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body for (var integer v_i := 0; v_i < p_max_try; v_i := v_i + 1) { var HttpMessage v_request; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var PublicVerificationKey v_key; var EnrolmentResponseCode v_response_code; if(p_state == c_stInitial){ v_response_code := deniedrequest; } else { v_response_code := ok; } if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request, v_response_code))) { log("*** " & testcasename() & ": ERROR: EC request receiving error ***"); setverdict(inconc); f_clientSync(c_nextTry, e_error); } v_key := v_inner_ec_request.publicKeys.verificationKey; if (isbound(v_generated_keys) and match(v_generated_keys, superset(v_key))) { log("*** " & testcasename() & ": LOG: ", match(v_generated_keys, superset(v_key)), "***"); log("*** " & testcasename() & ": FAIL: Duplication of generated public keys ***"); setverdict(fail); f_clientSync(c_nextTry, e_error); } v_generated_keys[v_i] := v_key; f_clientSync(c_nextTry, e_success); } log("*** " & testcasename() & ": PASS: No identical verification keys received in " & int2str(p_max_try) & " messages ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_06_BV_pki } // End of group 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.2.1 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_07_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of TC_SECPKI_ITSS_ENR_07_BV group f_SECPKI_ITSS_ENR_07_BV { function f_TC_SECPKI_ITSS_ENR_07_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_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var Oct16 v_request_hash, v_aes_enc_key; var PublicVerificationKey v_canonical_key; tc_ac.stop; if( not f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request)) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send any response to prevent enrolment repetition // negative is simpler if( not f_http_build_error_ec_response ( unknownits,v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); if (not isvalue(v_inner_ec_request)) { log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (ispresent(v_inner_ec_request.requestedSubjectAttributes.certIssuePermissions)) { log("*** " & testcasename() & ": FAIL: InnerEcRequest shall not contain certIssuePermissions attribute ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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_07_BV_pki } // End of group f_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.2.1 SECPKI_ITSS_ENR_08_BV * @reference ETSI TS 102 941, clause 6.2.3.2.1 */ testcase TC_SECPKI_ITSS_ENR_08_BV_1() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_08_BV_mtc(c_stInitial); } // End of TC_SECPKI_ITSS_ENR_08_BV_1 testcase TC_SECPKI_ITSS_ENR_08_BV_2() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_08_BV_mtc(c_stEnrolled); } // End of TC_SECPKI_ITSS_ENR_08_BV_2 group f_SECPKI_ITSS_ENR_08_BV { function f_TC_SECPKI_ITSS_ENR_08_BV_mtc(in charstring p_itss_state) 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 if(p_itss_state == c_stEnrolled) { v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); } else { v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); } v_ea.start(f_TC_SECPKI_ITSS_ENR_08_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of TC_SECPKI_ITSS_ENR_08_BV function f_TC_SECPKI_ITSS_ENR_08_BV_pki( in charstring p_itss_state ) 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); if (p_itss_state == c_stEnrolled) { var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; if(not f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request)){ log("*** " & testcasename() & ": INFO: First InnerEcRequest error ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); } f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Oct16 v_request_hash; var Oct16 v_aes_enc_key; var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; tc_ac.stop; f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request); if (not(isvalue(v_pki_request))) { log("*** " & testcasename() & ": FAIL: Can't parse enrolment request ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send any response to prevent enrolment repetition // negative is simpler if( not f_http_build_error_ec_response ( unknownits,v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); if( not ischosen(v_pki_request.content.enrolmentRequest)) { log("*** " & testcasename() & ": FAIL: Not an enrolment request ***"); log("*** " & testcasename() & ": EtsiTs102941Data.content=", v_pki_request.content); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not(match(v_pki_request.content.enrolmentRequest, mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( -, mw_headerInfo_inner_pki_request )))))) { log("*** " & testcasename() & ": FAIL: Wrong InnerECRequestSignedForPOP headers ***"); log("*** " & testcasename() & ": ", match( v_pki_request.content.enrolmentRequest, m_etsiTs103097Data_signed(mw_signedData( -,mw_toBeSignedData(-,mw_headerInfo_inner_pki_request()))))); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: EC Request received with proper InnerECRequestSignedForPOP headers ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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_08_BV_pki } // End of group f_SECPKI_ITSS_ENR_08 /** * @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.2.1 SECPKI_ITSS_ENR_09_BV * @reference ETSI TS 102 941, clause 6.2.3.2.1 */ testcase TC_SECPKI_ITSS_ENR_09_BV_1() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_09_BV_mtc(c_stInitial); } // End of TC_SECPKI_ITSS_ENR_09_BV_1 testcase TC_SECPKI_ITSS_ENR_09_BV_2() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_09_BV_mtc(c_stEnrolled); } // End of TC_SECPKI_ITSS_ENR_09_BV_2 group f_TC_SECPKI_ITSS_ENR_09_BV { function f_TC_SECPKI_ITSS_ENR_09_BV_mtc(in charstring p_itss_state) 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 if(p_itss_state == c_stEnrolled) { v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); } else { v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); } v_ea.start(f_TC_SECPKI_ITSS_ENR_09_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of f_TC_SECPKI_ITSS_ENR_09_BV_mtc function f_TC_SECPKI_ITSS_ENR_09_BV_pki( in charstring p_itss_state ) 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); if (p_itss_state == c_stEnrolled) { var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request))) { log("*** " & testcasename() & ": INFO: First InnerEcRequest error ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); } f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var Oct16 v_request_hash, v_aes_enc_key; var PublicVerificationKey v_canonical_key; tc_ac.stop; if (not(f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request))) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send error response to prevent enrolment repetition if( not f_http_build_error_ec_response ( unknownits,v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); // check signed message structure if ( not ( match( v_decrypted_message, mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( -, mw_headerInfo_outer_pki_request )))))) { log("*** " & testcasename() & ": FAIL: Invalid outer signed structure in EC request ***"); log("*** " & testcasename() & ": ", match(v_decrypted_message,m_etsiTs103097Data_signed(mw_signedData(-,mw_toBeSignedData(-,mw_headerInfo_outer_pki_request())))) ); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: EC request contains valid outer signed structure ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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_09_BV_pki } // End of group f_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.2.1 SECPKI_ITSS_ENR_10_BV * @reference ETSI TS 102 941, clause 6.2.3.2.1 */ testcase TC_SECPKI_ITSS_ENR_10_BV_1() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_10_BV_mtc(c_stInitial); } // End of TC_SECPKI_ITSS_ENR_10_BV_1 testcase TC_SECPKI_ITSS_ENR_10_BV_2() runs on ItsMtc system ItsPkiItssSystem { f_TC_SECPKI_ITSS_ENR_10_BV_mtc(c_stEnrolled); } // End of TC_SECPKI_ITSS_ENR_10_BV_2 group f_TC_SECPKI_ITSS_ENR_10_BV { function f_TC_SECPKI_ITSS_ENR_10_BV_mtc(in charstring p_itss_state) 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 if(p_itss_state == c_stEnrolled) { v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); } else { v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); } v_ea.start(f_TC_SECPKI_ITSS_ENR_10_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of f_TC_SECPKI_ITSS_ENR_10_BV_mtc function f_TC_SECPKI_ITSS_ENR_10_BV_pki( in charstring p_itss_state ) 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); if (p_itss_state == c_stEnrolled) { var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; if (not(f_await_ec_request_send_response( v_inner_ec_request, v_inner_ec_response, v_request))) { log("*** " & testcasename() & ": INFO: First InnerEcRequest error ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); } f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body 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_recipientInfo_certRecipInfo( mw_pKRecipientInfo(vc_eaHashedId8) ) } )))))), v_request) { var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var Oct16 v_request_hash, v_aes_enc_key; var PublicVerificationKey v_canonical_key; tc_ac.stop; log("*** " & testcasename() & ": PASS: EC request sent to proper EA recipient ***"); if (not(f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request))) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send any response to prevent enrolment repetition // negative is just simpler if( not f_http_build_error_ec_response ( unknownits,v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); // Set verdict log("*** " & testcasename() & ": PASS: EC request can be decrypted ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { f_send_500_Internal_Error(v_headers); // we don't care about response log("*** " & testcasename() & ": FAIL: EC request sent to wrong recipient ***"); 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 // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_10_BV_pki } // End of group f_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 v2.0.1 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_11_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of TC_SECPKI_ITSS_ENR_11_BV group f_TC_SECPKI_ITSS_ENR_11_BV { function f_TC_SECPKI_ITSS_ENR_11_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_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { var Ieee1609Dot2Data v_decrypted_message; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var Oct16 v_request_hash, v_aes_enc_key; var PublicVerificationKey v_canonical_key; tc_ac.stop; if (not f_read_ec_request_from_iut_itss(v_request.request.body.binary_body.ieee1609dot2_data, v_request_hash, v_aes_enc_key, v_decrypted_message, v_pki_request, v_inner_ec_request)) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // send any response to prevent enrolment repetition // negative is easier if( not f_http_build_error_ec_response ( unknownits,v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_response_message) ) { f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": FAIL: Can't build enrolment response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers))); if (not isbound(v_inner_ec_request)) { log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } if (not f_verifyEcdsa(bit2oct(encvalue(v_pki_request.content.enrolmentRequest.content.signedData.tbsData)), int2oct(0, 32), v_pki_request.content.enrolmentRequest.content.signedData.signature_, v_inner_ec_request.publicKeys.verificationKey)) { log("*** " & testcasename() & ": FAIL: EC request signature verification failed ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } // Set verdict log("*** " & testcasename() & ": PASS: PoP signature verified correctly ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] 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_11_BV_pki } // End of group g_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 in enrolled state
       *             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 v2.0.1 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 f_cfMtcDown01(v_itss, v_ea); } // End of TC_SECPKI_ITSS_ENR_12_BV } // End of group itss_enrolment_request // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.2.2 Enrollment response handling 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 v2.0.1 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; var boolean v_iut_state_ok := false; // Test component configuration f_cfUp_itss(); // No IT certificate selected // 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() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 0 }) { tc_ac.stop; v_iut_state_ok := true; log("*** " & testcasename() & "_itss: INFO: IUT is in initialized state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved ***"); //f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement tc_noac.start; alt { [] geoNetworkingPort.receive { log("No CA message expected"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] tc_noac.timeout { if (v_iut_state_ok == true) { log("*** " & testcasename() & "_itss: : PASS: Enrolment trigger processed succesfully ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } else { log("Did not receive IUT state update"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } } // 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_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_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, -, -, 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 v2.0.1 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_02_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_itss() runs on ItsPkiItss system ItsPkiItssSystem { // Local variables var HashedId8 v_certificate_digest; var EtsiTs103097Certificate v_certificate; var boolean v_iut_state_ok := false; // Test component configuration //TODO:DELETE vc_hashedId8ToBeUsed := ""; // No certificates //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() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; v_iut_state_ok := true; log("*** " & testcasename() & "_itss: INFO: IUT is in enrol state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved ***"); //f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement tc_noac.start; alt { [] geoNetworkingPort.receive { log("No CA message expected"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] tc_noac.timeout { if (v_iut_state_ok == true) { log("*** " & testcasename() & "_itss: : PASS: Enrolment trigger processed succesfully ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } else { log("Did not receive IUT state update"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } } // End of 'alt' statement // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_ENR_RECV_02_BV_itss 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_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_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 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_02_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_RECV_02_BV } // End of group itss_enrolment_response // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.2.3 Enrollment request repetition group itss_enrollment_request_repetition { /** * @desc Check that IUT repeats an enrollment request when response has not been received *
       * Pics Selection: PICS_SECPKI_ENROLLMENT_RETRY
       * Initial conditions: {
       *     the IUT being in the 'initialized' state
       *     and the IUT already sent the Enrollment Request at the time T1
       *     and the IUT has not yet received the Enrollment Response
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT local time is reached the T1 + PIXIT_ENR_TIMEOUT_TH1  
       *         }
       *         then {
       *             the IUT sends to EA an EnrollmentRequestMessage
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_01_BV * @reference ETSI TS 103 601, clause 5.1.2 */ group g_TC_SECPKI_ITSS_ENR_REP_01_BV { testcase TC_SECPKI_ITSS_ENR_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_ENROLMENT or not PICS_SECPKI_ENROLLMENT_RETRY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SECPKI_ENROLLMENT_RETRY 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_REP_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_ENR_REP_01_BV function f_TC_SECPKI_ITSS_ENR_REP_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { // Test component configuration f_cfUp_itss(); // No IT certificate selected // Test adapter configuration // Preamble // Initial state: No CAM shall be emitted geoNetworkingPort.clear; tc_noac.start; alt { [] geoNetworkingPort.receive { log("*** " & testcasename() & "_itss: ERROR: Unexpected GeoNet message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_error); } [] tc_noac.timeout { // Trigger the first enrolment log("*** " & testcasename() & "_itss: INFO: No GeoNet message received. Continue ***"); f_sendUtTriggerEnrolmentRequestPrimitive(-, -, -, -, -, false); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body // Nothing to do in test body. Just wait for ENR repetition in PKI component f_selfOrClientSyncAndVerdict(c_tbDone, e_success); // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_01_BV_itss function f_TC_SECPKI_ITSS_ENR_REP_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_initial_request; 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_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { log("*** " & testcasename() & ": INFO: First enrolment request received ***"); tc_ac.stop; f_http_restart("inner_ec_request"); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); // Test Body tc_wait.start(PX_EC_REPETITION_TIMEOUT); alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { log("*** " & testcasename() & ": PASS: EC repetition has been received after a ", tc_wait.read, " ***"); tc_wait.stop; f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } [] tc_wait.timeout { log("*** " & testcasename() & ": FAIL: EC repetition was not received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } } // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_01_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_REP_01_BV /** * @desc Check that IUT uses the same message to perform enrollment retry *
       * Pics Selection: PICS_SECPKI_ENROLLMENT_RETRY
       * Initial conditions: {
       *     the IUT being in the 'initialized' state
       *     and the IUT already sent the Enrollment Request (M)
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to re-send an Enrollment Request 
       *         }
       *         then {
       *             the IUT sends M to EA
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_02_BV * @reference ETSI TS 103 601, clause 5.1.2 */ group f_TC_SECPKI_ITSS_ENR_REP_02_BV { testcase TC_SECPKI_ITSS_ENR_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_ENROLMENT or not PICS_SECPKI_ENROLLMENT_RETRY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SECPKI_ENROLLMENT_RETRY 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_REP_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_02_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_ENR_REP_02_BV function f_TC_SECPKI_ITSS_ENR_REP_02_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request1; var HttpMessage v_request2; // 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_ec_http_request_from_iut(mw_http_ec_request_generic, v_request1) { log("*** " & testcasename() & ": INFO: First enrolment request received ***"); tc_ac.stop; f_http_restart("inner_ec_request"); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut( mw_http_request( mw_http_request_post( PICS_HTTP_POST_URI_EC, -, v_request1.request.body)), v_request2) { tc_ac.stop; log("*** " & testcasename() & ": PASS: Same enrolment request received ***"); // send error respond to prevent future requests f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success); } [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request2) { tc_ac.stop; log("*** " & testcasename() & ": FAIL: 2nd enrolment request is not identical ***"); f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_02_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_REP_02_BV /** * @desc Check that IUT stops sending the Enrollment Request message if Enrollment Response message has been received *
       * Pics Selection: PICS_SECPKI_ENROLLMENT_RETRY
       * Initial conditions: {
       *     the IUT being in the 'initialized' state
       *     and the IUT has sent the Enrollment Request more than 1 time
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT receives an Enrollment Response
       *         }
       *         then {
       *             the IUT stops sending Enrollment Requests to EA
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_03_BV * @reference ETSI TS 103 601, clause 5.1.2 */ testcase TC_SECPKI_ITSS_ENR_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_ENROLMENT or not PICS_SECPKI_ENROLLMENT_RETRY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SECPKI_ENROLLMENT_RETRY 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_REP_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_03_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_ENR_REP_03_BV group f_TC_SECPKI_ITSS_ENR_REP_03_BV { function f_TC_SECPKI_ITSS_ENR_REP_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var HttpMessage v_initial_request; var integer v_rep_count := 0; var integer c_rep_answer := 2; // answer to the n-th request repetition // 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_ec_http_request_from_iut(mw_http_ec_request_generic, v_initial_request) { log("*** " & testcasename() & ": INFO: First enrolment request received ***"); tc_ac.stop; f_http_restart("inner_ec_request"); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); // Test Body tc_ac.start; alt { // match initial request [] a_await_ec_http_request_from_iut( mw_http_ec_request_generic( v_initial_request.request.body.binary_body.ieee1609dot2_data ), v_request ) { v_rep_count := v_rep_count + 1; tc_ac.stop; if (v_rep_count < c_rep_answer) { // skip repetition log("*** " & testcasename() & ": ", v_rep_count, " EC repetition has been received. Continue ***"); f_http_restart("inner_ec_request"); tc_ac.start; repeat; } if(v_rep_count == c_rep_answer) { // answer this repetition log("*** " & testcasename() & ": ", v_rep_count, " EC repetition has been received. Respond ***"); var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var HttpMessage v_response; var integer v_result; 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); } else { // Send HTTP error 500 f_send_500_Internal_Error(v_headers); } // Set verdict if (v_result == 0) { log("*** " & testcasename() & ": PASS: InnerEcRequest received ***"); } else { log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); } repeat; } // repetition request received after sending the response log("*** " & testcasename() & ": FAIL: Repetition request received after response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] a_await_ec_http_request_from_iut( mw_http_ec_request_generic, v_request ) { tc_ac.stop; f_send_500_Internal_Error(v_headers); log("*** " & testcasename() & ": INCONC: New request received during repetition period ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } [] tc_ac.timeout { if(v_rep_count < c_rep_answer) { log("*** " & testcasename() & ": INCONC: Timeout occured during the repetition period ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } log("*** " & testcasename() & ": PASS: EC repetition request was not received after response ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } } // End of alt statment // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_03_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_REP_03_BV /** * @desc Check that IUT stops sending the Enrollment Request message if maximum number of retry has been reached *
       * Pics Selection: PICS_SECPKI_ENROLLMENT_RETRY
       * Initial conditions: {
       *     the IUT being in the 'initialized' state
       *     and the IUT has started sending the Enrollment Request
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT sent the PIXIT_ENR_MAX_N1 Enrollment Request messages
       *         }
       *         then {
       *             the IUT stops sending Enrollment Requests
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_04_BV * @reference ETSI TS 103 601, clause 5.1.2 */ testcase TC_SECPKI_ITSS_ENR_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_ENROLMENT or not PICS_SECPKI_ENROLLMENT_RETRY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SECPKI_ENROLLMENT_RETRY 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_REP_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_04_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_ENR_REP_04_BV group f_TC_SECPKI_ITSS_ENR_REP_04_BV { function f_TC_SECPKI_ITSS_ENR_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 integer v_count := 0; // 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{ [v_count <= PX_ENR_MAX_N1] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_initial_request) { v_count := v_count + 1; repeat; } [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_initial_request){ // count exceed log("*** " & testcasename() & ": FAIL: Too many repetitions of Enrolment requests received ***"); f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_error); } [] tc_ac.timeout{ if(v_count > PX_ENR_MAX_N1){ log("*** " & testcasename() & ": PASS: Maximum number of Enrollment request repetitions received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } else { log("*** " & testcasename() & ": INCONC: Expected message not received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } } // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_04_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_REP_04_BV /** * @desc Check that IUT stops sending the Enrollment Request message if timeout has been reached *
       * Pics Selection: PICS_SECPKI_ENROLLMENT_RETRY
       * Initial conditions: {
       *     the IUT being in the 'initialized' state
       *     and the IUT has started sending the Enrollment Request at the time T1
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT sent the PIXIT_ENR_TIMEOUT_TH2 Enrollment Request messages
       *         }
       *         then {
       *             the IUT stops sending an Enrollment Request messages
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_05_BV * @reference ETSI TS 103 601, clause 5.1.2 */ testcase TC_SECPKI_ITSS_ENR_REP_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_ENROLMENT or not PICS_SECPKI_ENROLLMENT_RETRY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SECPKI_ENROLLMENT_RETRY 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_REP_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_05_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_ENR_REP_05_BV group f_TC_SECPKI_ITSS_ENR_REP_05_BV { function f_TC_SECPKI_ITSS_ENR_REP_05_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var HttpMessage v_initial_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_ec_http_request_from_iut(mw_http_ec_request_generic, v_initial_request) { log("*** " & testcasename() & ": INFO: First enrolment request received ***"); tc_ac.stop; f_http_restart("inner_ec_request"); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); // Test body tc_wait.start(PX_EC_REPETITION_TIMEOUT_TH2); alt { [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) { log("*** " & testcasename() & ": FAIL: No EC repetition should be received ***"); tc_wait.stop; f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] tc_wait.timeout { log("*** " & testcasename() & ": PASS: EC repetition not received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } } // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_ENR_REP_05_BV_pki } // End of group f_TC_SECPKI_ITSS_ENR_REP_05_BV } // End of group itss_enrollment_request_repetition // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.3.1 Authorization request group itss_authorization_request { function f_TC_SECPKI_ITSS_AUTH_itss( in integer p_execution_count := 1, in boolean p_force_enrolment := PX_TRIGGER_EC_BEFORE_AT ) runs on ItsPkiItss system ItsPkiItssSystem { // Local variables 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() & "_itss: : INFO: No CA message received ***"); if (p_force_enrolment) { f_sendUtTriggerEnrolmentRequestPrimitive(); tc_ac.start; alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; log("*** " & testcasename() & "_itss: INFO: IUT is in enrol state ***"); } [LibItsPki_Pics.PICS_UT_STATE_INDICATION ] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } [not LibItsPki_Pics.PICS_UT_STATE_INDICATION ] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT doesn't support state indication. Assume it was well done.***"); } } // End of 'alt' statement } else { log("*** " & testcasename() & "_itss: DBG: Assume IUT already in enrolled state.***"); } f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body var integer v_i := 0; label l_repeat; log("*** " & testcasename() & "_itss: DBG: Send UT Authorisation request " & int2str(v_i) & " out of " & int2str(p_execution_count) & ". ***"); f_sendUtTriggerAuthorizationRequestPrimitive(); v_i := v_i + 1; if( v_i < p_execution_count ){ log("*** " & testcasename() & "_itss: Sync on " & c_nextTry & ". ***"); f_clientSync(c_nextTry , e_success ); f_sleep ( 1.0 ); goto l_repeat; } log("*** " & testcasename() & "_itss: Success. ***"); f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_AUTH_04_BV_itss type record TC_SECPKI_ITSS_AUTH_04_BV_pki_test_data { OctSet nonces, OctSet symmKeys }; type set of PublicVerificationKey SetOfPublicVerificationKey; type set of BasePublicEncryptionKey SetOfPublicEncryptionKey; type record TC_SECPKI_ITSS_AUTH_06_BV_pki_test_data { SetOfPublicVerificationKey vKeys, SetOfPublicEncryptionKey eKeys, OctSet hmacKeys }; type record SECPKI_ITSS_TestData { integer counter, Oct16 aesKey, union { integer none_, TC_SECPKI_ITSS_AUTH_04_BV_pki_test_data tc04, TC_SECPKI_ITSS_AUTH_06_BV_pki_test_data tc06 } anyData }; const SECPKI_ITSS_TestData SECPKI_ITSS_TestData_init_value := {0, '00000000000000000000000000000000'O, {none_:=0}}; type function F_Test_Ieee1609Dot2Data (inout SECPKI_ITSS_TestData p_data, in Ieee1609Dot2Data p_value) runs on ItsPkiHttp return boolean; type function F_Test_EtsiTs102941Data (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean; function f_TC_SECPKI_ITSS_AUTH_pki_simple( in SECPKI_ITSS_TestData p_data := SECPKI_ITSS_TestData_init_value,//< Data to be sent to callbacks in F_Test_Ieee1609Dot2Data pf_test_encryptedData := null, //< function to be called when outer message is decrypted in F_Test_Ieee1609Dot2Data pf_test_signedData := null, //< function to be called to test signed data in F_Test_EtsiTs102941Data pf_test_pkiRequest := null, //< function to be called to test pki request in integer p_execution_count := 1, //< count of messages to be tested in boolean p_force_enrolment := PX_TRIGGER_EC_BEFORE_AT, in template (present) HttpMessage pmw_at_request := mw_http_at_request_generic, in AuthorizationResponseCode p_responseCode := ok ) runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(p_data, pf_test_encryptedData, pf_test_signedData, pf_test_pkiRequest, p_execution_count, p_force_enrolment, pmw_at_request, p_responseCode); f_cfHttpDown(); } function f_TC_SECPKI_ITSS_AUTH_pki( inout SECPKI_ITSS_TestData p_data, //< Data to be sent to callbacks in F_Test_Ieee1609Dot2Data pf_test_encryptedData := null, //< function to be called when outer message is decrypted in F_Test_Ieee1609Dot2Data pf_test_signedData := null, //< function to be called to test signed data in F_Test_EtsiTs102941Data pf_test_pkiRequest := null, //< function to be called to test pki request in integer p_execution_count := 1, //< count of messages to be tested in boolean p_force_enrolment := PX_TRIGGER_EC_BEFORE_AT, in template (present) HttpMessage pmw_at_request := mw_http_at_request_generic, in AuthorizationResponseCode p_responseCode := ok ) runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var HttpMessage v_response; var InnerAtRequest v_inner_at_request; // Preamble f_init_default_headers_list(-, "inner_at_response", v_headers); if (p_force_enrolment) { var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; if (f_await_ec_request_send_response(v_inner_ec_request, 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 var charstring c_interSyncPoint; if (p_execution_count > 1) { c_interSyncPoint := c_nextTry; } else { c_interSyncPoint := c_tbDone; } p_data.counter := 0; log("*** " & testcasename() & ": Wait for Authorization message " & int2str(p_data.counter) & " ***"); tc_ac.start; alt { [] a_await_at_http_request_from_iut(pmw_at_request, v_request) { var Oct16 v_request_hash; var Ieee1609Dot2Data v_request_message_signed; var Ieee1609Dot2Data v_response_message; var EtsiTs102941Data v_pki_request; var InnerAtResponse v_at_response; var boolean v_result; tc_ac.stop; if( pf_test_encryptedData != null ){ if( not pf_test_encryptedData.apply( p_data, v_request.request.body.binary_body.ieee1609dot2_data )){ log("*** " & testcasename() & ": FAIL: Encrypted data check failed ***"); f_send_500_Internal_Error(v_headers); f_selfOrClientSyncAndVerdict(c_interSyncPoint, e_error); } } if(pf_test_signedData == null and pf_test_pkiRequest == null) { // don't need to parse the rest of the message f_send_500_Internal_Error(v_headers); } else { v_result := f_read_pki_request_message ( v_request.request.body.binary_body.ieee1609dot2_data, vc_aaPrivateEncKey, vc_aaWholeHash, v_request_hash, p_data.aesKey, v_request_message_signed, v_pki_request); if( isbound(v_request_message_signed) ){ if(pf_test_signedData != null){ v_result := pf_test_signedData.apply(p_data, v_request_message_signed ); } } if(not v_result) { log("*** " & testcasename() & ": FAIL: Can't parse Auth request ***"); f_send_500_Internal_Error(v_headers); f_selfOrClientSyncAndVerdict(c_interSyncPoint, e_error); } log("*** " & testcasename() & ": The " & int2str(p_data.counter) & " Authorization message received ***"); var template (omit) InnerAtRequest v_innerAtRequest := omit; if(pf_test_pkiRequest != null){ // send response to prevent auth repetition if( ischosen ( v_pki_request.content.authorizationRequest ) ) { v_innerAtRequest := v_pki_request.content.authorizationRequest; } } if(p_responseCode == ok and not isvalue(v_innerAtRequest)){ p_responseCode := its_aa_cantparse; } if( not f_http_build_authorization_response ( v_innerAtRequest , p_responseCode , v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, p_data.aesKey, v_at_response, v_response_message) ) { f_send_500_Internal_Error(v_headers); }else{ f_http_send(v_headers, m_http_response( m_http_response_ok( m_http_message_body_binary( m_binary_body_ieee1609dot2_data(v_response_message) ), v_headers ))); } if( pf_test_pkiRequest != null) { if( not pf_test_pkiRequest.apply( p_data, v_pki_request ) ) { f_selfOrClientSyncAndVerdict(c_interSyncPoint, e_error); } } } p_data.counter := p_data.counter + 1; if( p_data.counter < p_execution_count ) { f_clientSync(c_nextTry, e_success); log("*** " & testcasename() & ": Wait for Auth message " & int2str(p_data.counter) & " ***"); tc_ac.start; repeat; } log("*** " & testcasename() & ": PASS: Everything OK ***"); } [] a_await_at_http_request_from_iut(?, v_request) { log("*** " & testcasename() & ": ERROR: Strange message received ***"); f_selfOrClientSyncAndVerdict(c_interSyncPoint, e_error); } [] tc_ac.timeout { log("*** " & testcasename() & ": INCONC: Expected message not received ***"); f_selfOrClientSyncAndVerdict(c_interSyncPoint, e_timeout); } } // End of 'alt' statement f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } // End of function f_TC_SECPKI_ITSS_AUTH_pki /** * @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 v2.0.1 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_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // 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_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var InnerEcRequest v_inner_ec_request; var InnerEcResponse v_inner_ec_response; var template (omit) EtsiTs103097Certificate v_ec_cert := omit; // 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_at_response", v_headers); if (PX_TRIGGER_EC_BEFORE_AT) { if (f_await_ec_request_send_response(v_inner_ec_request, v_inner_ec_response, v_request) == true) { v_ec_cert := v_inner_ec_response.certificate; 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_request_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_authorizationRequestMessage( mw_encryptedData( { *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(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_ec_cert, v_inner_at_request, v_inner_at_response, v_response, v_result); log("f_TC_SECPKI_ITSS_AUTH_01_BV_pki: v_result: ", v_result); log("f_TC_SECPKI_ITSS_AUTH_01_BV_pki: v_response: ", v_response); // 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: InnerAtResponse 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 v2.0.1 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_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_02_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_02_BV group f_TC_SECPKI_ITSS_AUTH_02_BV { function f_TC_SECPKI_ITSS_AUTH_02_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); var SECPKI_ITSS_TestData v_data; f_TC_SECPKI_ITSS_AUTH_pki( v_data, -, -, -, -, -, mw_http_request( mw_http_request_post( PICS_HTTP_POST_URI_AT, -, mw_http_message_body_binary( mw_binary_body_ieee1609dot2_data( mw_authorizationRequestMessage( mw_encryptedData( { *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_aaHashedId8)), * }, ? )))))), ok ); // Postamble f_cfHttpDown(); } // end of function f_TC_SECPKI_ITSS_AUTH_02_BV_pki } // end of group f_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 AA being in the "operational state"
       *             authorized with AA certificate
       *                 containing encryptionKey (AA_ENC_PUB_KEY)
       *         and the IUT being in the "enrolled" 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
       *                         containing data
       *                             encrypted using AA_ENC_PUB_KEY
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 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_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, refers(f_TC_SECPKI_ITSS_AUTH_03_BV_pki_check_encryptedData), refers(f_TC_SECPKI_ITSS_AUTH_03_BV_pki_check_signedData))); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_03_BV group f_TC_SECPKI_ITSS_AUTH_03_BV { function f_TC_SECPKI_ITSS_AUTH_03_BV_pki_check_encryptedData (inout SECPKI_ITSS_TestData p_data, in Ieee1609Dot2Data p_value) runs on ItsPkiHttp return boolean { var template (present) EtsiTs103097Data mw := m_etsiTs103097Data_encrypted( mw_encryptedData( { [0] := mw_recipientInfo_certRecipInfo( mw_pKRecipientInfo( vc_aaHashedId8 ) ) } ) ); /* Ieee1609Dot2Data : { protocolVersion := ?, content := { encryptedData := { recipients := { [0] := { certRecipInfo := { recipientId := vc_aaHashedId8, encKey := ? } } }, ciphertext := ? } } }; */ if(not match (p_value, mw)){ log("*** " & testcasename() & ": FAIL: Not an encrypted message or wrong encryption target used (not an AA digest) ***"); log(match(p_value, mw)); return false; } return true; } // end of function f_TC_SECPKI_ITSS_AUTH_03_BV_pki_check_encryptedData function f_TC_SECPKI_ITSS_AUTH_03_BV_pki_check_signedData ( inout SECPKI_ITSS_TestData p_data, in Ieee1609Dot2Data p_value) runs on ItsPkiHttp return boolean { // need for this function to check an actual decryption return true; } } // end of group f_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 v2.0.1 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_aa; var SECPKI_ITSS_TestData v_data := SECPKI_ITSS_TestData_init_value; v_data.anyData.tc04 := {{},{}}; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss(PX_RE_AUTHORIZATION_COUNTER)); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(v_data, refers(f_TC_SECPKI_ITSS_AUTH_04_BV_pki_check_encryptedData), refers(f_TC_SECPKI_ITSS_AUTH_04_BV_pki_check_signedData), null, PX_RE_AUTHORIZATION_COUNTER )); // Synchronization f_serverSyncClientsTimed (2, c_prDone, PX_TSYNC_TIME_LIMIT ); for (var integer v_i := 1; v_i < PX_RE_AUTHORIZATION_COUNTER; v_i := v_i + 1) { f_serverSyncClientsTimed (2, c_nextTry, PX_TSYNC_TIME_LIMIT ); } f_serverSyncClientsTimed (2, c_tbDone, PX_TSYNC_TIME_LIMIT ); f_serverWaitForAllClientsToStop(); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // 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_pki_check_encryptedData (inout SECPKI_ITSS_TestData p_data, in Ieee1609Dot2Data p_value) runs on ItsPkiHttp return boolean { if( not isbound (p_value.content.encryptedData.ciphertext.aes128ccm.nonce)){ log("*** " & testcasename() & ": FAIL: At step " & int2str(p_data.counter) &": nonce not found in a message ***"); return false; } var octetstring v_nonce := p_value.content.encryptedData.ciphertext.aes128ccm.nonce; if (isbound(p_data.anyData.tc04.nonces) and match(p_data.anyData.tc04.nonces, superset(v_nonce))) { log("*** " & testcasename() & ": FAIL: At step " & int2str(p_data.counter) & " duplicate nonce found ***"); log(" nonce is: ", v_nonce); return false; } log("*** " & testcasename() & ": LOG: At step " & int2str(p_data.counter) &" nonces are unique ***"); p_data.anyData.tc04.nonces[p_data.counter] := v_nonce; return true; } function f_TC_SECPKI_ITSS_AUTH_04_BV_pki_check_signedData (inout SECPKI_ITSS_TestData p_data, in Ieee1609Dot2Data p_value) runs on ItsPkiHttp return boolean { if (isbound(p_data.anyData.tc04.symmKeys) and match(p_data.anyData.tc04.symmKeys, superset(p_data.aesKey))) { log("*** " & testcasename() & ": FAIL: At step " & int2str(p_data.counter) &": duplicate symmetric encryption keys found ***"); log(" key is: ", p_data.aesKey); return false; } log("*** " & testcasename() & ": LOG: At step " & int2str(p_data.counter) &": symmetric encryption keys are unique ***"); p_data.anyData.tc04.symmKeys[p_data.counter] := p_data.aesKey; return true; } } // 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 v2.0.1 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_itss()); v_ea.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_05_BV_pki_check_authRequest))); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_AUTH_05_BV group f_TC_SECPKI_ITSS_AUTH_05_BV { function f_TC_SECPKI_ITSS_AUTH_05_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { if(not match (p_value, mw_etsiTs102941Data_authorization_request)){ log("*** " & testcasename() & "_pki: FAIL: Invalid message received ***"); return false; } return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_05_BV_pki /** * @desc Check that for each authorization request the ITS-S generates a new verification key pair * Check that for each authorization request the ITS-S generates a new encryption key pair * Check that for each authorization request the ITS-S generates a new hmac-key *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         the IUT being in the "operational state"
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
	     *	            containing EtsiTs102941Data
	     *		            containing authorizationRequest
	     *			            containing publicKeys
       *                    containing verificationKey
	     *					            indicating value not equal to the field verificationKey of N previous messages
	     *				            and not containing encryptionKey
	     *				            or containing encryptionKey
	     *					            indicating value not equal to the field encryptionKey of N previous messages
	     *			            and containing hmacKey
	     *				            indicating value not equal to the field hmacKey of N previous messages
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_06_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_06_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; var SECPKI_ITSS_TestData v_data := SECPKI_ITSS_TestData_init_value; v_data.anyData.tc06 := {{},{},{}}; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss(PX_RE_AUTHORIZATION_COUNTER)); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_05_BV_pki_check_authRequest), PX_RE_AUTHORIZATION_COUNTER )); // Synchronization f_serverSyncClientsTimed ( 2, c_prDone, PX_TSYNC_TIME_LIMIT ); for (var integer v_i := 1; v_i < PX_RE_AUTHORIZATION_COUNTER; v_i := v_i + 1) { f_serverSyncClientsTimed ( 2, c_nextTry, PX_TSYNC_TIME_LIMIT ); } f_serverSyncClientsTimed ( 2, c_tbDone, PX_TSYNC_TIME_LIMIT ); f_serverWaitForAllClientsToStop(); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_06_BV group f_TC_SECPKI_ITSS_AUTH_06_BV { function f_TC_SECPKI_ITSS_AUTH_06_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { if (not isvalue(p_value.content.authorizationRequest)){ log("*** " & testcasename() & "_pki: FAIL: Invalid message received ***"); return false; } if (isbound(p_data.anyData.tc06.vKeys) and match(p_data.anyData.tc06.vKeys, superset(p_value.content.authorizationRequest.publicKeys.verificationKey))) { log("*** " & testcasename() & "_pki: FAIL: At step " & int2str(p_data.counter) & " duplicate verification key found ***"); return false; } log("*** " & testcasename() & "_pki: LOG: At step " & int2str(p_data.counter) &" verification keys are unique ***"); p_data.anyData.tc06.vKeys[p_data.counter] := p_value.content.authorizationRequest.publicKeys.verificationKey; if( ispresent (p_value.content.authorizationRequest.publicKeys.encryptionKey)){ if (isbound(p_data.anyData.tc06.eKeys) and match(p_data.anyData.tc06.eKeys, superset(p_value.content.authorizationRequest.publicKeys.encryptionKey.publicKey))) { log("*** " & testcasename() & "_pki: FAIL: At step " & int2str(p_data.counter) & " duplicate encryption key found ***"); return false; } log("*** " & testcasename() & "_pki: LOG: At step " & int2str(p_data.counter) &" encryption keys are unique ***"); p_data.anyData.tc06.eKeys[p_data.counter] := p_value.content.authorizationRequest.publicKeys.encryptionKey.publicKey; } if (isbound(p_data.anyData.tc06.hmacKeys) and match(p_data.anyData.tc06.hmacKeys, superset(p_value.content.authorizationRequest.hmacKey))) { log("*** " & testcasename() & "_pki: FAIL: At step " & int2str(p_data.counter) & " duplicate HMAC key found ***"); return false; } log("*** " & testcasename() & "_pki: LOG: At step " & int2str(p_data.counter) &" HMAC keys are unique ***"); p_data.anyData.tc06.hmacKeys[p_data.counter] := p_value.content.authorizationRequest.hmacKey; return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_06_BV /** * @desc Check that ITS-S sends Authorization request with a keyTag field computed as described in ETSI TS 102 941 [1], clause 6.2.3.3.1 *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         the IUT being in the "operational state"
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request a new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	            containing EtsiTs102941Data
       *		            containing authorizationRequest
       *			            containing sharedAtRequest
       *                    containing keyTag
       *					            indicating properly calculated value
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_07_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_07_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_itss()); v_ea.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_07_BV_pki_check_authRequest)) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_AUTH_07_BV group f_TC_SECPKI_ITSS_AUTH_07_BV { function f_TC_SECPKI_ITSS_AUTH_07_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { // calculate keyTag var octetstring v_encoded_tag; var octetstring v_key_tag; v_encoded_tag := bit2oct(encvalue(p_value.content.authorizationRequest.publicKeys.verificationKey)); if (ispresent(p_value.content.authorizationRequest.publicKeys.encryptionKey)) { v_encoded_tag := v_encoded_tag & bit2oct(encvalue(p_value.content.authorizationRequest.publicKeys.encryptionKey)); } v_key_tag := substr( fx_hmac_sha256( // TODO Rename and use a wrapper function p_value.content.authorizationRequest.hmacKey, v_encoded_tag ), 0, 16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously var template (present) EtsiTs102941Data mw := mw_etsiTs102941Data_authorization_request( mw_innerAtRequest( -, -, mw_shared_at_request( -, v_key_tag, - ), - ) ); if(not match (p_value, mw)){ log("*** " & testcasename() & "_pki: FAIL: Wrong keyTag value ***"); log(match (p_value, mw)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_07_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_07_BV_pki_check_authRequest)); f_cfHttpDown(); } */ } // End of group f_TC_SECPKI_ITSS_AUTH_07_BV_pki /** * @desc Check that ITS-S sends Authorization request with eaId of EA certificate *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT is enrolled by the EC, signed with the CERT_EA certificate
       *         the IUT being in the "operational" state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	                containing EtsiTs102941Data
       *		                 containing authorizationRequest
       *			                  containing sharedAtRequest
       *                          containing eaId
       *					                  indicating HashedId8 of CERT_EA certificate
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_08_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_08_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); // force enrolment v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_08_BV_pki_check_authRequest)) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_08_BV group f_TC_SECPKI_ITSS_AUTH_08_BV { function f_TC_SECPKI_ITSS_AUTH_08_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var template (present) EtsiTs102941Data mw := mw_etsiTs102941Data_authorization_request( mw_innerAtRequest( -, -, mw_shared_at_request(vc_eaHashedId8) ) ); if(not match (p_value, mw)){ log("*** " & testcasename() & "_pki: FAIL: Invalid message received ***"); log(match(p_value, mw)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_08_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_08_BV_pki_check_authRequest)); f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_08_BV_pki */ } // End of group f_TC_SECPKI_ITSS_AUTH_08_BV /** * @desc Check that ITS-S sends Authorization request with the certificateFormat equal to 1 *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	                containing EtsiTs102941Data
       *		                 containing authorizationRequest
       *			                  containing sharedAtRequest
       *                          containing certificateFormat
       *					                     indicating 1
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_09_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_09_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_09_BV_pki_check_authRequest)) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_09_BV group f_TC_SECPKI_ITSS_AUTH_09_BV { function f_TC_SECPKI_ITSS_AUTH_09_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { if(not match (p_value, mw_etsiTs102941Data_authorization_request)){ log("*** " & testcasename() & "_pki: FAIL: Invalid message received ***"); log(match(p_value, mw_etsiTs102941Data_authorization_request)); return false; } return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_09_BV /** * @desc Check that ITS-S sends Authorization request certificate attributes are properly set *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	              containing EtsiTs102941Data
       *		               containing authorizationRequest
       *			                containing sharedAtRequest
       *                          containing requestedSubjectAttributes
       *					                   containing appPermissions
       *                             and not containing certIssuePermissions
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_10_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_10_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_10_BV_pki_check_authRequest)) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_08_BV group f_TC_SECPKI_ITSS_AUTH_10_BV { function f_TC_SECPKI_ITSS_AUTH_10_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var template (present) EtsiTs102941Data mw := mw_etsiTs102941Data_authorization_request( mw_innerAtRequest( -, -, mw_shared_at_request( -, -, mw_certificate_subject_attributes ) ) ); if(not match (p_value, mw)){ log("*** " & testcasename() & "_pki: FAIL: Invalid message received ***"); log(match (p_value, mw)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_10_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_10_BV_pki_check_authRequest)); f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_10_BV_pki */ } // End of group f_TC_SECPKI_ITSS_AUTH_10_BV /** * @desc Check that ITS-S sends Authorization request containing EC signature calculated over the * sharedATRequest using supported hash algorithm *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	                containing EtsiTs102941Data
       *		                 containing authorizationRequest
       *			                  containing ecSignature
       *                           containing structure of type EtsiTs103097Data-SignedExternalPayload
       *                               containing tbsData
       *                                  containing payload
       *                                     containing extDataHash
       *                                        indicating supported hash algorithm 
			 *                                        and indicating hash of sharedATRequest
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_11_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_11_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_11_BV_pki_check_authRequest))); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_11_BV group f_TC_SECPKI_ITSS_AUTH_11_BV { function f_TC_SECPKI_ITSS_AUTH_11_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; if(ischosen(p_value.content.authorizationRequest.ecSignature.encryptedEcSignature)){ // contains encrypted signature if( not f_decrypt(vc_eaPrivateEncKey, // EA private encryption key p_value.content.authorizationRequest.ecSignature.encryptedEcSignature, vc_eaWholeHash, // salt v_ecSignature, // decrypted message v_aes_enc_key)) { return false; } } else { v_ecSignature := p_value.content.authorizationRequest.ecSignature.ecSignature; } var template (present) EtsiTs103097Data mw := mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload_ext(mw_etsiTs103097SupportedAlgHashedData) ) ) ); if(not match (v_ecSignature, mw)){ log("*** " & testcasename() & "_pki: FAIL: Wrong ecSignature format ***"); log(match(v_ecSignature, mw)); return false; } var HashedData v_extDataHash := v_ecSignature.content.signedData.tbsData.payload.extDataHash; // check that the hash is calculated well var template (value) HashedData mw_hashedData; if(ischosen(v_extDataHash.sha256HashedData)){ mw_hashedData.sha256HashedData := f_hashWithSha256(bit2oct(encvalue(p_value.content.authorizationRequest.sharedAtRequest))); }else if(ischosen(v_extDataHash.sha384HashedData)){ mw_hashedData.sha384HashedData := f_hashWithSha384(bit2oct(encvalue(p_value.content.authorizationRequest.sharedAtRequest))); }else{ return false; } if( not match(v_extDataHash, mw_hashedData)){ log("*** " & testcasename() & "_pki: FAIL: SharedAtRequest hash mismatch ***"); log(match(v_extDataHash, mw_hashedData)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_11_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_11_BV_pki_check_authRequest)); f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_10_BV_pki */ } // End of group f_TC_SECPKI_ITSS_AUTH_11_BV /** * @desc Check that the ecSignature psid is set to the proper ITS_AID * Check that the ecSignature generation time is present *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	                containing EtsiTs102941Data
       *		                 containing authorizationRequest
       *			                  containing ecSignature
       *                            containing structure of type EtsiTs103097Data-SignedExternalPayload
       *                                containing tbsData
       *                                    containing headerInfo
       *                                        containing psid
       *                                            indicating AID_PKI_CERT_REQUEST
       *                                         and containing generationTime
       *					                               and not containing any other headers
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_12_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_12_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_12_BV_pki_check_authRequest)) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_11_BV group f_TC_SECPKI_ITSS_AUTH_12_BV { function f_TC_SECPKI_ITSS_AUTH_12_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; if(ischosen(p_value.content.authorizationRequest.ecSignature.encryptedEcSignature)){ // contains encrypted signature if( not f_decrypt(vc_eaPrivateEncKey, // EA private encryption key p_value.content.authorizationRequest.ecSignature.encryptedEcSignature, vc_eaWholeHash, // salt v_ecSignature, // decrypted message v_aes_enc_key)) { return false; } } else { v_ecSignature := p_value.content.authorizationRequest.ecSignature.ecSignature; } var template (present) EtsiTs103097Data mw := mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( -, mw_headerInfo_ecSignature ) ) ); if(not match (v_ecSignature, mw)){ log("*** " & testcasename() & "_pki: FAIL: Invalid header info in ecSignature received ***"); log(match (v_ecSignature, mw)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_12_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_12_BV_pki_check_authRequest)); f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_10_BV_pki */ } // End of group f_TC_SECPKI_ITSS_AUTH_11_BV /** * @desc Check that ITS-S sends Authorization request containing EC signature * with supported hash algorithm *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the AA
       *	                containing EtsiTs102941Data
       *		                 containing authorizationRequest
       *			                  containing ecSignature
       *                           containing structure of type EtsiTs103097Data-SignedExternalPayload
       *                              containing hashId
       *                                 indicating supported hash algorithm
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_13_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_13_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_itss()); v_ea.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_13_BV_pki_check_authRequest))); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_AUTH_13_BV group f_TC_SECPKI_ITSS_AUTH_13_BV { function f_TC_SECPKI_ITSS_AUTH_13_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; if(ischosen(p_value.content.authorizationRequest.ecSignature.encryptedEcSignature)){ // contains encrypted signature if( not f_decrypt(vc_eaPrivateEncKey, // EA private encryption key p_value.content.authorizationRequest.ecSignature.encryptedEcSignature, vc_eaWholeHash, // salt v_ecSignature, // decrypted message v_aes_enc_key)) { return false; } } else { v_ecSignature := p_value.content.authorizationRequest.ecSignature.ecSignature; } var template (present) EtsiTs103097Data mw := mw_etsiTs103097Data_signed( mw_signedData( mw_validEtsiTs103097HashAlgorithm) ); if(not match (v_ecSignature, mw)) { log("*** " & testcasename() & "_pki: FAIL: Unsupported ecSignature hash algorithm ***"); log(match (v_ecSignature, mw)); return false; } return true; } /* function f_TC_SECPKI_ITSS_AUTH_13_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Test component configuration var SECPKI_ITSS_TestData v_data; f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); f_TC_SECPKI_ITSS_AUTH_pki(v_data, null, null, refers(f_TC_SECPKI_ITSS_AUTH_13_BV_pki_check_authRequest)); f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_10_BV_pki */ } // End of group f_TC_SECPKI_ITSS_AUTH_11_BV /** * @desc Check that the ecSignature of the Authorization request is signed with EC certificate * Check that the signature over tbsData computed using the private key corresponding to * the EC's verification public key. *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_AUTHORIZATION
       * Initial conditions: 
       *     with {
       *         the IUT is enrolled with CERT_EC certificate
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends EtsiTs103097Data to the AA
       *                containing EtsiTs102941Data
       *                  containing authorizationRequest
       *                    containing ecSignature
       *                      containing structure of type EtsiTs103097Data-SignedExternalPayload
       *                        containing signer
       *                          indicating HashedId8 of the CERT_EC certificate
       *                        containing signature
       *                          indicating signature over sharedATRequest calculated with CERT_EC verificationKey 
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_14_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_14_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss(1, true)); // force enrollment v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_14_BV_pki_check_authRequest), -, true // force enrollment ) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_14_BV group f_TC_SECPKI_ITSS_AUTH_14_BV { function f_TC_SECPKI_ITSS_AUTH_14_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; if(ischosen(p_value.content.authorizationRequest.ecSignature.encryptedEcSignature)){ // contains encrypted signature if( not f_decrypt(vc_eaPrivateEncKey, // EA private encryption key p_value.content.authorizationRequest.ecSignature.encryptedEcSignature, vc_eaWholeHash, // salt v_ecSignature, // decrypted message v_aes_enc_key)) { return false; } } else { v_ecSignature := p_value.content.authorizationRequest.ecSignature.ecSignature; } var template (present) EtsiTs103097Data mw := mw_etsiTs103097Data_signed( mw_signedData(-, -, mw_signerIdentifier_digest( (all from(vc_ec_hashed_id8)) ) ) ); if(not match (v_ecSignature, mw)){ log("*** " & testcasename() & "_pki: FAIL: EC digest mismatch.***"); log(match (v_ecSignature, mw)); return false; } // check signature for(var integer v_i := 0; v_i < vc_ec_counter; v_i := v_i + 1){ if(vc_ec_hashed_id8[v_i] == v_ecSignature.content.signedData.signer.digest){ var EtsiTs103097Certificate v_ec_cert := vc_ec_certificates[v_i]; if(not f_verifySignedMessageECDSA(v_ecSignature, vc_ec_certificates[v_i])){ log("*** " & testcasename() & "_pki: FAIL: EC signature verification failed.***"); return false; } break; } } return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_14_BV /** * @desc Check that the encrypted ecSignature of the Authorization request is encrypted using the EA encryptionKey * Check that the encrypted ecSignature of the Authorization request was done from the * EtsiTs103097Data-SignedExternalPayload structure *
       * Pics Selection: PICS_IUT_ITS_S_ROLE, PICS_SECPKI_AUTHORIZATION and PICS_SECPKI_AUTH_PRIVACY
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *         and the EA in 'operational' state
       *         authorized with CERT_EA certificate
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends EtsiTs103097Data to the AA
       *                containing EtsiTs102941Data
       *                  containing authorizationRequest
       *                    containing ecSignature
       *                      containing encryptedEcSignature
       *                        containing recipients
       *                        containing only one element of type RecipientInfo
       *                          containing certRecipInfo
       *                            containing recipientId
       *                              indicating HashedId8 of the CERT_EA
       *                            and containing encKey
       *                              indicating encryption key of supported type
       *                       and containing cyphertext
       *                        containing encrypted representation of structure EtsiTs103097Data-SignedExternalPayload
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_15_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_15_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // Test control if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_AUTHORIZATION or not PICS_SECPKI_AUTH_PRIVACY) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE, PICS_SECPKI_AUTHORIZATION are required for executing the TC ***"); setverdict(inconc); stop; } if (not PICS_SECPKI_AUTH_PRIVACY) { log("*** " & testcasename() & ": PICS_SECPKI_AUTH_PRIVACY is required for executing the TC ***"); setverdict(inconc); stop; } // Test component configuration f_cfMtcUp01(v_itss, v_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_15_BV_pki_check_authRequest) ) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } group f_TC_SECPKI_ITSS_AUTH_15_BV { function f_TC_SECPKI_ITSS_AUTH_15_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; template (present) EcSignature mw1 := mw_ec_signature ( // strange, but this is a signature with privace template mw_etsiTs103097Data_encrypted( mw_encryptedData( { mw_recipientInfo_certRecipInfo( mw_pKRecipientInfo(vc_eaHashedId8) ) }, mw_symmetricCiphertext_aes128ccm ) ) ); if(not match(p_value.content.authorizationRequest.ecSignature, mw1)){ log("*** " & testcasename() & "_pki: FAIL: Invalid EC signature with mandatory privacy.***"); log(match(p_value.content.authorizationRequest.ecSignature, mw1)); return false; } if( not f_decrypt(vc_eaPrivateEncKey, // EA private encryption key p_value.content.authorizationRequest.ecSignature.encryptedEcSignature, vc_eaWholeHash, // salt v_ecSignature, // decrypted message v_aes_enc_key)) { return false; } var template (present) EtsiTs103097Data mw2 := mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload_ext(mw_etsiTs103097SupportedAlgHashedData) ) ) ); if(not match (v_ecSignature, mw2)){ log("*** " & testcasename() & "_pki: FAIL: Wrong ecSignature format ***"); log(match(v_ecSignature, mw2)); return false; } return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_15_BV /** * @desc Check that the ecSignature of the Authorization request is not encrypted *
       * Pics Selection: PICS_IUT_ITS_S_ROLE, PICS_SECPKI_AUTHORIZATION and not PICS_SECPKI_AUTH_PRIVACY
       * Initial conditions: 
       *     with {
       *         the IUT in 'enrolled' state
       *         and the AA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request new Authorization Ticket (AT)
       *         }
       *         then {
       *             the IUT sends EtsiTs103097Data to the AA
       *                containing EtsiTs102941Data
       *                  containing authorizationRequest
       *                    containing ecSignature
       *                      containing ecSignature
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_AUTH_16_BV * @reference ETSI TS 102 941 [2], clause 6.2.3.3.1 */ testcase TC_SECPKI_ITSS_AUTH_16_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables var ItsPkiItss v_itss; var ItsPkiHttp v_aa; // 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; } if (PICS_SECPKI_AUTH_PRIVACY) { log("*** " & testcasename() & ": PICS_SECPKI_AUTH_PRIVACY should not be set for executing the TC ***"); setverdict(inconc); stop; } // Test component configuration f_cfMtcUp01(v_itss, v_aa); // Start component v_itss.start(f_TC_SECPKI_ITSS_AUTH_itss()); v_aa.start(f_TC_SECPKI_ITSS_AUTH_pki_simple(-, null, null, refers(f_TC_SECPKI_ITSS_AUTH_16_BV_pki_check_authRequest) ) ); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_aa); } // End of testcase TC_SECPKI_ITSS_AUTH_16_BV group f_TC_SECPKI_ITSS_AUTH_16_BV { function f_TC_SECPKI_ITSS_AUTH_16_BV_pki_check_authRequest (inout SECPKI_ITSS_TestData p_data, in EtsiTs102941Data p_value) runs on ItsPkiHttp return boolean { var EtsiTs103097Data v_ecSignature; var octetstring v_aes_enc_key; template (present) EcSignature mw := mw_ec_signature_ext_payload ( mw_etsiTs103097Data_signed( mw_signedData( -, mw_toBeSignedData( mw_signedDataPayload_ext(mw_etsiTs103097SupportedAlgHashedData) ) ) ) ); if(not match(p_value.content.authorizationRequest.ecSignature, mw)){ log("*** " & testcasename() & "_pki: FAIL: Invalid EC signature in no-privacy mode.***"); log(match(p_value.content.authorizationRequest.ecSignature, mw)); return false; } return true; } } // End of group f_TC_SECPKI_ITSS_AUTH_16_BV } // End of group itss_authorization_request // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.3.2 Authorization response handling group itss_authorization_response { // Void } // End of group itss_authorization_response // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.3.3 Authorization request repetition 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 or not PICS_SECPKI_AUTHORIZATION_RETRY) { 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() & "_itss: : INFO: 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() & "_itss: : 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 InnerEcRequest v_inner_ec_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 f_init_default_headers_list(-, "inner_at_response", v_headers); 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 ***"); } // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { if (f_await_ec_request_send_response(v_inner_ec_request, 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); v_inner_ec_response.certificate := omit; } // 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 or not PICS_SECPKI_AUTHORIZATION_RETRY) { 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() & "_itss: : INFO: 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() & "_itss: : 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 InnerEcRequest v_inner_ec_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 f_init_default_headers_list(-, "inner_at_response", v_headers); 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 ***"); } // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { if (f_await_ec_request_send_response(v_inner_ec_request, 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 or not PICS_SECPKI_AUTHORIZATION_RETRY) { 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() & "_itss: : INFO: 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() & "_itss: : 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 InnerEcRequest v_inner_ec_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 f_init_default_headers_list(-, "inner_at_response", v_headers); 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 ***"); } // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { if (f_await_ec_request_send_response(v_inner_ec_request, 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 or not PICS_SECPKI_AUTHORIZATION_RETRY) { 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() & "_itss: : INFO: 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() & "_itss: : INFO: 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 InnerEcRequest v_inner_ec_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); } // 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_request, 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 /** * @desc Check that IUT stops sending the Authorization Request message if timeout has been reached *
       * Pics Selection: PICS_SECPKI_AUTHORIZATION_RETRY
       * Initial conditions: {
       *     the IUT being in the 'enrolled' state
       *     and the IUT has started sending the Authorization Request at the time T1
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT local time is reached the T1 + PIXIT_AUTH_TIMEOUT_TH2
       *         }
       *         then {
       *             the IUT stops sending an Authorization Request messages
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 TP SECPKI_ITSS_AUTH_REP_05_BV * @reference ETSI TS 103 601, clause 5.1.2 */ testcase TC_SECPKI_ITSS_AUTH_REP_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 or not PICS_SECPKI_AUTHORIZATION_RETRY) { 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_05_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_AUTH_REP_05_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } group f_TC_SECPKI_ITSS_AUTH_REP_05_BV { function f_TC_SECPKI_ITSS_AUTH_REP_05_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() & "_itss: : INFO: 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_tbDone, e_error); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } } // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_AUTH_REP_05_BV_itss function f_TC_SECPKI_ITSS_AUTH_REP_05_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var HttpMessage v_at_request; var InnerEcResponse v_inner_ec_response; var InnerEcRequest v_inner_ec_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_at_response", v_headers); 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 ***"); } else { f_selfOrClientSyncAndVerdict(c_prDone, e_success); } // Do not expect any repetition if (PX_TRIGGER_EC_BEFORE_AT) { if (f_await_ec_request_send_response(v_inner_ec_request, v_inner_ec_response, v_request) == true) { log("*** " & testcasename() & ": INFO: Enrolment succeed ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } else { log("*** " & testcasename() & ": INCONC: Enrolment failed ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // Test Body tc_wait.start(PX_AT_REPETITION_TIMEOUT_TH2); // PX_AT_REPETITION_TIMEOUT alt { [] a_await_at_http_request_from_iut(mw_http_at_request_generic, v_request) { log("*** " & testcasename() & ": FAIL: AT repetition has been received after a ", tc_wait.read, " ***"); //fails in TC5 tc_wait.stop; f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } [] tc_wait.timeout { if (f_await_at_request_send_no_response(v_at_request) == true) { log("*** " & testcasename() & ": FAIL: AT repetition was received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } else { log("*** " & testcasename() & ": PASS: AT repetition was not received ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); } } } // Postamble f_cfHttpDown(); } // End of function f_TC_SECPKI_ITSS_AUTH_REP_05_BV_pki } // End of group f_TC_SECPKI_ITSS_AUTH_REP_05_BV } // End of group itss_authorization_request_repetition // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.3.4 Authorization using butterfly key expansion mechanism group itss_authorization_request_bfk { /** * @desc Check that the ITS-S send the EtsiTs103097Data to the Enrollment Authority (EA) to request a batch of authorization tickets Check that this message is encrypted and addressed to a single recipient. *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SEC_BFK_AUTH
       * Initial conditions: 
       *     with {
       *         the IUT being in the "initial state" and
       *         the EA in 'operational' state
       *             authorized with enrollment certificate CERT_IUT_A_EA
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request a new batch of authorization tickets
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the EA
       *                 containing content.encryptedData
       *                     containing recipients
       *                         indicating size 1
       *                         and containing the instance of RecipientInfo
       *                             containing certRecipInfo
       *                             containing recipientId
       *                             indicating HashedId8 of the CERT_IUT_A_EA
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_01_BV * @reference ETSI TS 102 941 [1], clause 6.2.3.5.1 */ testcase TC_SECPKI_ITSS_BFK_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_ENROLMENT or not PICS_SEC_BFK_AUTH) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SEC_BFK_AUTH 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_BFK_AUTH_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_BFK_AUTH_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_BFK_AUTH_01_BV group f_TC_SECPKI_ITSS_BFK_AUTH_01_BV { function f_TC_SECPKI_ITSS_BFK_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(); tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; log("*** " & testcasename() & "_itss: INFO: IUT is in enrol state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement log("*** " & testcasename() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body f_sendUtTriggerAuthorizationRequestPrimitive(); // TODO FSCOM Add BFK mode 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() & "_itss: : 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_BFK_AUTH_01_BV_itss function f_TC_SECPKI_ITSS_BFK_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; var InnerEcRequest v_inner_ec_request; // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); // Test adapter configuration // Preamble if (f_await_ec_request_send_response(v_inner_ec_request, 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); } // Test Body tc_ac.start; alt { [] a_await_ec_http_request_from_iut( mw_http_request( mw_http_request_post( PICS_HTTP_POST_URI_BFK_AUTH, -, 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 EeRaCertRequest v_bfk_authorization_request; var RaEeCertInfo v_bfk_authorization_response; tc_ac.stop; // Verify IUT response f_verify_http_bfk_authorization_request(v_request.request, v_headers, v_inner_ec_response.certificate, v_bfk_authorization_request, v_bfk_authorization_response, v_response, v_result); // Send response if (isvalue(v_response)) { httpPort.send(v_response); } else { // Send HTTP error 500 f_send_500_Internal_Error(v_headers); } // 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_BFK_AUTH_01_BV_pki } // End of group f_TC_SECPKI_ITSS_BFK_AUTH_01_BV /** * @desc Check that the ButterflyAuthorizationRequestMessage is signed using the EC certificate *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SEC_BFK_AUTH
       * Initial conditions: 
       *     with {
       *         the IUT being in the 'enrolled' state
       *             with certificate CERT_EC
       *                 issued by CA authorized with CERT_IUT_A_EA
       *         and the EA in 'operational' state
       *             authorized with enrollment certificate CERT_IUT_A_EA
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request a new batch of authorization tickets
       *         }
       *         then {
       *             the IUT sends a EtsiTs103097Data to the EA
       *                 containing content.encryptedData.cipherText
       *                     containing encrypted representation of EtsiTs103097Data
       *                         containing signedData
       *                             containing tbsData
       *                                 containing psid
       *                                     indicating AID_PKI_CERT_REQUEST
       *                                 and containing generationTime
       *                                 and not containing any other field
       *                                 and containing payload.data
       *                                     indicating EtsiTs102941Data
       *                                         containing version
       *                                             indicating ‘1’
       *                                         and containing content
       *                                             containing butterflyAuthorizationRequest
       *                                                 indicating EeRaCertRequest
       *                                 and containing signer
       *                                     containing digest
       *                                         indicating HashedId8 of the CERT_EC
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_02_BV * @reference ETSI TS 102 941 [1], clause 6.2.3.5.2 */ testcase TC_SECPKI_ITSS_BFK_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_ENROLMENT or not PICS_SEC_BFK_AUTH) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SEC_BFK_AUTH 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_BFK_AUTH_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_BFK_AUTH_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_BFK_AUTH_02_BV /** * @desc Check that the ButterflyAuthorizationRequestMessage contains all required elements *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SEC_BFK_AUTH
       * Initial conditions: 
       *     with {
       *         the IUT being in the 'enrolled' state
       *         and the EA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request a new batch of authorization tickets (AT)
       *         }
       *         then {
       *             the IUT sends to the EA a EtsiTs103097Data
       *                 containing the EeRaCertRequest
       *                     containing version
       *                         indicating ‘2’
       *                     and containing generationTime
       *                         indicating current ITS timestamp
       *                     and containing certificateType
       *                         indicating ‘explicit”
       *                     and containing tbsCert
       *                         containing id
       *                             indicating ‘none’
       *                         and containing cracaId
       *                             indicating ‘000000’H
       *                         and containing crlSeries
       *                             indicating ‘0’
       *                     and containing additionalParams
       *                         containing original
       *                         or containing unified
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_03_BV * @reference ETSI TS 102 941 [1], clause 6.2.3.5.2 */ testcase TC_SECPKI_ITSS_BFK_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_ENROLMENT or not PICS_SEC_BFK_AUTH) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SEC_BFK_AUTH 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_BFK_AUTH_01_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_BFK_AUTH_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_BFK_AUTH_04_BV /** * @desc Check that the ButterflyAuthorizationRequestMessage contains newlly generated caterpillar public key *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SEC_BFK_AUTH
       * Initial conditions: 
       *     with {
       *         the IUT being in the 'authorized' state
       *         and the IUT already sent one or more Butterfly Authorization Requests
       *         and the EA in 'operational' state
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to request a new batch of authorization tickets (AT)
       *         }
       *         then {
       *             the IUT sends to the EA a EtsiTs103097Data
       *                 containing the EeRaCertRequest
       *                     containing version
       *                         indicating ‘2’
       *                     and containing generationTime
       *                         indicating current ITS timestamp
       *                     and containing certificateType
       *                         indicating ‘explicit”
       *                     and containing tbsCert
       *                         containing id
       *                             indicating ‘none’
       *                         and containing cracaId
       *                             indicating ‘000000’H
       *                         and containing crlSeries
       *                             indicating ‘0’
       *                     and containing additionalParams
       *                         containing original
       *                         or containing unified
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_03_BV * @reference ETSI TS 102 941 [1], clause 6.2.3.5.2 */ testcase TC_SECPKI_ITSS_BFK_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_ENROLMENT or not PICS_SEC_BFK_AUTH) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SEC_BFK_AUTH 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_BFK_AUTH_04_BV_itss()); v_ea.start(f_TC_SECPKI_ITSS_BFK_AUTH_04_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_BFK_AUTH_04_BV group f_TC_SECPKI_ITSS_BFK_AUTH_04_BV { function f_TC_SECPKI_ITSS_BFK_AUTH_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(); tc_ac.start; // TDOD To refined, use altstep alt { [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { tc_ac.stop; log("*** " & testcasename() & "_itss: INFO: IUT is in enrol state ***"); } [] tc_ac.timeout { log("*** " & testcasename() & "_itss: DBG: IUT state update not recieved ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); } } // End of 'alt' statement log("*** " & testcasename() & "_itss: : INFO: No CA message received ***"); f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement // Test Body f_sendUtTriggerAuthorizationRequestPrimitive(); // TODO FSCOM Add BFK mode 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() & "_itss: : 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_BFK_AUTH_04_BV_itss function f_TC_SECPKI_ITSS_BFK_AUTH_04_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable var Headers v_headers; var HttpMessage v_request; var InnerEcResponse v_inner_ec_response; var InnerEcRequest v_inner_ec_request; // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); // Test adapter configuration // Preamble if (f_await_ec_request_send_response(v_inner_ec_request, 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); } // Test Body 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_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * }, mw_symmetricCiphertext_aes128ccm )))))), v_request ) { var HttpMessage v_response; var integer v_result; var EeRaCertRequest v_bfk_authorization_request; var RaEeCertInfo v_bfk_authorization_response; tc_ac.stop; // Verify IUT response f_verify_http_bfk_authorization_request(v_request.request, v_headers, v_inner_ec_response.certificate, v_bfk_authorization_request, v_bfk_authorization_response, v_response, v_result); // Send response if (isvalue(v_response)) { httpPort.send(v_response); } else { // Send HTTP error 500 f_send_500_Internal_Error(v_headers); } // 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_BFK_AUTH_04_BV_pki } // End of group f_TC_SECPKI_ITSS_BFK_AUTH_04_BV /** * @desc Check that IUT downloads the AT certificates batch after receiving of positive ButterflyAuthorizationResponse message *
       * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SEC_BFK_AUTH
       * Initial conditions: 
       *     with {
       *         the IUT being in the 'enrolled' state
       *         and the EA in 'operational' state
       *         and the IUT has sent the ButterflyAuthorizationRequestMessage
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT receives an EtsiTs102941Data as an answer of the EA
       *                 containing butterflyAuthorizationResponse
       *                     indicating RaEeCertInfo
       *                         containing generationTime
       *                             indicating GEN_TIME
       *                         and containing currentI
       *                             indicating VALUE_I
       *                         and containing requestHash
       *                             indicating REQ_HASH
       *                         and containing nextDlTime
       *                             indicating time between GEN_TIME and current time 
       *         }
       *         then {
       *             the IUT send the ButterflyAtDownloadRequestMessage
       *                 containing butterflyAtDownloadRequest
       *                     indicating EeRaDownloadRequest
       *                         containing generationTime
       *                             indicating value more than GEN_TIME
       *                         and containing filename
       *                             indicating string REQ_HASH + “_” + VALUE_I + “.zip”
       *         }
       *     }
       * 
* * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_BFK_CERTDNL_01_BV * @reference ETSI TS 102 941 [1], clauses 6.2.3.5.3 and 6.2.3.5.6 */ testcase TC_SECPKI_ITSS_BFK_CERTDNL_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 or not PICS_SEC_BFK_AUTH) { log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT or PICS_SEC_BFK_AUTH required for executing the TC ***"); setverdict(inconc); stop; } // Test component configuration f_cfMtcUp01(v_itss, v_ea); // Start components v_itss.start(TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_itss()); v_ea.start(TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup f_cfMtcDown01(v_itss, v_ea); } // End of testcase TC_SECPKI_ITSS_BFK_CERTDNL_01_BV group f_TC_SECPKI_ITSS_BFK_CERTDNL_01_BV { function TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { // FIXME TODO } // End of function TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_itss function TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { // FIXME TODO } // End of function TC_SECPKI_ITSS_BFK_CERTDNL_01_BV_pki } // End of group f_TC_SECPKI_ITSS_BFK_CERTDNL_01_BV } // End of group itss_authorization_request_bfk // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.4 CTL handling 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_TLM )), 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_DC )), 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_TLM )), 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_TLM )), 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_DC )), 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_TLM )), 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 { 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 // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.5 CTL distribution 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_TLM )), 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_TLM )), 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_TLM )), 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_TLM )), 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 // TODO } // End of group itss_ctl_distribution // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.6 CRL handling 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 // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.2.7 CRL distribution 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 } // End of module ItsPkiItss_TestCases