Newer
Older
* @author ETSI / STF544
* @version $URL$
* $Id$
* @desc Module containing functions for ITS PKI ATS
* @copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
*
*/
module LibItsPki_Functions {
// LibCommon
import from LibCommon_Time all;
import from LibCommon_VerdictControl all;
import from LibCommon_Sync all;
import from LibCommon_BasicTypesAndValues all;
import from LibCommon_DataStrings all;
// LibIts
import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
import from IEEE1609dot2 language "ASN.1:1997" all;
import from EtsiTs102941BaseTypes language "ASN.1:1997" all;
import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorization language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorizationValidation language "ASN.1:1997" all;
import from EtsiTs102941MessagesCa language "ASN.1:1997" all;
import from EtsiTs103097Module language "ASN.1:1997" all;
import from ITS_Container language "ASN.1:1997" all;
import from CAM_PDU_Descriptions language "ASN.1:1997" all;
// LibItsCommon
import from LibItsCommon_Functions all;
import from LibItsCommon_ASN1_NamedNumbers all;
import from LibItsCommon_Pixits all;
// LibItsGeoNetworking
import from LibItsGeoNetworking_TypesAndValues all;
import from LibItsGeoNetworking_TestSystem all;
import from LibItsGeoNetworking_Pixits all;
// LibItsSecurity
import from LibItsSecurity_TypesAndValues all;
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Functions all;
import from LibItsSecurity_TestSystem all;
// LibItsHttp
import from LibItsHttp_TypesAndValues all;
import from LibItsHttp_Templates all;
import from LibItsHttp_BinaryTemplates all;
import from LibItsHttp_Functions all;
function f_cfMtcUp(
out ItsPkiItss p_itss,
out ItsPkiHttp p_pki
) runs on ItsMtc {
p_itss := ItsPkiItss.create("IUT") alive;
p_pki := ItsPkiHttp.create("TS") alive;
connect(self:syncPort, mtc:syncPort);
connect(p_itss:syncPort, self:syncPort);
connect(p_pki:syncPort, self:syncPort);
}
/**
* @desc Setups default configuration
* @param p_certificate_id The certificate identifier the TA shall use in case of secured IUT
in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant
in charstring p_aa_certificate_id := "CERT_TS_A_AA"
) runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ {
map(self:httpPort, system:httpPort);
} else {
map(self:httpEcPort, system:httpEcPort);
map(self:httpAtVPort, system:httpAtVPort);
map(self:httpAtPort, system:httpAtPort);
}
f_initialiseSecuredMode(p_ea_certificate_id, p_aa_certificate_id); // TODO To be removed???
// Setup EA certificate shared with PKI EA entity
f_readCertificate(p_ea_certificate_id, vc_eaCertificate);
f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed
f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey);
f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8);
f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash);
log("f_cfHttpUp: vc_eaPrivateKey= ", vc_eaPrivateKey);
log("f_cfHttpUp: vc_eaPrivateEncKey= ", vc_eaPrivateEncKey);
log("f_cfHttpUp: vc_eaHashedId8= ", vc_eaHashedId8);
log("f_cfHttpUp: vc_eaWholeHash= ", vc_eaWholeHash);
// Setup AA certificate shared with PKI AA entity
f_readCertificate(p_aa_certificate_id, vc_aaCertificate);
f_readSigningKey(p_aa_certificate_id, vc_aaPrivateKey); // Required for AuthorizationValidation request
f_readEncryptingKey(p_aa_certificate_id, vc_aaPrivateEncKey);
f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8);
f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash);
log("f_cfHttpUp: vc_aaPrivateKey= ", vc_aaPrivateKey);
log("f_cfHttpUp: vc_aaPrivateEncKey= ", vc_aaPrivateEncKey);
log("f_cfHttpUp: vc_aaHashedId8= ", vc_aaHashedId8);
log("f_cfHttpUp: vc_aaWholeHash= ", vc_aaWholeHash);
if (PICS_MULTIPLE_END_POINT == false) {
activate(a_default_pki_http());
} else {
activate(a_default_pki_http_ec());
activate(a_default_pki_http_atv());
activate(a_default_pki_http_at());
}
in charstring p_certificate_id := "CERT_TS_A_EA" // TODO Use a constant
) runs on ItsPkiItss /* TITAN TODO: system ItsPkiItssSystem */ {
map(self:geoNetworkingPort, system:geoNetworkingPort);
map(self:utPort, system:utPort);
f_initializeState();
// activate(a_default_pki()); TOTO Defualt from geoNet
/**
* @desc Deletes default configuration
*/
function f_cfMtcDown(
inout ItsPkiItss p_itss,
inout ItsPkiHttp p_pki
) runs on ItsMtc {
disconnect(self:syncPort, mtc:syncPort);
disconnect(p_itss:syncPort, self:syncPort);
disconnect(p_pki:syncPort, self:syncPort);
p_itss.done;
p_pki.done;
}
/**
* @desc Deletes default configuration
*/
function f_cfHttpDown() runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ {
if (PICS_MULTIPLE_END_POINT == false) {
unmap(self:httpPort, system:httpPort);
} else {
unmap(self:httpEcPort, system:httpEcPort);
unmap(self:httpAtVPort, system:httpAtVPort);
unmap(self:httpAtPort, system:httpAtPort);
}
f_uninitialiseSecuredMode();
/**
* @desc Deletes default configuration
*/
function f_cfDown_itss() runs on ItsPkiItss /* TITAN TODO: system ItsPkiItssSystem */ {
unmap(self:geoNetworkingPort, system:geoNetworkingPort);
unmap(self:utPort, system:utPort);
} // End of function f_cfDown
/**
* @desc Initialise secure mode if required
*/
function f_initialiseSecuredMode(
in charstring p_certificate_id := "CERT_TS_A_EA", // TODO Use a constant
in charstring p_peerCertificateId := "CERT_IUT_A_EA"
) runs on ItsSecurityBaseComponent {
if(not(f_loadCertificates(PX_IUT_SEC_CONFIG_NAME))) {
log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***");
setverdict(inconc);
// f_prepareCertificates(p_certificate_id, vc_aaCertificate, vc_atCertificate);
function f_uninitialiseSecuredMode() runs on ItsSecurityBaseComponent {
f_unloadCertificates();
} // End of function f_uninitialiseSecuredMode()
function f_initializeState() runs on ItsPkiItss {
var Oct8 v_hashedId8ToBeUsed;
log(">>> f_initializeState: vc_hashedId8ToBeUsed= ", vc_hashedId8ToBeUsed);
v_hashedId8ToBeUsed := f_setupIutCertificate(vc_hashedId8ToBeUsed);
log("f_initializeState: v_hashedId8ToBeUsed= ", v_hashedId8ToBeUsed);
f_utInitializeIut(UtPkiInitialize: { v_hashedId8ToBeUsed } );
f_sleep(PX_NEIGHBOUR_DISCOVERY_DELAY);
// f_acLoadScenario(p_scenario);
// f_acStartScenario();
}
group ut_port {
function f_utInitializeIut(template (value) UtPkiInitialize p_init) runs on ItsPkiItss {
utPort.send(p_init);
tc_wait.start;
alt {
[] utPort.receive(UtPkiResults: { utPkiInitializeResult := true }) {
tc_wait.stop;
log("*** f_utInitializeIut: INFO: IUT initialized ***");
}
[] utPort.receive {
tc_wait.stop;
log("*** f_utInitializeIut: INFO: IUT could not be initialized ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
[] tc_wait.timeout {
log("*** f_utInitializeIut: INFO: IUT could not be initialized in time ***");
f_selfOrClientSyncAndVerdict("error", e_timeout);
}
}
} // End of function f_utInitializeIut
function f_sendUtTriggerEnrolmentRequestPrimitive(
in octetstring p_canonical_id := ''O,
in Oct1 p_enc_algorithm := '00'O,
in octetstring p_private_key := ''O,
in octetstring p_public_key_compressed := ''O,
in integer p_compressed_mode := 0
) runs on ItsPkiItss {
var TriggerEnrolmentRequest v_ut_trigger_enrolment_request;
var octetstring v_compressed_public_key;
if (p_compressed_mode == 2) { // TODO v_compressed_public_key := int2oct(p_compressed_mode, 1) & p_public_key_compressed?
v_compressed_public_key := '02'O & p_public_key_compressed;
} else {
v_compressed_public_key := '03'O & p_public_key_compressed;
v_ut_trigger_enrolment_request := { p_canonical_id, p_enc_algorithm, p_private_key, v_compressed_public_key };
utPort.send(UtPkiTrigger: { triggerEnrolmentRequest := v_ut_trigger_enrolment_request });
tc_ac.start;
alt {
[] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) {
tc_ac.stop;
}
[] utPort.receive(UtPkiResults: { utPkiTriggerResult := false }) {
tc_ac.stop;
274
275
276
277
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
log("*** f_sendUtTriggerEnrolmentRequestPrimitive: ERROR: Received unexpected message ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
[] tc_ac.timeout {
log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***");
f_selfOrClientSyncAndVerdict("error", e_timeout);
}
} // End of 'alt' statement
} // End of function f_sendUtTriggerEnrolmentRequestPrimitive
function f_sendUtTriggerAuthorizationRequestPrimitive(
in octetstring p_canonical_id := ''O,
in Oct1 p_enc_algorithm := '00'O,
in octetstring p_private_key := ''O,
in octetstring p_public_key_compressed := ''O,
in integer p_compressed_mode := 0
) runs on ItsPkiItss {
var TriggerAuthorizationRequest v_ut_trigger_enrolment_request;
var octetstring v_compressed_public_key;
if (p_compressed_mode == 2) { // TODO v_compressed_public_key := int2oct(p_compressed_mode, 1) & p_public_key_compressed?
v_compressed_public_key := '02'O & p_public_key_compressed;
} else {
v_compressed_public_key := '03'O & p_public_key_compressed;
}
v_ut_trigger_enrolment_request := { p_canonical_id, p_enc_algorithm, p_private_key, v_compressed_public_key };
utPort.send(UtPkiTrigger: { triggerAuthorizationRequest := v_ut_trigger_enrolment_request });
tc_ac.start;
alt {
[] utPort.receive(UtPkiResults: { utPkiTriggerResult := true }) {
tc_ac.stop;
}
[] utPort.receive(UtPkiResults: { utPkiTriggerResult := false }) {
tc_ac.stop;
log("*** f_sendUtTriggerAuthorizationRequestPrimitive: ERROR: Received unexpected message ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
[] tc_ac.timeout {
log("*** f_sendAcPkiPrimitive: ERROR: Timeout while waiting for adapter control event result ***");
f_selfOrClientSyncAndVerdict("error", e_timeout);
}
} // End of 'alt' statement
} // End of function f_sendUtTriggerAuthorizationRequestPrimitive
} // End of group ut_port
group helpers {
function f_generate_key_pair(
out octetstring p_private_key,
out octetstring p_public_key_x,
out octetstring p_public_key_y,
out octetstring p_public_key_compressed,
out integer p_compressed_mode
) return boolean {
if (PX_VE_ALG == e_nist_p256) {
f_generate_key_pair_nistp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
f_generate_key_pair_brainpoolp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
f_generate_key_pair_brainpoolp384(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode);
} else {
// error
return false;
}
return true;
}
function f_generate_key_pair_for_encryption(
in SecurityAlg p_algorithm,
out octetstring p_private_key,
out octetstring p_public_key_x,
out octetstring p_public_key_y,
out octetstring p_public_key_compressed,
out integer p_compressed_mode
) return boolean {
if (p_algorithm == e_nist_p256) {
f_generate_key_pair_nistp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode);
} else if (p_algorithm == e_brainpool_p256_r1) {
f_generate_key_pair_brainpoolp256(p_private_key, p_public_key_x, p_public_key_y, p_public_key_compressed, p_compressed_mode);
} else {
// error
return false;
}
return true;
}
function f_signWithEcdsa(
in octetstring p_toBeSignedSecuredMessage,
in octetstring p_certificateIssuer,
in octetstring p_privateKey
) return octetstring {
if (PX_VE_ALG == e_nist_p256) {
return f_signWithEcdsaNistp256WithSha256(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
return f_signWithEcdsaBrainpoolp256WithSha256(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
return f_signWithEcdsaBrainpoolp384WithSha384(p_toBeSignedSecuredMessage, p_certificateIssuer, p_privateKey);
}
return ''O;
} // End of function f_signWithEcdsa
function f_verifyEcdsa(
in octetstring p_tbs,
in octetstring p_issuer,
in Signature p_signature_,
in PublicVerificationKey p_verification_key
) return boolean {
var boolean v_ret := false;
log(">>> f_verifyEcdsa: p_tbs= ", p_tbs);
log(">>> f_verifyEcdsa: p_issuer= ", p_issuer);
log(">>> f_verifyEcdsa: p_signature_= ", p_signature_);
log(">>> f_verifyEcdsa: p_verification_key= ", p_verification_key);
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
if (ischosen(p_verification_key.ecdsaNistP256)) {
if (ischosen(p_verification_key.ecdsaNistP256.compressed_y_0)) {
v_ret := f_verifyWithEcdsaNistp256WithSha256(
p_tbs,
p_issuer,
p_signature_.ecdsaNistP256Signature.rSig.x_only & p_signature_.ecdsaNistP256Signature.sSig,
p_verification_key.ecdsaNistP256.compressed_y_0,
0);
} else {
v_ret := f_verifyWithEcdsaNistp256WithSha256(
p_tbs,
p_issuer,
p_signature_.ecdsaNistP256Signature.rSig.x_only & p_signature_.ecdsaNistP256Signature.sSig,
p_verification_key.ecdsaNistP256.compressed_y_1,
1);
}
} else if (ischosen(p_verification_key.ecdsaBrainpoolP256r1)) {
if (ischosen(p_verification_key.ecdsaBrainpoolP256r1.compressed_y_0)) {
v_ret := f_verifyWithEcdsaBrainpoolp256WithSha256(
p_tbs,
p_issuer,
p_signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP256r1Signature.sSig,
p_verification_key.ecdsaBrainpoolP256r1.compressed_y_0,
0);
} else {
v_ret := f_verifyWithEcdsaBrainpoolp256WithSha256(
p_tbs,
p_issuer,
p_signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP256r1Signature.sSig,
p_verification_key.ecdsaBrainpoolP256r1.compressed_y_1,
1);
}
} else if (ischosen(p_verification_key.ecdsaBrainpoolP384r1)) {
if (ischosen(p_verification_key.ecdsaBrainpoolP384r1.compressed_y_0)) {
v_ret := f_verifyWithEcdsaBrainpoolp384WithSha384(
p_tbs,
p_issuer,
p_signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP384r1Signature.sSig,
p_verification_key.ecdsaBrainpoolP384r1.compressed_y_0,
0);
} else {
v_ret := f_verifyWithEcdsaBrainpoolp384WithSha384(
p_tbs,
p_issuer,
p_signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & p_signature_.ecdsaBrainpoolP384r1Signature.sSig,
p_verification_key.ecdsaBrainpoolP384r1.compressed_y_1,
1);
}
}
return v_ret;
} // End of function f_verifyEcdsa
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
function f_http_send(
in HeaderLines p_headers,
in template (value) HttpMessage p_http_message
) runs on ItsPkiHttp {
if (not(PICS_MULTIPLE_END_POINT)) {
httpPort.send(p_http_message);
} else {
var charstring_list v_content_text;
f_get_header(p_headers, c_header_content_text, v_content_text);
if (not(isvalue(v_content_text))) {
log("f_http_send: Failed to send message: header not found: ", c_header_content_text);
return;
}
if (v_content_text == { "inner_ec_request" }) {
log("f_http_send: Send on EC end point");
f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers);
if (ischosen(p_http_message.request)) {
p_http_message.request.header := p_headers;
} else {
p_http_message.response.header := p_headers;
}
httpEcPort.send(p_http_message);
} else if (v_content_text == { "inner_atv_request" }) {
log("f_http_send: Send on ATV end point");
f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_ATV }, p_headers);
if (ischosen(p_http_message.request)) {
p_http_message.request.header := p_headers;
} else {
p_http_message.response.header := p_headers;
}
httpAtVPort.send(p_http_message);
} else if (v_content_text == { "inner_at_request" }) {
log("f_http_send: Send on AT end point");
f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_AT }, p_headers);
if (ischosen(p_http_message.request)) {
p_http_message.request.header := p_headers;
} else {
p_http_message.response.header := p_headers;
}
httpAtPort.send(p_http_message);
} else {
log("f_http_send: Invalid header value: ", v_content_text);
}
}
} // End of function f_http_send
} // End of group helpers
group http { // TODO Split into EnnerEc, Authorization & AuthorizationValidation
function f_http_build_inner_ec_request( // TODO Cleanup parameters
out octetstring p_public_key_compressed,
out integer p_compressed_mode,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out octetstring p_salt,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
var InnerEcRequest v_inner_ec_request;
var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode;
if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log ("f_http_build_enrolment_request: ==> EC verification private key: ", p_private_key);
log ("f_http_build_enrolment_request: ==> EC verification public compressed key: ", p_public_key_compressed);
log ("f_http_build_enrolment_request: ==> EC verification public compressed mode: ", p_compressed_mode);
// Generate InnerEcRequestSignedForPoP
if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log("f_http_build_enrolment_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
// Secure InnerEcRequestSignedForPoP message
if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
v_public_enc_key := 'DD4F6B0DF57C6E3BD0E32B565CACA1D858CEB08A5C2BBAB2C23E203C6DE697FF'O;
v_compressed_enc_key_mode := 0;
}
log("f_http_build_inner_ec_request: Public encryption key: ", v_public_enc_key);
log("f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode);
if (PICS_SECPKI_REENROLMENT == false) { // This is the first enrolment, we used Factory keys
v_result := f_build_pki_secured_request_message_signed_with_pop(PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
// TODO Retrieve EC certificate from the first enrolment instead of PX
log("f_http_build_inner_ec_request: v_ec_private_key: ", PX_EC_PRIVATE_KEY);
log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", PX_EC_HASHED_ID8);
v_result := f_build_pki_secured_request_message_signed_with_pop(PX_EC_PRIVATE_KEY, valueof(m_signerIdentifier_digest(PX_EC_HASHED_ID8)), PX_EC_HASHED_ID8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error);
} else {
log("f_http_build_inner_ec_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
log("f_http_build_inner_ec_request: p_request_hash= ", p_request_hash);
function f_http_build_invalid_enrolment_request(
out octetstring p_private_key,
out octetstring p_public_key_compressed,
out integer p_compressed_mode,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out octetstring p_salt,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
) runs on ItsPkiHttp {
var InnerEcRequest v_inner_ec_request;
var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode;
var boolean v_ret_code;
if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log ("f_http_build_invalid_enrolment_request: EC verification private key: ", p_private_key);
log ("f_http_build_invalid_enrolment_request: EC verification public compressed key: ", p_public_key_compressed);
log ("f_http_build_invalid_enrolment_request: EC verification public compressed mode: ", p_compressed_mode);
// Generate InnerEcRequestSignedForPoP
if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log("f_http_build_invalid_enrolment_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
// Modify signature to get an error
if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature)) {
v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1]));
} else {
v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1]));
}
// Secure InnerEcRequestSignedForPoP message
if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("*** f_http_build_invalid_enrolment_request: ERROR: Non canonical EA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log("*** f_http_build_invalid_enrolment_request: Public encryption key: ", v_public_enc_key);
log("*** f_http_build_invalid_enrolment_request: Public encryption key comp: ", v_compressed_enc_key_mode);
if (PICS_SECPKI_REENROLMENT == false) { // This is the first enrolment, we used Factory keys
v_ret_code := f_build_pki_secured_request_message_signed_with_pop(PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
// TODO Retrieve EC certificate from the first enrolment instead of PX
log("f_http_build_inner_ec_request: v_ec_private_key: ", PX_EC_PRIVATE_KEY);
log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", PX_EC_HASHED_ID8);
v_ret_code := f_build_pki_secured_request_message_signed_with_pop(PX_EC_PRIVATE_KEY, valueof(m_signerIdentifier_digest(PX_EC_HASHED_ID8)), PX_EC_HASHED_ID8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
log("*** f_http_build_invalid_enrolment_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data);
} // End of function f_http_build_invalid_enrolment_request
function f_http_build_inner_ec_response(
in InnerEcRequest p_inner_ec_request,
in EnrolmentResponseCode p_responseCode := ok,
in Oct16 p_request_hash,
in octetstring p_private_key := ''O,
in octetstring p_digest := ''O,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
) return boolean {
// Local variables
var bitstring v_msg_bit;
var octetstring v_msg;
var Oct12 v_nonce;
var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
var EtsiTs103097Certificate v_ec_certificate;
var boolean p_result := false;
log(">>> f_http_build_inner_ec_response: p_inner_ec_request= ", p_inner_ec_request);
log(">>> f_http_build_inner_ec_response: p_responseCode= ", p_responseCode);
log(">>> f_http_build_inner_ec_response: p_request_hash= ", p_request_hash);
log(">>> f_http_build_inner_ec_response: p_private_key= ", p_private_key);
log(">>> f_http_build_inner_ec_response: p_digest= ", p_digest);
log(">>> f_http_build_inner_ec_response: p_aes_sym_key= ", p_aes_sym_key);
// Check expectred response
if (p_responseCode != ok) {
m_innerEcResponse_ko(
p_request_hash,
p_responseCode
)
);
p_result := true;
} else {
// Generate the certificate
if (f_generate_ec_certificate_for_inner_ec_response(p_inner_ec_request, p_private_key, p_digest, v_ec_certificate) == false) {
log("f_http_build_inner_ec_response: Failed to generate the certificate");
m_innerEcResponse_ko(
p_request_hash,
incompleterequest
)
);
} else {
m_innerEcResponse_ok(
p_request_hash,
v_ec_certificate
)
);
}
}
// Secure the response
log("f_http_build_inner_ec_response: p_inner_ec_response= ", p_inner_ec_response);
v_msg := bit2oct(encvalue(p_inner_ec_response));
v_nonce := int2oct(f_getCurrentTime(), 32); // 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");
m_innerEcResponse_ko(
p_request_hash,
deniedrequest
)
);
} else {
p_result := true;
}
return p_result;
} // End of function f_http_build_inner_ec_response
function f_http_build_authorization_request(
in Certificate p_ec_certificate, // Enrolment credentials certificate
in octetstring p_ec_private_key,
out octetstring p_private_key,
out octetstring p_private_enc_key,
out octetstring p_public_compressed_enc_key,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out octetstring p_salt,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct32 p_request_hash
) runs on ItsPkiHttp {
var octetstring v_public_key_x;
var octetstring v_public_key_y;
var octetstring v_public_enc_key_x;
var octetstring v_public_enc_key_y;
var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode;
var InnerAtRequest v_inner_at_request;
var Ieee1609Dot2Data v_inner_at_request_data;
var InnerAtRequest v_authorization_request;
var bitstring v_authorization_request_msg;
if (f_generate_inner_at_request(vc_aaCertificate, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationValidationRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error);
log("f_http_build_authorization_request: v_inner_at_request= ", v_inner_at_request);
// Secure InnerAtRequest message
if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("*** f_http_build_authorization_request: ERROR: Non canonical AA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
v_public_enc_key := 'DD4F6B0DF57C6E3BD0E32B565CACA1D858CEB08A5C2BBAB2C23E203C6DE697FF'O;
v_compressed_enc_key_mode := 0;
}
log("*** f_http_build_authorization_request: Public encryption key: ", v_public_enc_key);
log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode);
p_salt := vc_aaWholeHash;
log("*** f_http_build_authorization_request: p_salt: ", p_salt);
if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
} else { // Only encryption of EtsiTs102941Data/InnerAtRequest
log("*** f_http_build_authorization_request: POP signature not applied");
if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
}
log("*** f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
log("*** f_http_build_authorization_request: DEBUG: p_request_hash= ", p_request_hash);
} // End of function f_http_build_authorization_request
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
function f_http_build_authorization_request_with_wrong_private_key(
in Certificate p_ec_certificate, // Enrolment credentials certificate
in octetstring p_ec_private_key,
out octetstring p_private_key,
out octetstring p_public_key_compressed,
out integer p_compressed_key_mode,
out octetstring p_private_enc_key,
out octetstring p_public_compressed_enc_key,
out integer p_compressed_enc_key_mode,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out octetstring p_salt,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct32 p_request_hash
) runs on ItsPkiHttp {
// Local variables
var octetstring v_public_key_x;
var octetstring v_public_key_y;
var octetstring v_public_enc_key_x;
var octetstring v_public_enc_key_y;
var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode;
var InnerAtRequest v_inner_at_request;
var Ieee1609Dot2Data v_inner_at_request_data;
var InnerAtRequest v_authorization_request;
var bitstring v_authorization_request_msg;
// Generate the InnerAtRequest
if (f_generate_inner_at_request(vc_aaCertificate, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate AuthorizationValidationRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error);
return;
}
log("f_http_build_authorization_request_with_wrong_private_key: v_inner_at_request= ", v_inner_at_request);
// Secure InnerAtRequest message
/***
Use the wrong private key
***/
if (f_extract_enc_key(vc_eaCertificate/*Insted of vc_aaCertificate/*/, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Non canonical EA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
v_public_enc_key := 'DD4F6B0DF57C6E3BD0E32B565CACA1D858CEB08A5C2BBAB2C23E203C6DE697FF'O;
v_compressed_enc_key_mode := 0;
}
log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key: ", v_public_enc_key);
log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key comp: ", v_compressed_enc_key_mode);
p_salt := vc_aaWholeHash;
log("*** f_http_build_authorization_request_with_wrong_private_key: p_salt: ", p_salt);
if (PICS_PKI_AUTH_POP) {
if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
} else { // Only encryption of EtsiTs102941Data/InnerAtRequest
log("*** f_http_build_authorization_request_with_wrong_private_key: POP signature not applied");
if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
f_selfOrClientSyncAndVerdict("error", e_error);
}
}
log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_request_hash= ", p_request_hash);
} // End of function f_http_build_authorization_request_with_wrong_private_key
function f_http_build_authorization_response(
in InnerAtRequest p_inner_at_request,
in AuthorizationResponseCode p_responseCode := ok,
in Oct16 p_request_hash,
in octetstring p_private_key := ''O,
in octetstring p_digest := ''O,
in Oct16 p_aes_sym_key,
out InnerAtResponse p_inner_at_response,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
) return boolean {
// Local variables
var bitstring v_msg_bit;
var octetstring v_msg;
var Oct12 v_nonce;
var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
var EtsiTs103097Certificate v_at_certificate;
var boolean p_result := false;
log(">>> f_http_build_authorization_response: p_inner_at_request= ", p_inner_at_request);
log(">>> f_http_build_authorization_response: p_responseCode= ", p_responseCode);
log(">>> f_http_build_authorization_response: p_request_hash= ", p_request_hash);
log(">>> f_http_build_authorization_response: p_private_key= ", p_private_key);
log(">>> f_http_build_authorization_response: p_digest= ", p_digest);
log(">>> f_http_build_authorization_response: p_aes_sym_key= ", p_aes_sym_key);
// Check expectred response
p_request_hash,
p_responseCode
)
);
p_result := true;
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
// Generate the certificate
if (f_generate_at_certificate_for_inner_at_response(p_inner_at_request, p_private_key, p_digest, v_at_certificate) == false) {
log("f_http_build_inner_at_response: Failed to generate the certificate");
p_inner_at_response := valueof(
m_innerEcResponse_ko(
p_request_hash,
incompleterequest
)
);
} else {
p_inner_at_response := valueof(
m_innerEcResponse_ok(
p_request_hash,
v_at_certificate
)
);
}
}
// Secure the response
log("f_http_build_inner_at_response: p_inner_at_response= ", p_inner_at_response);
v_msg := bit2oct(encvalue(p_inner_at_response));
v_nonce := int2oct(f_getCurrentTime(), 32); // 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_at_response: Failed to generate the certificate");
p_inner_at_response := valueof(
m_innerEcResponse_ko(
p_request_hash,
deniedrequest
)
);
} else {
return p_result;
} // End of function f_http_build_authorization_request
in octetstring p_public_key_compressed,
in integer p_compressed_key_mode,
in octetstring p_private_enc_key,
in octetstring p_public_compressed_enc_key,
in integer p_compressed_enc_key_mode,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out octetstring p_salt,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct32 p_request_hash
) runs on ItsPkiHttp {
// Local variables
var AuthorizationValidationRequest v_authorization_validation_request;
var bitstring v_authorization_validation_request_msg;
var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode;
log(">>> f_http_build_authorization_validation_request");
// Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage
v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest;
// Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop
v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature;
if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("f_http_build_authorization_validation_request: Non canonical EA certificate");
f_selfOrClientSyncAndVerdict("error", e_error);
}
if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
v_public_enc_key := 'DD4F6B0DF57C6E3BD0E32B565CACA1D858CEB08A5C2BBAB2C23E203C6DE697FF'O;
v_compressed_enc_key_mode := 0;
}
log("f_http_build_authorization_validation_request: Public encryption key: ", v_public_enc_key);
log("f_http_build_authorization_validation_request: Public encryption key comp: ", v_compressed_enc_key_mode);
log("f_http_build_authorization_validation_request: p_salt: ", p_salt);
if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
log("f_http_build_authorization_validation_request: Failed to generate Authorization Request");
f_selfOrClientSyncAndVerdict("error", e_error);
log("f_http_build_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
log("f_http_build_authorization_validation_request: p_request_hash= ", p_request_hash);
} // End of function f_http_build_authorization_validation_request
} // End of group http
group generate_certificates {
function f_generate_ec_certificate(
out Certificate p_ec_certificate
) return boolean {
var octetstring v_public_key_x;
var octetstring v_public_key_y;
var octetstring p_public_key_compressed;
var integer p_compressed_mode;
var EccP256CurvePoint v_ecc_p256_curve_point;
var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
valueof(m_appPermissions(36, { bitmapSsp := '830001'O })),
valueof(m_appPermissions(37, { bitmapSsp := '830001'O }))
};
var template (value) EtsiTs103097Certificate v_cert;
var bitstring v_tbs;
var Oct32 v_sig;
var bitstring v_enc_msg;
var PublicVerificationKey v_public_verification_key;
log(">>> f_generate_ec_certificate");
// Generate verification keys for the certificate
if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) {
log("f_generate_ec_certificate: Failed to generate verification key");
return false;
}
if (p_compressed_mode == 0) {
v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
} else {
v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
}