diff --git a/ItsPki_Pixits.ttcn b/ItsPki_Pixits.ttcn index 301885d353aa92efc2314d6ab70d582fe6449d87..689624336858d01187c4ef65052889376e36e8ad 100644 --- a/ItsPki_Pixits.ttcn +++ b/ItsPki_Pixits.ttcn @@ -10,4 +10,9 @@ module ItsPki_Pixits { modulepar boolean PX_TRIGGER_EC_BEFORE_AT := true; + modulepar boolean PX_CHECK_INITIAL_STATES := true; + + modulepar float PX_CERT_EXPIRATION_DELAY := 10.0; + + modulepar float PX_EC_REPETITION_TIMEOUT := 120.0; } // End of module ItsPki_Pixits diff --git a/ItsPki_TestCases.ttcn b/ItsPki_TestCases.ttcn index b36a0d77035f020390258d9f9cf6ce3b22079c41..b018b55d8e71df612078136238c09a396c004f63 100644 --- a/ItsPki_TestCases.ttcn +++ b/ItsPki_TestCases.ttcn @@ -86,6 +86,12 @@ module ItsPki_TestCases { * @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 { @@ -116,12 +122,13 @@ module ItsPki_TestCases { out InnerEcResponse p_inner_ec_response, out HttpMessage p_response, out integer p_result, - in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID, - in template SignerIdentifier p_signer := m_signerIdentifier_self, + in 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; @@ -129,40 +136,70 @@ module ItsPki_TestCases { 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 (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message + 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 - v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an 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 := -1; - } else { - log("f_verify_http_ec_request_from_iut_itss: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))); // TODO In TITAN, this is the only way to get the unmatching in log - if (match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer)))) == false) { + p_result := -2; + goto L_Done; + } +/* + var bitstring v_msg_bit := oct2bit(v_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData); + if (decvalue(v_msg_bit, p_inner_ec_request) != 0) { // 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); + 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); // Set verdict p_result := -2; - } else { + goto L_Done; + } +*/ // Verify signature of mw_innerEcRequestSignedForPop - if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request) == false) { + 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; - } else { + 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 (match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)}))) == false) { + 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; - } else { + goto L_Done; + } + // TODO Check ValidityPeriod // Send OK message log("f_verify_http_ec_request_from_iut_itss: Receive ", p_inner_ec_request); @@ -199,12 +236,11 @@ module ItsPki_TestCases { 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); } - 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)); - } - } - } - } + 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); @@ -217,7 +253,7 @@ module ItsPki_TestCases { function f_verify_http_at_request_from_iut_itss( in Request p_request, in Headers p_headers, - in EtsiTs103097Certificate p_ec_certificate, + in template (omit) EtsiTs103097Certificate p_ec_certificate, out InnerAtRequest p_inner_at_request, out InnerAtResponse p_inner_at_response, out HttpMessage p_response, @@ -226,47 +262,122 @@ module ItsPki_TestCases { in AuthorizationResponseCode p_force_response_code := ok ) runs on ItsPkiHttp { // Local variables - var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + var Ieee1609Dot2Data v_ieee1609dot2_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 octetstring v_msg; + log(">>> f_verify_http_at_request_from_iut_itss:", p_request); p_result := 0; - // Do not verify the signature now because ATRequest is required to verify the POP signature ==> false - if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Only decryption - // Send error message, unable to decrypt it - v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_response with an error message + // 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; + } + log("f_verify_http_at_request_from_iut_itss: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // TODO In TITAN, this is the only way to get the unmatching in log if (match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest)) == false) { // Send error message - f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + 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 { + return; + } +/* // Extract InnerAtRequest and Verify signature of mw_innerATRequestSignedForPop + if(!ispresent(p_ec_certificate)){ + // get ec certificate from + if(not f_readCertificate(PICS_IUT_EC_CERTIFICATE_ID, p_ec_certificate)){ + f_http_build_authorization_response(p_inner_at_request, unknownits, 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; + } + } +*/ if (f_verify_inner_at_request_signed_for_pop(v_etsi_ts_102941_data, p_ec_certificate, p_inner_at_request) == false) { // Send error message - f_http_build_authorization_response(p_inner_at_request, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); - v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + 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; - } else { - log("f_verify_http_at_request_from_iut_itss: match ", match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // TODO In TITAN, this is the only way to get the unmatching in log + 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 enrolment request - f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); - v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + // 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; - } else { + 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; @@ -290,27 +401,22 @@ module ItsPki_TestCases { log("f_verify_http_at_request_from_iut_itss: matching: ", match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag)); if (match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag) == false) { // Send error message: No enrolment request - f_http_build_authorization_response(p_inner_at_request, its_aa_keysdontmatch, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); - v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers)); + 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; - } else { + 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_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + 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, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data); + 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); } - 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); + 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 @@ -611,42 +717,32 @@ module ItsPki_TestCases { // 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; + [] 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; - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } else { // Send HTTP error 500 + 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 - 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 { @@ -689,7 +785,7 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_02_BV + * @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 { @@ -709,7 +805,7 @@ module ItsPki_TestCases { // Start components v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); - v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_02_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); @@ -719,6 +815,103 @@ module ItsPki_TestCases { } // 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_eaPrivateEncKey, + 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(false == 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 + } /** * @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 @@ -748,7 +941,7 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_03_BV + * @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 { @@ -780,13 +973,12 @@ module ItsPki_TestCases { group f_TC_SECPKI_ITSS_ENR_03_BV { - function f_TC_SECPKI_ITSS_ENR_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { - // Local variables - var HashedId8 v_certificate_digest; - var EtsiTs103097Certificate v_certificate; - + function f_TC_SECPKI_ITSS_ENR_03_BV_itss( + in float p_delay := 0.0 + ) runs on ItsPkiItss system ItsPkiItssSystem { // Test component configuration - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + // vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + vc_hashedId8ToBeUsed := ""; f_cfUp_itss(); // Test adapter configuration @@ -821,19 +1013,17 @@ module ItsPki_TestCases { //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(); - tc_noac.start; - alt { - [] geoNetworkingPort.receive { - log("*** " & testcasename() & "_itss: FAIL: No CA message expected ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_error); - } - [] tc_noac.timeout { + log("*** " & testcasename() & "_itss: PASS: Re-enrolment trigger sent succesfully ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - } - } // End of 'alt' statement // Postamble f_cfDown_itss(); @@ -843,117 +1033,98 @@ module ItsPki_TestCases { // Local variable var Headers v_headers; var HttpMessage v_request; - var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + 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); - 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 integer v_result; - var InnerEcRequest v_inner_ec_request; - var InnerEcResponse v_inner_ec_response; - var HttpMessage v_response; - - tc_ac.stop; - - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } else { // Send HTTP error 500 - f_send_500_Internal_Error(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); } - // Set verdict - if (v_result == 0) { log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_success); + log(">>>>> v_inner_ec_response=", v_inner_ec_response); + + 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: Failed to verify EA an EnrolmentRequestMessage ***"); + log("*** " & testcasename() & ": FAIL: Unknown EC certificate hash alg=", ha); 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 + v_ec_cert_digest := substr(v_ec_cert_hash, lengthof(v_ec_cert_hash) - 8, 8); + + 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( // Re-enrolment request - 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 - ) { + [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, v_request) + { var integer v_result; - var InnerEcRequest v_inner_ec_request; - var InnerEcResponse v_inner_ec_response; var HttpMessage v_response; + var Oct16 v_request_hash, v_aes_enc_key; + var Ieee1609Dot2Data v_decrypted_message; + var EtsiTs102941Data v_etsi_ts_102941_data; tc_ac.stop; + f_send_500_Internal_Error(v_headers); // we don't care about response // Verify IUT response - log(">>>>>>>>>>>>>> DBG: vc_ec_keys_counter= ", vc_ec_keys_counter); - log(">>>>>>>>>>>>>> DBG: vc_ec_public_compressed_key[vc_ec_keys_counter - 1]= ", vc_ec_public_compressed_key[vc_ec_keys_counter - 1]); - log(">>>>>>>>>>>>>> DBG: vc_ec_compressed_modes[vc_ec_keys_counter - 1]= ", vc_ec_compressed_modes[vc_ec_keys_counter - 1]); - log(">>>>>>>>>>>>>> DBG: vc_ec_hashed_id8[vc_ec_keys_counter - 1]= ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]); - 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, - vc_ec_hashed_id8[vc_ec_keys_counter - 1], // v_response... - // containing itsId declared as digest containing the HashedId8 of the EC identifier - m_signerIdentifier_digest(vc_ec_hashed_id8[vc_ec_keys_counter - 1] // containing signer declared as digest containing the HashedId8 of the EC identifier - ) - ); + 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)) + { + log("*** " & testcasename() & ": FAIL: Can't parse enrolment request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + if( not isvalue(v_inner_ec_request) ){ + log("*** " & testcasename() & ": FAIL: Can't parse enrolment request ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } else { // Send HTTP error 500 - f_send_500_Internal_Error(v_headers); + 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 - 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 ***"); @@ -982,18 +1153,11 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_04_BV + * @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 - var Oct32 v_private_key; - var Oct32 v_public_key_x; - var Oct32 v_public_key_y; - var Oct32 v_public_compressed_key; - var integer v_compressed_mode; - var ItsPkiItss v_itss; - var ItsPkiHttp v_ea; // Test control if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_CRL) { @@ -1016,17 +1180,23 @@ module ItsPki_TestCases { *
        * Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
        * Expected behaviour:
