Newer
Older
* $Id$
* @desc Testcases file for Security Protocol
* @reference ETSI TS ITS-00546v006
* @copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
*/
module ItsPki_TestCases {
// Libcommon
import from LibCommon_Time all;
import from LibCommon_VerdictControl all;
import from LibCommon_Sync all;
import from LibCommon_BasicTypesAndValues all;
// LibIts
import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
import from IEEE1609dot2 language "ASN.1:1997" all;
import from EtsiTs102941BaseTypes language "ASN.1:1997" all;
import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorization language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorizationValidation language "ASN.1:1997" all;
import from EtsiTs102941MessagesCa language "ASN.1:1997" all;
import from EtsiTs102941TrustLists language "ASN.1:1997" all;
import from EtsiTs103097Module language "ASN.1:1997" all;
import from ITS_Container language "ASN.1:1997" all;
import from CAM_PDU_Descriptions language "ASN.1:1997" all;
import from LibItsGeoNetworking_TypesAndValues all;
import from LibItsGeoNetworking_Functions all;
import from LibItsGeoNetworking_Templates all;
import from LibItsGeoNetworking_Pics all;
import from LibItsGeoNetworking_TestSystem all;
// LibItsSecurity
import from LibItsSecurity_TypesAndValues all;
import from LibItsSecurity_TestSystem all;
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Functions all;
import from LibItsSecurity_Pixits all;
import from LibItsSecurity_Pics all;
// LibItsHttp
import from LibItsHttp_TypesAndValues all;
import from LibItsHttp_Templates all;
import from LibItsHttp_BinaryTemplates all;
import from LibItsHttp_Functions all;
import from LibItsPki_Pixits all;
// ItsPki
import from ItsPki_Pixits all;
/**
* @desc 5.2 ITS-S behaviour
*/
group itss_behavior {
/**
* @desc The purpose of this function is verify the EC request and extract InnerEcRequest and build the InnerEcResponse for the HTTP response
* Note: This function accepts additional parameters to alter the reponse
*/
function f_verify_http_ec_request_from_iut_itss(
in Request p_request,
out HttpMessage p_response,
out integer p_result,
in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
in template SignerIdentifier p_signer := m_signerIdentifier_self,
in EnrolmentResponseCode p_force_response_code := ok
) runs on ItsPkiHttp {
// Local variables
var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
var EtsiTs102941Data v_etsi_ts_102941_data;
var Oct16 v_request_hash;
var Oct16 v_aes_enc_key;
var template (value) HttpMessage v_response;
log(">>> f_verify_http_ec_request_from_iut_itss: ", p_request);
if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message
v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an error message
// Set verdict
p_result := -1;
} else {
log("f_verify_http_ec_request_from_iut_itss: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))); // TODO In TITAN, this is the only way to get the unmatching in log
if (match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer)))) == false) {
// Send error message
f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
// Set verdict
p_result := -2;
} else {
// Verify signature of mw_innerEcRequestSignedForPop
if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request) == false) {
// Send error message
f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Set verdict
p_result := -3;
} else {
log("f_verify_http_ec_request_from_iut_itss: matching: ", match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes({mw_appPermissions(c_its_aid_SCR, ?)})))); // TODO In TITAN, this is the only way to get the unmatching in log
if (match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)}))) == false) {
// Send error message: Not enrolmentrequest
f_http_build_inner_ec_response(p_inner_ec_request, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Set verdict
p_result := -4;
} else {
log("f_verify_http_ec_request_from_iut_itss: Receive ", p_inner_ec_request);
f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
log("f_verify_http_ec_request_from_iut_itss: Succeed buit force error code ", p_force_response_code);
f_http_build_inner_ec_response(p_inner_ec_request, p_force_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
}
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Set verdict
p_result := 0;
}
}
}
}
p_response := valueof(v_response);
log("<<< f_verify_http_ec_request_from_iut_itss: p_response: ", p_response);
log("<<< f_verify_http_ec_request_from_iut_itss: p_result: ", p_result);
} // End of function f_verify_http_ec_request_from_iut_itss
/**
* @desc The purpose of this function is verify the AT request and extract InnerAtRequest and build the InnerAtResponse for the HTTP response
* Note: This function accepts additional parameters to alter the reponse
*/
function f_verify_http_at_request_from_iut_itss(
in Request p_request,
in Headers p_headers,
in EtsiTs103097Certificate p_ec_certificate,
out InnerAtResponse p_inner_at_response,
out HttpMessage p_response,
out integer p_result,
in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
in AuthorizationResponseCode p_force_response_code := ok
) runs on ItsPkiHttp {
// Local variables
var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
var EtsiTs102941Data v_etsi_ts_102941_data;
var Oct16 v_request_hash;
var Oct16 v_aes_enc_key;
var template (value) HttpMessage v_response;
log(">>> f_verify_http_at_request_from_iut_itss:", p_request);
// Do not verify the signature now because ATRequest is required to verify the POP signature ==> false
if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, p_request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Only decryption
// Send error message, unable to decypt it
v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an error message
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) {
f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
// Set verdict
p_result := -2;
} else {
// Extract InnerAtRequest and Verify signature of mw_innerATRequestSignedForPop
if (f_verify_inner_at_request_signed_for_pop(v_etsi_ts_102941_data, p_ec_certificate, p_inner_at_request) == false) {
f_http_build_authorization_response(p_inner_at_request, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Set verdict
p_result := -3;
} else {
log("f_verify_http_at_request_from_iut_itss: match ", match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // TODO In TITAN, this is the only way to get the unmatching in log
if (match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined
f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Set verdict
p_result := -4;
} else {
var PublicVerificationKey v_verification_tag;
var octetstring v_encoded_tag;
var octetstring v_key_tag;
// Build the tag
v_encoded_tag := bit2oct(encvalue(p_inner_at_request.publicKeys.verificationKey));
if (ispresent(p_inner_at_request.publicKeys.encryptionKey)) {
v_encoded_tag := v_encoded_tag & bit2oct(encvalue(p_inner_at_request.publicKeys.encryptionKey));
}
log("f_verify_http_at_request_from_iut_itss: v_encoded_tag= ", v_encoded_tag);
v_key_tag := substr(
fx_hmac_sha256( // TODO Rename and use a wrapper function
p_inner_at_request.hmacKey,
v_encoded_tag
),
0,
16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
log("f_verify_http_at_request_from_iut_itss: v_key_tag: ", v_key_tag);
log("f_verify_http_at_request_from_iut_itss: keyTag= ", p_inner_at_request.sharedAtRequest.keyTag);
log("f_verify_http_at_request_from_iut_itss: matching: ", match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag));
if (match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag) == false) {
// Send error message: No enrolment request
f_http_build_authorization_response(p_inner_at_request, its_aa_keysdontmatch, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
// Send OK message
log("f_verify_http_at_request_from_iut_itss: Receive ", p_inner_at_request);
if (p_force_response_code == ok) {
f_http_build_authorization_response(p_inner_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
} else {
log("f_verify_http_at_request_from_iut_itss: Succeed built force error code ", p_force_response_code);
f_http_build_authorization_response(p_inner_at_request, p_force_response_code, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_signed_and_encrypted_data);
v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
log("<<< f_verify_http_at_request_from_iut_itss: p_response: ", p_response);
log("<<< f_verify_http_at_request_from_iut_itss: p_result: ", p_result);
} // End of function f_verify_http_at_request_from_iut_itss
* @desc Await ITS CA message using the default AT certificate
*/
altstep a_await_cam_with_current_cert(
in HashedId8 p_certificate_digest,
in EtsiTs103097Certificate p_certificate
) runs on ItsPkiItss {
[PICS_SEC_SHA256 == true] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mw_etsiTs103097Data_signed(
mw_signedData(
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
mw_toBeSignedData(
mw_signedDataPayload,
mw_headerInfo_cam
),
mw_signerIdentifier_certificate(
mw_etsiTs103097Certificate(
mw_issuerIdentifier_sha256AndDigest(
p_certificate.issuer.sha256AndDigest
),
mw_toBeSignedCertificate_at(
-,
p_certificate.toBeSigned.verifyKeyIndicator
)
)
)
)
),
mw_geoNwShbPacket
))) {
}
[PICS_SEC_SHA384 == true] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mw_etsiTs103097Data_signed(
mw_signedData(
sha384,
mw_toBeSignedData(
mw_signedDataPayload,
mw_headerInfo_cam
),
mw_signerIdentifier_certificate(
mw_etsiTs103097Certificate(
mw_issuerIdentifier_sha384AndDigest(
p_certificate.issuer.sha384AndDigest
),
mw_toBeSignedCertificate_at(
-,
p_certificate.toBeSigned.verifyKeyIndicator
)
)
)
)
),
mw_geoNwShbPacket
))) {
}
} // End of altstep a_await_cam_with_current_cert
} // End of group itss_helpers
group itss_enrolment_request {
/**
* @desc Check that IUT sends an enrolment request when triggered.
* <pre>
* Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
* Initial conditions:
* with {
* the IUT being in the "initial state"
* }
* Expected behaviour:
* ensure that {
* when {
* the IUT is triggered to requested a new Enrolment Certificate (EC)
* }
* then {
* the IUT sends to EA an EnrolmentRequestMessage
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_01_BV
* @reference ETSI TS 102 941 [2], clause 6.1.3
*/
testcase TC_SECPKI_ITSS_ENR_01_BV() runs on ItsMtc system ItsPkiItssSystem {
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 ***");
v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss());
v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki());
f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
} // End of testcase TC_SECPKI_ITSS_ENR_01_BV
group f_TC_SECPKI_ITSS_ENR_01_BV {
function f_TC_SECPKI_ITSS_ENR_01_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem {
var HashedId8 v_certificate_digest;
var EtsiTs103097Certificate v_certificate;
vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE;
// Initial state: No CAM shall be emitted
geoNetworkingPort.clear;
tc_noac.start;
alt {
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_prDone, e_error);
}
[] tc_noac.timeout {
log("*** " & testcasename() & ": PASS: No CA message received ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_success);
tc_noac.start;
alt {
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
}
[] tc_noac.timeout {
log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
}
} // End of 'alt' statement
} // End of function f_TC_SECPKI_ITSS_ENR_01_BV_itss
function f_TC_SECPKI_ITSS_ENR_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
// 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);
tc_ac.start;
alt {
[] a_await_at_http_response_from_iut(
mw_http_request(
mw_http_request_post(
PICS_HTTP_POST_URI_EC,
-,
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentRequestMessage(
mw_encryptedData(
{ *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * },
mw_SymmetricCiphertext_aes128ccm
)))))),
v_request
) {
var HttpMessage v_response;
var integer v_result;
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() & ": PASS: InnerEcRequest received ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
}
[] tc_ac.timeout {
log("*** " & testcasename() & ": INCONC: Expected message not received ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
}
} // End of 'alt' statement
// Postamble
} // End of function f_TC_SECPKI_ITSS_ENR_01_BV_pki
} // End of group f_TC_SECPKI_ITSS_ENR_01_BV
/**
* @desc If the enrolment request of the IUT is an initial enrolment request, the itsId
* (contained in the InnerECRequest) shall be set to the canonical identifier, the
* signer (contained in the outer EtsiTs1030971Data-Signed) shall be set to self and
* the outer signature shall be computed using the canonical private key.
* <pre>
* Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT
* Expected behaviour:
* ensure that {
* when {
* the IUT is requested to send an EnrolmentRequestMessage
* }
* then {
* the IUT sends an EtsiTs103097Data-Encrypted
* containing an encrypted EtsiTs103097Data-Signed
* containing EtsiTs103097Data
* containing InnerECRequestSignedForPOP
* containing InnerEcRequest
* containing itsId
* indicating the canonical identifier of the ITS-S
* and containing signer
* declared as self
* and containing signature
* computed using the canonical private key
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_02_BV
* @reference ETSI TS 102 941, clause 6.1.3
*/
testcase TC_SECPKI_ITSS_ENR_02_BV() runs on ItsMtc system ItsPkiItssSystem {
// Local variables
var ItsPkiItss v_itss;
var ItsPkiHttp v_ea;
// Test control
if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) {
log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***");
setverdict(inconc);
stop;
}
// Test component configuration
v_itss.start(f_TC_SECPKI_ITSS_ENR_01_BV_itss());
v_ea.start(f_TC_SECPKI_ITSS_ENR_01_BV_pki());
f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
} // End of testcase TC_SECPKI_ITSS_ENR_02_BV
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
/**
* @desc In presence of a valid EC, the enrolment request of the IUT is a rekeying enrolment
request with the itsId (contained in the InnerECRequest) and the SignerIdentifier
(contained in the outer EtsiTs1030971Data-Signed) both declared as digest containing
the HashedId8 of the EC and the outer signature computed using the current valid EC
private key corresponding to the verification public key.
* <pre>
* Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT
* Expected behaviour:
* ensure that {
* when {
* the IUT is requested to send an EnrolmentRequestMessage
* }
* then {
* the IUT sends an EtsiTs103097Data-Encrypted
* containing an encrypted EtsiTs103097Data-Signed
* containing EtsiTs103097Data
* containing InnerECRequestSignedForPOP
* containing InnerEcRequest
* containing itsId
* declared as digest containing the HashedId8 of the EC identifier
* and containing signer
* declared as digest containing the HashedId8 of the EC identifier
* and containing signature
* computed using the current valid EC private key corresponding to the verification public key
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_03_BV
testcase TC_SECPKI_ITSS_ENR_03_BV() runs on ItsMtc system ItsPkiItssSystem {
// Local variables
var ItsPkiItss v_itss;
var ItsPkiHttp v_ea;
// Test control
if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_REENROLMENT) {
log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_REENROLMENT required for executing the TC ***");
setverdict(inconc);
stop;
}
// Test component configuration
v_itss.start(f_TC_SECPKI_ITSS_ENR_03_BV_itss());
v_ea.start(f_TC_SECPKI_ITSS_ENR_03_BV_pki());
// Synchronization
f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
// Cleanup
} // End of testcase TC_SECPKI_ITSS_ENR_03_BV
group f_TC_SECPKI_ITSS_ENR_03_BV {
function f_TC_SECPKI_ITSS_ENR_03_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem {
// Local variables
var HashedId8 v_certificate_digest;
var EtsiTs103097Certificate v_certificate;
// Test component configuration
vc_hashedId8ToBeUsed := PX_IUT_DEFAULT_CERTIFICATE;
f_cfUp_itss();
// Test adapter configuration
// Preamble
// Initial state: No CAM shall be emitted
geoNetworkingPort.clear;
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_prDone, e_error);
[] tc_noac.timeout {
// Trigger the first enrolment
f_sendUtTriggerEnrolmentRequestPrimitive();
log("*** " & testcasename() & ": PASS: No CA message received ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_success);
// Test Body
tc_noac.start;
alt {
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
}
[] tc_noac.timeout {
log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
// Postamble
f_cfDown_itss();
} // End of function f_TC_SECPKI_ITSS_ENR_03_BV_itss
function f_TC_SECPKI_ITSS_ENR_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
// Local variable
var HttpMessage v_request;
var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
// Test component configuration
f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID);
// Test adapter configuration
// Preamble
f_init_default_headers_list(-, "inner_ec_response", v_headers);
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
alt {
[] a_await_at_http_response_from_iut(
mw_http_request(
mw_http_request_post(
PICS_HTTP_POST_URI_EC,
-,
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentRequestMessage(
mw_encryptedData(
{ *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * },
mw_SymmetricCiphertext_aes128ccm
)))))),
v_request
) {
var integer v_result;
var InnerEcRequest v_inner_ec_request;
var InnerEcResponse v_inner_ec_response;
var HttpMessage v_response;
tc_ac.stop;
// Verify IUT response
f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result);
// Send response
if (isvalue(v_response)) {
httpPort.send(v_response);
} // TODO Send HTTP error 500
// Set verdict
if (v_result == 0) {
log("*** " & testcasename() & ": INFO: First InnerEcRequest received ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_success);
} else {
log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_error);
}
}
[] tc_ac.timeout {
log("*** " & testcasename() & ": INCONC: Expected message not received ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
}
} // End of 'alt' statement
// Test Body
tc_ac.start;
alt {
[] a_await_at_http_response_from_iut(
mw_http_request(
mw_http_request_post(
PICS_HTTP_POST_URI_EC,
-,
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentRequestMessage(
mw_encryptedData(
{ *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * },
mw_SymmetricCiphertext_aes128ccm
)))))),
v_request
) {
var integer v_result;
var InnerEcRequest v_inner_ec_request;
v_request.request,
v_headers,
v_inner_ec_request,
v_inner_ec_response,
v_response,
v_result,
PX_EC_HASHED_ID8, // v_response...
// containing itsId declared as digest containing the HashedId8 of the EC identifier
m_signerIdentifier_digest(PX_EC_HASHED_ID8 // containing signer declared as digest containing the HashedId8 of the EC identifier
)
);
// Send response
if (isvalue(v_response)) {
httpPort.send(v_response);
// Set verdict
if (v_result == 0) {
log("*** " & testcasename() & ": PASS: InnerEcRequest received ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
} else {
log("*** " & testcasename() & ": FAIL: Failed to verify EA an EnrolmentRequestMessage ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
}
}
[] tc_ac.timeout {
log("*** " & testcasename() & ": INCONC: Expected message not received ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
}
} // End of 'alt' statement
// Postamble
f_cfHttpDown();
} // End of function f_TC_SECPKI_ITSS_ENR_03_BV_pki
} // End of group f_TC_SECPKI_ITSS_ENR_03_BV
/**
* @desc If the EC is revoked, the IUT returns to the state 'initialized'.
* <pre>
* Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_CRL
* Expected behaviour:
* ensure that {
* when {
* the IUT is informed about a revocation of its EC
* }
* then {
* the IUT returns to the "initialized" state
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_04_BV
* @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1
*/
testcase TC_SECPKI_ITSS_ENR_04_BV() runs on ItsMtc system ItsPkiItssSystem {
// Local variables
var Oct32 v_private_key;
var Oct32 v_public_key_x;
var Oct32 v_public_key_y;
var Oct32 v_public_compressed_key;
var integer v_compressed_mode;
var ItsPkiItss v_itss;
var ItsPkiHttp v_ea;
// Test control
if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or not PICS_SECPKI_CRL) {
log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and PICS_SECPKI_CRL required for executing the TC ***");
setverdict(inconc);
stop;
}
// Test component configuration
// Synchronization
// Cleanup
} // End of TC_SECPKI_ITSS_ENR_04_BV
/**
* @desc If the EC expires, the IUT returns to the state 'initialized'.
* <pre>
* 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
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_05_BV
* @reference ETSI TS 102 941, clause 6.1.3, 6.2.3.2.1
*/
testcase TC_SECPKI_ITSS_ENR_05_BV() runs on ItsMtc system ItsPkiItssSystem {
// Local variables
var Oct32 v_private_key;
var Oct32 v_public_key_x;
var Oct32 v_public_key_y;
var Oct32 v_public_compressed_key;
var integer v_compressed_mode;
var ItsPkiItss v_itss;
var ItsPkiHttp v_ea;
// Test control
if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT) {
log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT required for executing the TC ***");
setverdict(inconc);
stop;
}
// Test component configuration
// Synchronization
// Cleanup
} // End of TC_SECPKI_ITSS_ENR_05_BV
/**
* @desc For each enrolment request, the ITS-S shall generate a new verification key pair
corresponding to an approved signature algorithm as specified in TS 103 097.
* <pre>
* Pics Selection: PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and not PICS_SECPKI_REENROLMENT
* Expected behaviour:
* ensure that {
* when {
* the IUT is requested to send multiple EnrolmentRequestMessage
* }
* then {
* each EnrolmentRequestMessage
* contains a different and unique verification key pair within the InnerECRequest
* }
* }
* </pre>
*
* @see ETSI TS 103 525-2 v1.1.3 SECPKI_ITSS_ENR_06_BV
* @reference ETSI TS 102 941, clause 6.1.3
*/
testcase TC_SECPKI_ITSS_ENR_06_BV() runs on ItsMtc system ItsPkiItssSystem {
// Local variables
var ItsPkiItss v_itss;
var ItsPkiHttp v_ea;
// Test control
if (not PICS_IUT_ITS_S_ROLE or not PICS_SECPKI_ENROLMENT or PICS_SECPKI_REENROLMENT) {
log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_SECPKI_ENROLMENT and not PICS_SECPKI_REENROLMENT required for executing the TC ***");
setverdict(inconc);
stop;
}
// Test component configuration
v_itss.start(f_TC_SECPKI_ITSS_ENR_06_BV_itss());
v_ea.start(f_TC_SECPKI_ITSS_ENR_06_BV_pki());
f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
// Cleanup
} // End of TC_SECPKI_ITSS_ENR_06_BV
group f_TC_SECPKI_ITSS_ENR_06_BV {
function f_TC_SECPKI_ITSS_ENR_06_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem {
var HashedId8 v_certificate_digest := int2oct(0, 8);
// Test component configuration
f_cfUp_itss();
// Test adapter configuration
// Preamble
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_prDone, e_error);
[] tc_noac.timeout {
log("*** " & testcasename() & ": PASS: No CA message received ***");
f_selfOrClientSyncAndVerdict(c_prDone, e_success);
// Re-enrolment
for (var integer v_i := 0; v_i < PX_RE_ENROLMENT_COUNTER; v_i := v_i + 1) {
f_sendUtTriggerEnrolmentRequestPrimitive();
f_sleep(PX_RE_ENROLMENT_DELAY);
} // End of 'for' statement
tc_noac.start;
alt {
[] geoNetworkingPort.receive {
log("No CA message expected");
f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
}
[] tc_noac.timeout {
log("*** " & testcasename() & ": PASS: Enrolment trigger sent succesfully ***");
f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
}
} // End of 'alt' statement
// Postamble
f_cfDown_itss();
} // End of function f_TC_SECPKI_ITSS_ENR_06_BV_itss
function f_TC_SECPKI_ITSS_ENR_06_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
var HttpMessage v_response;
var InnerEcRequest v_inner_ec_request;
var ListOfPublicVerificationKey v_generated_keys;
var integer v_result;
// Test component configuration
f_cfHttpUp();
// Test adapter configuration
// Preamble
f_init_default_headers_list(-, "inner_ec_response", v_headers);
// Wait for the first enrolment response
tc_ac.start;
alt {
[] a_await_at_http_response_from_iut(
mw_http_request(
mw_http_request_post(
PICS_HTTP_POST_URI_EC,
-,
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentRequestMessage(
mw_encryptedData(
{ *, mw_recipientInfo_certRecipInfo(mw_pKRecipientInfo(vc_eaHashedId8)), * },
mw_SymmetricCiphertext_aes128ccm
)))))),
v_request
) {
tc_ac.stop;
// Verify IUT response
f_verify_http_ec_request_from_iut_itss(v_request.request, v_headers, v_inner_ec_request, v_inner_ec_response, v_response, v_result);
// Send response
if (isvalue(v_response)) {
httpPort.send(v_response);