-       *     ensure that {
-       *         when {
-       *             the EC of the IUT expires
-       *         }
-       *         then {
-       *             the IUT returns to the "initialized" state
-       *         }
-       *     }
+       * 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 v2.0.1 SECPKI_ITSS_ENR_05_BV + * @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 { @@ -1047,14 +1217,155 @@ module ItsPki_TestCases { } // 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 - setverdict(inconc); + 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 + // vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + vc_hashedId8ToBeUsed := ""; + f_cfUp_itss(); + + // Test adapter configuration + + // Preamble + // Initial state: No CAM shall be emitted + geoNetworkingPort.clear; + tc_noac.start; + alt { + [] geoNetworkingPort.receive { + log("No CA message expected"); + f_selfOrClientSyncAndVerdict(c_prDone, e_error); + } + [] tc_noac.timeout { + // Trigger the first enrolment + 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 + + + group f_TC_SECPKI_ITSS_ENR_06_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. @@ -1072,17 +1383,26 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_06_BV + * @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() runs on ItsMtc system ItsPkiItssSystem { + const charstring c_nextTry := "nextTry"; + + testcase TC_SECPKI_ITSS_ENR_06_BV_1() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_06_BV_mtc(c_stInitial); + } + testcase TC_SECPKI_ITSS_ENR_06_BV_2() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_06_BV_mtc(c_stEnrolled); + } + + 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 or PICS_SECPKI_REENROLMENT) { - log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and not PICS_SECPKI_REENROLMENT required for executing the TC ***"); + 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; } @@ -1091,24 +1411,31 @@ module ItsPki_TestCases { f_cfMtcUp01(v_itss, v_ea); // Start components - v_itss.start(f_TC_SECPKI_ITSS_ENR_06_BV_itss()); - v_ea.start(f_TC_SECPKI_ITSS_ENR_06_BV_pki()); + 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_serverSync2ClientsAndStop({c_prDone, c_tbDone}); + 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 - - } // End of TC_SECPKI_ITSS_ENR_06_BV - - group f_TC_SECPKI_ITSS_ENR_06_BV { - - function f_TC_SECPKI_ITSS_ENR_06_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + 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 HashedId8 v_certificate_digest := int2oct(0, 8); var EtsiTs103097Certificate v_certificate; // Test component configuration + vc_hashedId8ToBeUsed := ""; f_cfUp_itss(); // Test adapter configuration @@ -1129,37 +1456,23 @@ module ItsPki_TestCases { } // End of 'alt' statement // Test Body - // Re-enrolment - for (var integer v_i := 0; v_i < PX_RE_ENROLMENT_COUNTER; v_i := v_i + 1) { - f_sendUtTriggerEnrolmentRequestPrimitive(); + // 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); - } // End of 'for' statement - tc_noac.start; - alt { - [] geoNetworkingPort.receive { - log("No CA message expected"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + f_sendUtTriggerEnrolmentRequestPrimitive(); + f_clientSync(c_nextTry, e_success); } - [] tc_noac.timeout { - log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - } - } // End of 'alt' statement // Postamble f_cfDown_itss(); } // End of function f_TC_SECPKI_ITSS_ENR_06_BV_itss - function f_TC_SECPKI_ITSS_ENR_06_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem { + function f_TC_SECPKI_ITSS_ENR_06_BV_pki(integer p_max_try, charstring p_state) runs on ItsPkiHttp system ItsPkiItssSystem { // Local variable - var integer v_counter := 0; var Headers v_headers; - var HttpMessage v_request; - var HttpMessage v_response; - var InnerEcRequest v_inner_ec_request; - var InnerEcResponse v_inner_ec_response; var ListOfPublicVerificationKey v_generated_keys; - var integer v_result; // Test component configuration f_cfHttpUp(); @@ -1168,98 +1481,42 @@ module ItsPki_TestCases { // Preamble f_init_default_headers_list(-, "inner_ec_response", v_headers); - // Wait for the first enrolment response - tc_ac.start; - alt { - [] a_await_at_http_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 - ) { - tc_ac.stop; + f_selfOrClientSyncAndVerdict(c_prDone, e_success); - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } - // Set verdict - if (v_result == 0) { - v_generated_keys[v_counter] := v_inner_ec_request.publicKeys.verificationKey; - v_counter := v_counter + 1; - f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); + // 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 { - log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_error); + 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); } - [] tc_ac.timeout { - log("*** " & testcasename() & ": INCONC: Expected message not received ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_timeout); - } - } // End of 'alt' statement - // Test Body - tc_ac.start; - alt { - [] a_await_at_http_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 - ) { - tc_ac.stop; + v_key := v_inner_ec_request.publicKeys.verificationKey; - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } - // Set verdict - if (v_result == 0) { - log("*** " & testcasename() & ": LOG: ", match(v_generated_keys, superset(v_inner_ec_request.publicKeys.verificationKey)), "***"); - if (match(v_generated_keys, superset(v_inner_ec_request.publicKeys.verificationKey)) == true) { - v_generated_keys[v_counter] := v_inner_ec_request.publicKeys.verificationKey; - v_counter := v_counter + 1; - f_selfOrClientSyncAndVerdictTestBody(c_prDone, e_success); - } else { + 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 ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_error); + setverdict(fail); + f_clientSync(c_nextTry, e_error); } - } else { - log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_error); - } - } - [] tc_ac.timeout { - if (v_counter == PX_RE_ENROLMENT_COUNTER) { - log("*** " & testcasename() & ": PASS: InnerEcRequest received with different key pairs ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - } else { - log("*** " & testcasename() & ": INCONC: Expected message not received ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + v_generated_keys[v_i] := v_key; + + f_clientSync(c_nextTry, e_success); } - } - } // End of 'alt' statement + log("*** " & testcasename() & ": PASS: No identical verification keys received in " & int2str(p_max_try) & " messages ***"); + f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success); // Postamble f_cfHttpDown(); @@ -1267,6 +1524,7 @@ module ItsPki_TestCases { } // End of f_TC_SECPKI_ITSS_ENR_06_BV + group SECPKI_ITSS_ENR_07_BV { /** * @desc Within the InnerECRequest, the requestedSubjectAttributes shall not contain a certIssuePermissions field. *
@@ -1288,7 +1546,7 @@ module ItsPki_TestCases {
        *     }
        * 
* - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_07_BV + * @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 { @@ -1313,7 +1571,7 @@ module ItsPki_TestCases { // Start components v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); - v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + v_ea.start(f_TC_SECPKI_ITSS_ENR_07_BV_pki()); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); @@ -1322,6 +1580,72 @@ module ItsPki_TestCases { } // End of TC_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; + + f_send_500_Internal_Error(v_headers); // we don't care about 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_pki_request, + v_inner_ec_request)) + { + log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + 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 SECPKI_ITSS_ENR_07_BV + + group SECPKI_ITSS_ENR_08_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. @@ -1349,10 +1673,17 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_08_BV + * @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() runs on ItsMtc system ItsPkiItssSystem { + testcase TC_SECPKI_ITSS_ENR_08_BV_1() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_08_BV_mtc(c_stInitial); + } + testcase TC_SECPKI_ITSS_ENR_08_BV_2() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_08_BV_mtc(c_stEnrolled); + } + + 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; @@ -1368,8 +1699,12 @@ module ItsPki_TestCases { f_cfMtcUp01(v_itss, v_ea); // Start components + if(p_itss_state == c_stEnrolled){ v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); - v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki()); + }else{ + v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss()); + } + v_ea.start(f_TC_SECPKI_ITSS_ENR_08_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); @@ -1378,6 +1713,95 @@ module ItsPki_TestCases { } // 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_send_500_Internal_Error(v_headers); // we dont care about response + + 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); + } + 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_01_BV_pki + } + /** * @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. @@ -1405,10 +1829,17 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_09_BV + * @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() runs on ItsMtc system ItsPkiItssSystem { + group g_TC_SECPKI_ITSS_ENR_09_BV { + testcase TC_SECPKI_ITSS_ENR_09_BV_1() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_09_BV_mtc(c_stInitial); + } + testcase TC_SECPKI_ITSS_ENR_09_BV_2() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_09_BV_mtc(c_stEnrolled); + } + 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; @@ -1424,15 +1855,101 @@ module ItsPki_TestCases { 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_01_BV_pki()); + } + v_ea.start(f_TC_SECPKI_ITSS_ENR_09_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup - } // End of TC_SECPKI_ITSS_ENR_09_BV + } // 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; + + f_send_500_Internal_Error(v_headers); // we don't care about 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_pki_request, + v_inner_ec_request)) + { + log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + + 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 g_TC_SECPKI_ITSS_ENR_09_BV /** * @desc The EtsiTs103097Data-Encrypted containing the correctly encrypted ciphertext and a recipients @@ -1463,10 +1980,17 @@ module ItsPki_TestCases { * } * * - * @see ETSI TS 103 525-2 v2.0.1 SECPKI_ITSS_ENR_10_BV + * @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() runs on ItsMtc system ItsPkiItssSystem { + group g_TC_SECPKI_ITSS_ENR_10_BV { + testcase TC_SECPKI_ITSS_ENR_10_BV_1() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_10_BV_mtc(c_stInitial); + } + testcase TC_SECPKI_ITSS_ENR_10_BV_2() runs on ItsMtc system ItsPkiItssSystem { + f_TC_SECPKI_ITSS_ENR_10_BV_mtc(c_stEnrolled); + } + 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; @@ -1482,15 +2006,109 @@ module ItsPki_TestCases { f_cfMtcUp01(v_itss, v_ea); // Start components + // 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_01_BV_pki()); + } + v_ea.start(f_TC_SECPKI_ITSS_ENR_10_BV_pki(p_itss_state)); // Synchronization f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); // Cleanup - } // End of TC_SECPKI_ITSS_ENR_10_BV + } // 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; + + f_send_500_Internal_Error(v_headers); // we don't care about response + + 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)) + { + log("*** " & testcasename() & ": FAIL: Can't parse enrolment request***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + // 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 g_TC_SECPKI_ITSS_ENR_10_BV + /** * @desc In the inner signed data structure (InnerECRequestSignedForPOP), the signature is computed @@ -1666,7 +2284,9 @@ module ItsPki_TestCases { var boolean v_iut_state_ok := false; // Test component configuration - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + // vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + vc_hashedId8ToBeUsed := ""; // No certificates //PX_IUT_DEFAULT_CERTIFICATE + f_cfUp_itss(); // Test adapter configuration @@ -1846,7 +2466,7 @@ module ItsPki_TestCases { var boolean v_iut_state_ok := false; // Test component configuration - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + vc_hashedId8ToBeUsed := ""; // No certificates //PX_IUT_DEFAULT_CERTIFICATE f_cfUp_itss(); // Test adapter configuration @@ -1994,95 +2614,40 @@ module ItsPki_TestCases { * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_01_BV * @reference ETSI TS 103 601, clause 5.1.2 */ - 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); + group g_TC_SECPKI_ITSS_ENR_REP_01_BV { - } // End of testcase TC_SECPKI_ITSS_ENR_REP_01_BV - - group f_TC_SECPKI_ITSS_ENR_REP_01_BV { - - function f_TC_SECPKI_ITSS_ENR_REP_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + testcase TC_SECPKI_ITSS_ENR_REP_01_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables - var HashedId8 v_certificate_digest; - var EtsiTs103097Certificate v_certificate; + 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 - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; - f_cfUp_itss(); + f_cfMtcUp01(v_itss, v_ea); - // Test adapter configuration + // Start component + v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss()); // reuse from ENR group + v_ea.start(f_TC_SECPKI_ITSS_ENR_REP_01_BV_pki()); - // 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() & ": INFO: No CA message received ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_success); - } - } // End of 'alt' statement + // Synchronization + f_serverSync2ClientsAndStop({c_prDone, c_tbDone}); - // Test Body - f_sendUtTriggerEnrolmentRequestPrimitive(); - tc_ac.start; - alt { - [] utPort.receive(UtPkiTriggerInd: { state := 1 }) { - tc_ac.stop; - log("*** " & testcasename() & ": INFO: IUT is in enrolment state ***"); - } - [] tc_ac.timeout { - log("*** " & testcasename() & ": DBG: IUT state update not recieved ***"); - } - } // End of 'alt' statement - tc_noac.start; - alt { - [] geoNetworkingPort.receive { - log("No CA message expected"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_error); - } - [] tc_noac.timeout { - log("*** " & testcasename() & ": PASS: Enrolment trigger sent successfully ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - } - } // End of 'alt' statement + // Cleanup + f_cfMtcDown01(v_itss, v_ea); - // Postamble - f_cfDown_itss(); - } // End of function f_TC_SECPKI_ITSS_ENR_REP_01_BV_itss + } // End of testcase TC_SECPKI_ITSS_ENR_REP_01_BV 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; - var InnerEcResponse v_inner_ec_response; // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); @@ -2091,66 +2656,35 @@ module ItsPki_TestCases { // Preamble f_init_default_headers_list(-, "inner_ec_response", v_headers); - f_await_ec_request_send_no_response(v_initial_request); - log("*** " & testcasename() & ": INFO: Reply with no response error message ***"); - f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success); - - // Test Body - var integer i; - var boolean v_loop := true; - for (i := 0; i < PX_ENR_MAX_N1; i := i + 1) { - 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; - - tc_ac.stop; - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } 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: Response received on the IUT ***"); - v_loop := false; - f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - //break; - } - } // End of 'alt' statement - if (v_loop == false){ - break; + 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"); } - } // End of 'loop' statement - + [] tc_ac.timeout { + log("*** " & testcasename() & ": INCONC: First enrolment request not received 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 @@ -2179,84 +2713,39 @@ module ItsPki_TestCases { * @see ETSI TS 103 525-2 TP SECPKI_ITSS_ENR_REP_02_BV * @reference ETSI TS 103 601, clause 5.1.2 */ - 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_02_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 - group f_TC_SECPKI_ITSS_ENR_REP_02_BV { - - function f_TC_SECPKI_ITSS_ENR_REP_02_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem { + testcase TC_SECPKI_ITSS_ENR_REP_02_BV() runs on ItsMtc system ItsPkiItssSystem { // Local variables - var HashedId8 v_certificate_digest; - var EtsiTs103097Certificate v_certificate; - - // Test component configuration - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; - f_cfUp_itss(); - - // Test adapter configuration - - // Preamble - // Initial state: No CAM shall be emitted - geoNetworkingPort.clear; - tc_noac.start; - alt { - [] geoNetworkingPort.receive { - log("No CA message expected"); - f_selfOrClientSyncAndVerdict(c_prDone, e_error); - } - [] tc_noac.timeout { - log("*** " & testcasename() & ": INFO: No CA message received ***"); - f_selfOrClientSyncAndVerdict(c_prDone, e_success); - } - } // End of 'alt' statement - - // Test Body - f_sendUtTriggerEnrolmentRequestPrimitive(); - tc_noac.start; - alt { - [] geoNetworkingPort.receive { - log("No CA message expected"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_error); - } - [] tc_noac.timeout { - log("*** " & testcasename() & ": PASS: Enrolment trigger sent successfully ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_success); - } - } // End of 'alt' statement - - // Postamble - f_cfDown_itss(); - } // End of function f_TC_SECPKI_ITSS_ENR_REP_02_BV_itss - + 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_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_request; - var HttpMessage v_initial_request; + var HttpMessage v_request1; + var HttpMessage v_request2; // Test component configuration f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID); @@ -2265,60 +2754,45 @@ module ItsPki_TestCases { // Preamble f_init_default_headers_list(-, "inner_ec_response", v_headers); - 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); + 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 + // 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 - ) { + mw_http_request( + mw_http_request_post( + PICS_HTTP_POST_URI_EC, + -, + v_request1.request.body)), + + v_request2) + { tc_ac.stop; - - if (f_verify_repeated_request(v_request, v_initial_request) == false) { - log("*** " & testcasename() & ": FAIL: Repetition request are different ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_error); - } else { - // Repetition request are same - var HttpMessage v_response; - var integer v_result; - var InnerEcRequest v_inner_ec_request; - var InnerEcResponse v_inner_ec_response; - - // Verify IUT response - f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result); - // Send response - if (isvalue(v_response)) { - httpPort.send(v_response); - } 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); - } - } + 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: Expected message not received ***"); - f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + log("*** " & testcasename() & ": INCONC: First enrolment request not received ***"); + f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout); } } // End of 'alt' statement @@ -2599,6 +3073,7 @@ module ItsPki_TestCases { var HttpMessage v_request; var HttpMessage v_initial_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); @@ -2616,7 +3091,7 @@ module ItsPki_TestCases { } // End of 'for' staement // Do not expect any repetition - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -2790,8 +3265,9 @@ module ItsPki_TestCases { [] tc_ac.timeout { // Do not expect any repetition var InnerEcResponse v_inner_ec_response; + var InnerEcRequest v_inner_ec_request; - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 timeout ***"); f_selfOrClientSyncAndVerdict(c_tbDone, e_error); } else { @@ -2871,7 +3347,8 @@ module ItsPki_TestCases { var boolean v_start_awaiting := false; // Test component configuration - vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; +// vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE; + vc_hashedId8ToBeUsed := ""; f_cfUp_itss(); // Test adapter configuration @@ -2886,6 +3363,8 @@ module ItsPki_TestCases { f_selfOrClientSyncAndVerdict(c_prDone, e_error); } [] tc_noac.timeout { + log("*** " & testcasename() & "_itss: : INFO: No CA message received ***"); + if(PX_TRIGGER_EC_BEFORE_AT){ f_sendUtTriggerEnrolmentRequestPrimitive(); tc_ac.start; // TDOD To refined, use altstep alt { @@ -2893,12 +3372,17 @@ module ItsPki_TestCases { tc_ac.stop; log("*** " & testcasename() & "_itss: INFO: IUT is in enrol state ***"); } - [] tc_ac.timeout { + [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 - log("*** " & testcasename() & "_itss: : INFO: No CA message received ***"); + }else{ + log("*** " & testcasename() & "_itss: DBG: Assume IUT already in enrolled state.***"); + } f_selfOrClientSyncAndVerdict(c_prDone, e_success); } } // End of 'alt' statement @@ -2936,7 +3420,9 @@ module ItsPki_TestCases { // 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); @@ -2946,7 +3432,8 @@ module ItsPki_TestCases { // 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_response, v_request) == true) { + 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 { @@ -2954,6 +3441,8 @@ module ItsPki_TestCases { f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout); } } else { +// f_readCertificate(PICS_IUT_EC_CERTIFICATE_ID, v_inner_ec_response.certificate); +// v_ec_cert := omit; f_selfOrClientSyncAndVerdict(c_prDone, e_success); } @@ -2982,7 +3471,7 @@ module ItsPki_TestCases { 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); + 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 @@ -3532,6 +4021,7 @@ module ItsPki_TestCases { // 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 @@ -3548,7 +4038,7 @@ module ItsPki_TestCases { f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -3557,6 +4047,7 @@ module ItsPki_TestCases { } } else { f_selfOrClientSyncAndVerdict(c_prDone, e_success); + v_inner_ec_response.certificate := omit; } // Test Body @@ -3734,6 +4225,7 @@ module ItsPki_TestCases { 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 @@ -3750,7 +4242,7 @@ module ItsPki_TestCases { f_selfOrClientSyncAndVerdict(c_prDone, e_success); // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -3944,6 +4436,7 @@ module ItsPki_TestCases { 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 @@ -3961,7 +4454,7 @@ module ItsPki_TestCases { // Wait for the repetition if (PX_TRIGGER_EC_BEFORE_AT) { - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -4141,6 +4634,7 @@ module ItsPki_TestCases { 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 @@ -4159,7 +4653,7 @@ module ItsPki_TestCases { // Do not expect any repetition if (PX_TRIGGER_EC_BEFORE_AT) { - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -4176,6 +4670,205 @@ module ItsPki_TestCases { } // 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) { + 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 + 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_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 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_ac.start(PX_TAC * 1.1); // for different timer PIXIT_AUTH_TIMEOUT_TH2 + 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_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: InnerAtRequest 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 AA an AuthorizationRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_error); + } + } + [] tc_ac.timeout { + log("*** " & testcasename() & ": PASS: Expected no AuthorizationRequestMessage ***"); + f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout); + } + } // End of 'alt' statement + + // Postamble + f_cfHttpDown(); + } // End of function f_TC_SECPKI_ITSS_AUTH_REP_05_BV_pki + } } // 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 @@ -4316,6 +5009,7 @@ module ItsPki_TestCases { 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); @@ -4323,7 +5017,7 @@ module ItsPki_TestCases { // Test adapter configuration // Preamble - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -4666,6 +5360,7 @@ module ItsPki_TestCases { 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); @@ -4673,7 +5368,7 @@ module ItsPki_TestCases { // Test adapter configuration // Preamble - if (f_await_ec_request_send_response(v_inner_ec_response, v_request) == true) { + 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 { @@ -11121,12 +11816,20 @@ module ItsPki_TestCases { var HashedId8 v_bfk_hashed_id8; var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; var EtsiTs102941Data v_etsi_ts_102941_data; + var EtsiTs103097Certificate v_aaCertificate; + var charstring v_aaCertificate_id; log(">>> f_verify_http_at_request_from_iut_atv: p_request= ", p_request); p_result := 0; - if (f_verify_pki_request_message(vc_eaPrivateEncKey/*Encrypted with AA*/, vc_eaWholeHash/*salt*/, vc_aaWholeHash/*Issuer is AA*/, p_request.body.binary_body.ieee1609dot2_data, true, p_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, p_aes_enc_key) == false) { + if (not(f_getCertificateFromDigest(f_hashedId8FromSha256(vc_aaWholeHash), v_aaCertificate, v_aaCertificate_id))) { + p_result := -1; + return; + } + if (not f_verify_pki_request_message(vc_eaPrivateEncKey/*Encrypted with AA*/, vc_eaWholeHash/*salt*/, vc_aaWholeHash/*Issuer is AA*/, + v_aaCertificate.toBeSigned.verifyKeyIndicator.verificationKey, + p_request.body.binary_body.ieee1609dot2_data, true, p_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, p_aes_enc_key)) { // Set verdict p_result := -1; } else { @@ -13176,7 +13879,9 @@ module ItsPki_TestCases { p_result := 0; - if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message + if (f_verify_pki_request_message( vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, + omit, + p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, 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 @@ -17584,7 +18289,9 @@ module ItsPki_TestCases { p_result := 0; - if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message + if (f_verify_pki_request_message( vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, + omit, + p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, 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 diff --git a/ItsPki_TestControl.ttcn b/ItsPki_TestControl.ttcn index 577ddf94cd64627dfaff728a4e1c2072348d20c1..f3a81014717bb5918b4a5ee0fd86668911d6a6b9 100644 --- a/ItsPki_TestControl.ttcn +++ b/ItsPki_TestControl.ttcn @@ -14,7 +14,8 @@ module ItsPki_TestControl { execute(TC_SECPKI_ITSS_ENR_02_BV()); if (PICS_SECPKI_REENROLMENT) { execute(TC_SECPKI_ITSS_ENR_03_BV()); - execute(TC_SECPKI_ITSS_ENR_06_BV()); + execute(TC_SECPKI_ITSS_ENR_06_BV_1()); + execute(TC_SECPKI_ITSS_ENR_06_BV_2()); execute(TC_SECPKI_ITSS_ENR_12_BV()); } if (PICS_SECPKI_CRL) { @@ -29,9 +30,12 @@ module ItsPki_TestControl { } execute(TC_SECPKI_ITSS_ENR_05_BV()); execute(TC_SECPKI_ITSS_ENR_07_BV()); - execute(TC_SECPKI_ITSS_ENR_08_BV()); - execute(TC_SECPKI_ITSS_ENR_09_BV()); - execute(TC_SECPKI_ITSS_ENR_10_BV()); + execute(TC_SECPKI_ITSS_ENR_08_BV_1()); + execute(TC_SECPKI_ITSS_ENR_08_BV_2()); + execute(TC_SECPKI_ITSS_ENR_09_BV_1()); + execute(TC_SECPKI_ITSS_ENR_09_BV_2()); + execute(TC_SECPKI_ITSS_ENR_10_BV_1()); + execute(TC_SECPKI_ITSS_ENR_10_BV_2()); execute(TC_SECPKI_ITSS_ENR_11_BV()); execute(TC_SECPKI_ITSS_ENR_RECV_01_BV()); diff --git a/lib/LibItsPki_EncdecDeclarations.ttcn b/lib/LibItsPki_EncdecDeclarations.ttcn index 70922b0a86d35fe99961d8748167ba1e341df18d..e58c926592b1a5f38ec30fc8276bc793c5b08b63 100644 --- a/lib/LibItsPki_EncdecDeclarations.ttcn +++ b/lib/LibItsPki_EncdecDeclarations.ttcn @@ -11,7 +11,7 @@ module LibItsPki_EncdecDeclarations { import from EtsiTs103097Module language "ASN.1:1997" all; import from EtsiTs102941TrustLists language "ASN.1:1997" all; - // LibItsSecurity + // LibItsPki import from LibItsSecurity_TypesAndValues all; external function fx_enc_EtsiTs102941Data(in EtsiTs102941MessagesCa.EtsiTs102941Data p_etsi_ts_102941_data) return bitstring diff --git a/lib/LibItsPki_Pics.ttcn b/lib/LibItsPki_Pics.ttcn index cab931a58a53470ac84eef14ceb6b96b9abf0c72..6f1fd42d6124d5de08f6677c17fed1a5710ae04e 100644 --- a/lib/LibItsPki_Pics.ttcn +++ b/lib/LibItsPki_Pics.ttcn @@ -60,11 +60,21 @@ module LibItsPki_Pics { */ modulepar boolean PICS_PKI_AUTH_POP := true; + /** + * @desc Do the Authorization Request use SignedWithPop mechanism? + */ + modulepar boolean PICS_UT_STATE_INDICATION := true; + /** * @desc Certificate used by the IUT acting as ITS-S */ modulepar charstring PICS_IUT_CERTIFICATE_ID := "CERT_IUT_A_AT"; + /** + * @desc Default enrollment credentials used by ITS-S + */ + modulepar charstring PICS_IUT_EC_CERTIFICATE_ID := "CERT_IUT_A_EC"; + /** * @desc Certificate used by the IUT acting as EA */ diff --git a/lib/LibItsPki_Templates.ttcn b/lib/LibItsPki_Templates.ttcn index bb58abd9122598e26dd686b013e5dc64c5a49993..65b7db986ae692e0954c300a5c193e874a358440 100644 --- a/lib/LibItsPki_Templates.ttcn +++ b/lib/LibItsPki_Templates.ttcn @@ -527,7 +527,7 @@ module LibItsPki_Templates { } // End of template mw_publicKeys template (omit) CertificateSubjectAttributes m_certificateSubjectAttributes_id_none( - in template (value) SequenceOfPsidSsp p_appPermissions, + in template (omit) SequenceOfPsidSsp p_appPermissions := omit, in template (omit) ValidityPeriod p_validityPeriod := omit, in template (omit) GeographicRegion p_region := omit, in template (omit) SubjectAssurance p_assuranceLevel := omit @@ -541,7 +541,7 @@ module LibItsPki_Templates { } // End of template m_certificateSubjectAttributes_id_none template (omit) CertificateSubjectAttributes m_certificateSubjectAttributes_id_omit( - in template (value) SequenceOfPsidSsp p_appPermissions, + in template (omit) SequenceOfPsidSsp p_appPermissions := omit, in template (omit) ValidityPeriod p_validityPeriod := omit, in template (omit) GeographicRegion p_region := omit, in template (omit) SubjectAssurance p_assuranceLevel := omit @@ -752,7 +752,7 @@ module LibItsPki_Templates { template CertificateSubjectAttributes mw_certificate_subject_attributes( template (present) SequenceOfPsidSsp p_appPermissions := ?, template CertificateId p_id := *, - template (present) ValidityPeriod p_validityPeriod := ?, + template ValidityPeriod p_validityPeriod := *, template SubjectAssurance p_assuranceLevel := *, template GeographicRegion p_region := *, template SequenceOfPsidGroupPermissions p_certIssuePermissions := omit @@ -768,7 +768,7 @@ module LibItsPki_Templates { template CertificateSubjectAttributes mw_certificate_subject_attributes_optional_assuranceLevel( template (present) SequenceOfPsidSsp p_appPermissions := ?, template (present) CertificateId p_id := ?, - template (present) ValidityPeriod p_validityPeriod := ?, + template ValidityPeriod p_validityPeriod := *, template SubjectAssurance p_assuranceLevel := *, template GeographicRegion p_region := *, template SequenceOfPsidGroupPermissions p_certIssuePermissions := omit @@ -1323,4 +1323,61 @@ module LibItsPki_Templates { cert := p_cert } // End of template mw_dc_entry + group security_templates { + template (omit) HeaderInfo m_headerInfo_inner_pki_request( + in template (value) Psid p_psid := c_its_aid_SCR, + in template (value) Time64 p_generationTime + ) modifies m_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime + }; + + template (omit) HeaderInfo m_headerInfo_inner_pki_response( + in template (value) Psid p_psid := c_its_aid_SCR, + in template (value) Time64 p_generationTime + ) modifies m_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime + }; + + template (omit) HeaderInfo m_headerInfo_inner_pki_ctl_response( + in template (value) Psid p_psid := c_its_aid_CPOC, + in template (value) Time64 p_generationTime + ) modifies m_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime + }; + + template (omit) HeaderInfo m_headerInfo_inner_pki_crl_response( + in template (value) Psid p_psid := c_its_aid_CRL, + in template (value) Time64 p_generationTime + ) modifies m_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime + }; + + template (present) HeaderInfo mw_headerInfo_inner_pki_request( + template (present) Psid p_psid := c_its_aid_SCR, + template (present) Time64 p_generationTime := ? + ) modifies mw_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime, + expiryTime := omit, + generationLocation := omit + }; + + template (present) HeaderInfo mw_headerInfo_outer_pki_request( + template (present) Psid p_psid := c_its_aid_SCR, + template (present) Time64 p_generationTime := ? + ) modifies mw_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime, + expiryTime := omit, + generationLocation := omit + }; + + template HeaderInfo mw_headerInfo_inner_pki_response( + template (present) Psid p_psid := c_its_aid_SCR, + template Time64 p_generationTime := * + ) modifies mw_ieee1609Dot2_headerInfo := { + generationTime := p_generationTime, + expiryTime := omit, + generationLocation := omit + } + } + } // End of module LibItsPki_Templates diff --git a/lib_system/LibItsPki_Functions.ttcn b/lib_system/LibItsPki_Functions.ttcn index 371b60084e7ef06a80bea15ff133c7047aa0f3ed..f84821686380ab54033ac9347589841c76e02927 100644 --- a/lib_system/LibItsPki_Functions.ttcn +++ b/lib_system/LibItsPki_Functions.ttcn @@ -573,6 +573,7 @@ module LibItsPki_Functions { v_compressed_public_key := '03'O & p_public_key_compressed; } + utPort.clear; v_ut_trigger_enrolment_request := { p_canonical_id, p_enc_algorithm, p_private_key, v_compressed_public_key }; utPort.send(UtPkiTrigger: { triggerEnrolmentRequest := v_ut_trigger_enrolment_request }); tc_ac.start; @@ -585,6 +586,10 @@ module LibItsPki_Functions { log("*** f_sendUtTriggerEnrolmentRequestPrimitive: ERROR: Received unexpected message ***"); f_selfOrClientSyncAndVerdict("error", e_error); } + [] utPort.receive { + log("*** f_sendUtTriggerEnrolmentRequestPrimitive: INFO: Some message received in UT Port ***"); + repeat; + } [] tc_ac.timeout { log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); @@ -620,6 +625,9 @@ module LibItsPki_Functions { log("*** f_sendUtTriggerAuthorizationRequestPrimitive: ERROR: Received unexpected message ***"); f_selfOrClientSyncAndVerdict("error", e_error); } + [] utPort.receive(UtPkiTriggerInd:?) { + repeat; + } [] tc_ac.timeout { log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); @@ -694,6 +702,76 @@ module LibItsPki_Functions { group helpers { + function f_decode_EccP256CurvePoint( + in octetstring buf, + out EccP256CurvePoint p + ) runs on ItsPkiHttp return boolean { + var integer ptype := oct2int(buf[0] and4b '7F'O); + if(lengthof(buf) == 33){ + if (ptype == 0) {p.x_only := substr(buf, 1, 32);} + else if (ptype == 2) {p.compressed_y_0 := substr(buf, 1, 32);} + else if (ptype == 3) {p.compressed_y_1 := substr(buf, 1, 32);} + else { + log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); + return false; + } + }else if(lengthof(buf) == 65){ + if (ptype == 4) { + p.uncompressedP256.x := substr(buf, 1, 32); + p.uncompressedP256.y := substr(buf, 33, 32); + }else{ + log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); + return false; + } + }else{ + log("f_decode_EccP256CurvePoint: wrong buffer length ", lengthof(buf)); + return false; + } + return true; + } + + function f_decode_EccP384CurvePoint( + in octetstring buf, + out EccP384CurvePoint p + ) runs on ItsPkiHttp return boolean { + var integer ptype := oct2int(buf[0] and4b '7F'O); + if(lengthof(buf) == 49){ + if (ptype == 0) {p.x_only := substr(buf, 1, 48);} + else if (ptype == 2) {p.compressed_y_0 := substr(buf, 1, 48);} + else if (ptype == 3) {p.compressed_y_1 := substr(buf, 1, 48);} + else { + log("f_decode_EccP384CurvePoint: unsupported value for point type ", ptype); + return false; + } + }else if(lengthof(buf) == 97){ + if (ptype == 4) { + p.uncompressedP384.x := substr(buf, 1, 48); + p.uncompressedP384.y := substr(buf, 49, 48); + }else{ + log("f_decode_EccP256CurvePoint: unsupported value for point type ", ptype); + return false; + } + }else{ + log("f_decode_EccP256CurvePoint: wrong buffer length ",lengthof(buf)); + return false; + } + return true; + } + + function f_get_canonical_itss_key( + out PublicVerificationKey p_key + ) runs on ItsPkiHttp return boolean { + log("f_get_canonical_itss_key: PX_VE_ALG=", PX_VE_ALG); + if (PX_VE_ALG == e_nist_p256) { + return f_decode_EccP256CurvePoint(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, p_key.ecdsaNistP256); + } else if (PX_VE_ALG == e_brainpool_p256_r1) { + return f_decode_EccP256CurvePoint(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, p_key.ecdsaNistP256); + } else if (PX_VE_ALG == e_brainpool_p384_r1) { + return f_decode_EccP384CurvePoint(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, p_key.ecdsaNistP256); + } + return false; + } + function f_generate_key_pair( out octetstring p_private_key, out octetstring p_public_key_x, @@ -743,6 +821,27 @@ module LibItsPki_Functions { return true; } + function f_http_restart ( + in charstring p_content_text + ) runs on ItsPkiHttp { + if (not(PICS_MULTIPLE_END_POINT)) { + log("f_http_restart: restart httpPort"); + httpPort.stop; + httpPort.start; + } else { + log("f_http_restart: restart httpPort with contentType ", p_content_text); + select(p_content_text){ + case ("inner_ec_request"){ + httpEcPort.stop; + httpEcPort.start; + } + case ("inner_atv_request"){ + httpAtVPort.stop; + httpAtVPort.start; + } + } + } + } function f_http_send( in Headers p_headers, @@ -1242,6 +1341,49 @@ module LibItsPki_Functions { return p_result; } // End of function f_http_build_inner_ec_response + function f_http_build_error_ec_response( + in EnrolmentResponseCode p_responseCode := ok, + in Oct16 p_request_hash, + in octetstring p_private_key := ''O, + in octetstring p_digest := ''O, + in Oct16 p_aes_sym_key, + out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data + ) return boolean { + // Local variables + var octetstring v_msg; + var Oct12 v_nonce; + var Ieee1609Dot2Data v_ieee1609dot2_signed_data; + var boolean p_result := false; + var InnerEcResponse v_inner_ec_response; + + // Check expectred response + if (p_responseCode == ok) { + return false; + } + v_inner_ec_response := valueof( + m_innerEcResponse_ko( + p_request_hash, + p_responseCode + ) + ); + // Secure the response + log("f_http_build_error_ec_response: p_inner_ec_response= ", v_inner_ec_response); + v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_ec_response(v_inner_ec_response))); + v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value + // TODO Consider Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest)) + if (f_build_pki_secured_response_message(p_private_key, + valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),// in SignerIdentifier p_signer_identifier, + v_msg, + p_aes_sym_key, + v_nonce, + p_ieee1609dot2_signed_and_encrypted_data + ) == false) { + log("f_http_build_inner_ec_response: Failed to generate the certificate"); + return false; + } + return true; + } // End of function f_http_build_error_ec_response + function f_http_build_authorization_request( in Certificate p_ec_certificate, // Enrolment credentials certificate in octetstring p_ec_private_key, @@ -1636,7 +1778,11 @@ module LibItsPki_Functions { p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3. log("f_http_build_invalid_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8); log("f_http_build_invalid_authorization_validation_request: p_salt: ", p_salt); - if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, true, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { + if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), + vc_eaHashedId8/*recipientId*/, v_public_enc_key, + v_compressed_enc_key_mode, p_salt, + bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), + PX_EC_ALG_FOR_ATV, true, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) { log("f_http_build_invalid_authorization_validation_request: Failed to generate Authorization Request"); return false; } @@ -2129,6 +2275,7 @@ module LibItsPki_Functions { var IssuerIdentifier v_issuer; var bitstring v_tbs; var octetstring v_sig; + var ValidityPeriod v_valPeriod; log(">>> f_generate_ec_certificate_for_inner_ec_response: p_inner_ec_request: ", p_inner_ec_request); log(">>> f_generate_ec_certificate_for_inner_ec_response: p_digest: ", p_digest); @@ -2139,16 +2286,19 @@ module LibItsPki_Functions { } else { v_certificate_id := p_inner_ec_request.requestedSubjectAttributes.id; } + if (ispresent(p_inner_ec_request.requestedSubjectAttributes.validityPeriod)) { + v_valPeriod := p_inner_ec_request.requestedSubjectAttributes.validityPeriod; + } else { + v_valPeriod := valueof(m_validityPeriod(f_getCurrentTime() / 1000, m_duration_in_hours(24))); + } v_cert := valueof( m_etsiTs103097Certificate( v_issuer, m_toBeSignedCertificate_ec( v_certificate_id, p_inner_ec_request.requestedSubjectAttributes.appPermissions, - m_verificationKeyIndicator_verificationKey( - p_inner_ec_request.publicKeys.verificationKey - ), - p_inner_ec_request.requestedSubjectAttributes.validityPeriod, + m_verificationKeyIndicator_verificationKey(p_inner_ec_request.publicKeys.verificationKey), + v_valPeriod, p_inner_ec_request.requestedSubjectAttributes.region, p_inner_ec_request.requestedSubjectAttributes.assuranceLevel, p_inner_ec_request.publicKeys.encryptionKey @@ -3516,7 +3666,7 @@ module LibItsPki_Functions { function f_verify_inner_at_request_signed_for_pop( in EtsiTs102941Data p_etsi_ts_102941_data, - in EtsiTs103097Certificate p_ec_certificate, + in template (omit) EtsiTs103097Certificate p_ec_certificate, out InnerAtRequest p_inner_at_request ) return boolean { var bitstring v_msg_bit; @@ -5196,63 +5346,95 @@ module LibItsPki_Functions { return true; } // End of function f_await_http_inner_ec_request_response + group PredefinedRequests { + template (present) HttpMessage mw_http_ec_request_generic := + 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() + ))))); + } + function f_await_ec_request_send_response( + out InnerEcRequest p_inner_ec_request, out InnerEcResponse p_inner_ec_response, - out HttpMessage p_request + out HttpMessage p_request, + in EnrolmentResponseCode p_response_code := ok, + in template (omit) CertificateSubjectAttributes p_attributes := omit ) runs on ItsPkiHttp return boolean { var boolean v_result := false; + var HttpMessage v_wrong_request; + var Headers v_headers; log(">>> f_await_ec_request_send_response"); + f_init_default_headers_list(-, "inner_ec_response", v_headers); tc_ac.start; alt { - [] a_await_ec_http_request_from_iut( - mw_http_request( - mw_http_request_post( - PICS_HTTP_POST_URI_EC, - -, - mw_http_message_body_binary( - mw_binary_body_ieee1609dot2_data( - mw_enrolmentRequestMessage( - mw_encryptedData( - -, - mw_symmetricCiphertext_aes128ccm - )))))), - p_request - ) { - var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data; + [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, p_request) { + var Ieee1609Dot2Data v_decrypted_message; var EtsiTs102941Data v_etsi_ts_102941_data; - var Oct16 v_request_hash; - var HashedId8 v_bfk_hashed_id8; - var Oct16 v_aes_enc_key; - var InnerEcRequest v_inner_ec_request; var template (value) HttpMessage v_response; - var Headers v_headers; + var Oct16 v_request_hash, v_aes_enc_key; + tc_ac.stop; + + if(f_read_ec_request_from_iut_itss( p_request.request.body.binary_body.ieee1609dot2_data, + v_request_hash, v_aes_enc_key, + v_decrypted_message, + v_etsi_ts_102941_data, + p_inner_ec_request + )){ var EtsiTs103097Certificate v_ec_certificate; var HashedId8 v_ec_certificate_hashed_id8; + var Ieee1609Dot2Data v_response_message; - tc_ac.stop; + log(">>>>>> f_await_ec_request_send_response v_inner_ec_request=", p_inner_ec_request); - f_init_default_headers_list(-, "inner_ec_response", v_headers); + if(ispresent(p_attributes)){ + if(isvalue(p_attributes.id)){ + p_inner_ec_request.requestedSubjectAttributes.id := valueof(p_attributes.id); + } + if(isvalue(p_attributes.validityPeriod)){ + p_inner_ec_request.requestedSubjectAttributes.validityPeriod := valueof(p_attributes.validityPeriod); + } + if(isvalue(p_attributes.region)){ + p_inner_ec_request.requestedSubjectAttributes.region := valueof(p_attributes.region); + } + if(isvalue(p_attributes.assuranceLevel)){ + p_inner_ec_request.requestedSubjectAttributes.assuranceLevel := valueof(p_attributes.assuranceLevel); + } + if(isvalue(p_attributes.appPermissions)){ + p_inner_ec_request.requestedSubjectAttributes.appPermissions := valueof(p_attributes.appPermissions); + } + if(isvalue(p_attributes.certIssuePermissions)){ + p_inner_ec_request.requestedSubjectAttributes.certIssuePermissions := valueof(p_attributes.certIssuePermissions); + } + } - if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, p_request.request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_bfk_hashed_id8, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message - log("f_await_ec_request_send_response: Failed to verify PKI message ***"); - // Send error message - v_response := m_http_response(m_http_response_ko(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers, 400, "Bad request")); // Initialize v_reponse with an error message + f_http_build_inner_ec_response(p_inner_ec_request, p_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, + v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_response_message); + + v_response := m_http_response( + m_http_response_ok( + m_http_message_body_binary( + m_binary_body_ieee1609dot2_data(v_response_message) + ), v_headers)); } else { - log("f_await_ec_request_send_response: Receive ", v_etsi_ts_102941_data, " ***"); - if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, v_inner_ec_request) == false) { - log("f_await_ec_request_send_response: Failed to verify PKI message ***"); - // Send error message - f_http_build_inner_ec_response(v_inner_ec_request/*Not required*/, cantparse, v_request_hash, -, -, v_aes_enc_key, 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)), v_headers)); - } else { - f_http_build_inner_ec_response(v_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, 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)), v_headers)); - v_result := true; + v_response := m_http_response(m_http_response_500_internal_error(v_headers)); } f_http_send(v_headers, v_response); + v_result := true; } + + [] a_await_ec_http_request_from_iut( mw_http_request(), v_wrong_request) { + log(">>>>>> f_await_ec_request_send_response: Wrong message received ", v_wrong_request); + log(" ", match(v_wrong_request, mw_http_request())); + f_http_send(v_headers, m_http_response(m_http_response_500_internal_error(v_headers))); + repeat; } [] tc_ac.timeout { log("f_await_ec_request_send_response: Expected message not received ***"); @@ -5271,26 +5453,9 @@ module LibItsPki_Functions { tc_ac.start; alt { - [] a_await_ec_http_request_from_iut( - mw_http_request( - mw_http_request_post( - PICS_HTTP_POST_URI_EC, - -, - mw_http_message_body_binary( - mw_binary_body_ieee1609dot2_data( - mw_enrolmentRequestMessage( - mw_encryptedData( - -, - mw_symmetricCiphertext_aes128ccm - )))))), - p_request - ) { - var template (value) HttpMessage v_response; - var Headers v_headers; - + [] a_await_ec_http_request_from_iut(mw_http_ec_request_generic, p_request) { tc_ac.stop; - - f_init_default_headers_list(-, "inner_ec_response", v_headers); + f_http_restart("inner_ec_request"); log("f_await_ec_request_send_no_response: Failed to verify PKI message ***"); } [] tc_ac.timeout { @@ -5808,7 +5973,7 @@ module LibItsPki_Functions { var octetstring v_encoded_inner_ec_response; var HashedId8 v_recipientId; var octetstring v_encrypted_inner_ec_response; - + var octetstring v_symkeyidentifier; // Signed the encoded PKI message v_tbs := m_toBeSignedData( m_signedDataPayload( @@ -5844,7 +6009,9 @@ module LibItsPki_Functions { // Encode EtsiTs103097Data-Signed data structure v_encoded_inner_ec_response := bit2oct(encvalue(v_ieee1609dot2_signed_data)); v_encrypted_inner_ec_response := fx_encrypt_aes_128_ccm_test(p_aes_sym_key, p_nonce, v_encoded_inner_ec_response); - v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(p_aes_sym_key)); + v_symkeyidentifier := '80'O & p_aes_sym_key; + log("v_symkeyidentifier= ", v_symkeyidentifier); + v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(v_symkeyidentifier)); log("v_recipientId= ", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) p_ieee1609dot2_signed_and_encrypted_data := valueof( @@ -5869,6 +6036,92 @@ module LibItsPki_Functions { return true; } // End of function f_build_pki_secured_response_message + function f_read_pki_request_message( + in Ieee1609Dot2Data p_encrypted_message, + in Oct32 p_private_enc_key, + in Oct32 p_salt, + out Oct16 p_request_hash, + out Oct16 p_aes_enc_key, + out Ieee1609Dot2Data p_decrypted_message, + out EtsiTs102941Data p_etsi_ts_102941_data + ) return boolean { + var octetstring v_msg; + var boolean ret := true; + + // 1. Calculate the request Hash + v_msg := bit2oct(encvalue(p_encrypted_message)); + log("f_parse_pki_request: Encoded request: ", v_msg); + p_request_hash := substr(f_hashWithSha256(v_msg), 0, 16); + log("f_parse_pki_request: p_request_hash= ", p_request_hash); + + // 2. Decrypt message + log("f_parse_pki_request: p_private_enc_key= ", p_private_enc_key); + if (false == f_decrypt(p_private_enc_key, p_encrypted_message, p_salt, p_decrypted_message, p_aes_enc_key)) { + log("f_parse_pki_request: Failed to decrypt message"); + return false; + } + log("f_parse_pki_request: v_ieee1609dot2_signed_data= ", p_decrypted_message); + log("f_parse_pki_request: p_aes_enc_key= ", p_aes_enc_key); + + // 3. get TS 102 941 data + select(p_decrypted_message){ + case( mw_etsiTs103097Data_signed( + mw_signedData( + -, + mw_toBeSignedData( + mw_signedDataPayload + ) + ) + ) + ) { + var bitstring v_msg_bit; + v_msg_bit := oct2bit(p_decrypted_message.content.signedData.tbsData.payload.data.content.unsecuredData); + if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) { + ret := false; + } + } + case else { + ret := false; + } + } + return ret; + } // End of function f_read_pki_request_message + + function f_read_ec_request_from_iut_itss( + in Ieee1609Dot2Data p_encrypted_message, + out Oct16 p_request_hash, + out Oct16 p_aes_enc_key, + out Ieee1609Dot2Data p_decrypted_message, + out EtsiTs102941Data p_etsi_ts_102941_data, + out InnerEcRequest p_inner_ec_request + ) runs on ItsPkiHttp return boolean { + // Local variables + var PublicVerificationKey v_canonical_key; + var EtsiTs103097Certificate v_ec_certificate; + var HashedId8 v_ec_certificate_hashed_id8; + var InnerEcResponse v_inner_ec_response; +/* + if(false == f_get_canonical_itss_key(v_canonical_key)){ + log(">>> f_read_ec_request_from_iut_itss: error getting canonical key"); + return false; + } +*/ + if( f_read_pki_request_message( p_encrypted_message, vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, + p_request_hash, p_aes_enc_key, + p_decrypted_message, + p_etsi_ts_102941_data + )) { + // decode InnerEcRequest + var bitstring v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData); + if (decvalue(v_msg_bit, p_inner_ec_request) != 0) { + log("f_read_ec_request_from_iut_itss: Failed to decode InnerEcRequest"); + } + return true; + } + return false; + } // End of function f_read_ec_request_from_iut_itss + + /** * @desc Verify the protocol element of the Pki message. * If p_check_security is set to false, only decryption and decoding of the outer message are verified. @@ -5884,7 +6137,8 @@ module LibItsPki_Functions { function f_verify_pki_request_message( in Oct32 p_private_enc_key, in Oct32 p_salt, - in octetstring p_issuer, + in octetstring p_issuer_hash, + in template (omit) PublicVerificationKey p_verification_key, in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data, in boolean p_check_security := true, out Oct16 p_request_hash, @@ -5902,7 +6156,8 @@ module LibItsPki_Functions { log(">>> f_verify_pki_request_message: p_private_enc_key= ", p_private_enc_key); log(">>> f_verify_pki_request_message: p_salt= ", p_salt); - log(">>> f_verify_pki_request_message: p_issuer= ", p_issuer); + log(">>> f_verify_pki_request_message: p_issuer_hash= ", p_issuer_hash); + log(">>> f_verify_pki_request_message: p_verification_key= ", p_verification_key); log(">>> f_verify_pki_request_message: p_ieee1609dot2_encrypted_and_signed_data= ", p_ieee1609dot2_encrypted_and_signed_data); // 1. Calculate the request Hash @@ -5945,30 +6200,75 @@ module LibItsPki_Functions { // 4. Verifiy signature log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData); v_msg := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData)); - log("f_verify_pki_request_message: v_msg= ", v_msg); + if (not ispresent(p_verification_key)){ + var EtsiTs103097Certificate v_cert; + var charstring v_cert_id; + if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.digest)){ + if (not f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_cert, v_cert_id)){ + if (p_check_security == true) { + return false; + } + } + } + if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.certificate)){ + if(lengthof(v_ieee1609dot2_signed_data.content.signedData.signer.certificate) > 0){ + v_cert := v_ieee1609dot2_signed_data.content.signedData.signer.certificate[0]; + } + } + if (isbound(v_cert)){ + if(ischosen(v_cert.toBeSigned.verifyKeyIndicator.verificationKey)){ + p_verification_key := v_cert.toBeSigned.verifyKeyIndicator.verificationKey; + } + } + } + if (ispresent(p_verification_key)){ + log("f_verify_pki_request_message: v_msg= ", v_msg); + if (false == f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_signed_data.content.signedData.signature_, valueof(p_verification_key))) { + if (p_check_security == true) { + return false; + } + } + } + +/* if (p_issuer == ''O) { // self log("f_verify_pki_request_message: Issuer is self, check outer signature using IUT public key (PICS_ITS_S_SIGN_xxx_PUBLIC_KEY)"); var PublicVerificationKey v_verification_key; log("f_verify_pki_request_message: PX_VE_ALG=", PX_VE_ALG); if (PX_VE_ALG == e_nist_p256) { - if (PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY[0] == '02'O) { + if (PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY[0] == '00'O) { + v_verification_key.ecdsaNistP256.x_only := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); + }else if (PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY[0] == '02'O) { v_verification_key.ecdsaNistP256.compressed_y_0 := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); - } else { + }else if (PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY[0] == '03'O) { v_verification_key.ecdsaNistP256.compressed_y_1 := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); + } else { + v_verification_key.ecdsaNistP256.uncompressedP256.x := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 1, 32); + v_verification_key.ecdsaNistP256.uncompressedP256.y := substr(PICS_ITS_S_SIGN_NISTP256_PUBLIC_KEY, 33, 32); } } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM } else if (PX_VE_ALG == e_brainpool_p256_r1) { - if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '02'O) { + if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '00'O) { + v_verification_key.ecdsaBrainpoolP256r1.x_only := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); + }else if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '02'O) { v_verification_key.ecdsaBrainpoolP256r1.compressed_y_0 := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); - } else { + } else if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '03'O) { v_verification_key.ecdsaBrainpoolP256r1.compressed_y_1 := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); + } else if (PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY[0] == '04'O) { + v_verification_key.ecdsaBrainpoolP256r1.uncompressedP256.x := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 1, 32); + v_verification_key.ecdsaBrainpoolP256r1.uncompressedP256.y := substr(PICS_ITS_S_SIGN_BRAINPOOLP256r1_PUBLIC_KEY, 33, 32); } } else if (PX_VE_ALG == e_brainpool_p384_r1) { - if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '02'O) { + if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '00'O) { + v_verification_key.ecdsaBrainpoolP384r1.x_only := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); + }else if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '02'O) { v_verification_key.ecdsaBrainpoolP384r1.compressed_y_0 := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); - } else { + }else if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '02'O) { v_verification_key.ecdsaBrainpoolP384r1.compressed_y_1 := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); + }else if (PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY[0] == '04'O) { + v_verification_key.ecdsaBrainpoolP384r1.uncompressedP384.x := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 1, 48); + v_verification_key.ecdsaBrainpoolP384r1.uncompressedP384.y := substr(PICS_ITS_S_SIGN_BRAINPOOLP384r1_PUBLIC_KEY, 49, 48); } } log("f_verify_pki_request_message: v_verification_key=", v_verification_key); @@ -5991,7 +6291,7 @@ module LibItsPki_Functions { } } } - + */ // 4. Return the PKI message log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData); v_msg_bit := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);