Newer
Older
m_duration_years(1) // TODO Use PIXIT
{
m_identifiedRegion_country_only(12), // TODO Use PIXIT
m_identifiedRegion_country_only(34) // TODO Use PIXIT
}
),
log ("f_generate_inner_ec_request: ", p_inner_ec_request);
} // End of function f_generate_inner_ec_request
function f_generate_inner_ec_request_signed_for_pop(
in octetstring p_private_key,
in InnerEcRequest p_inner_ec_request,
out Ieee1609Dot2Data p_inner_ec_request_signed_for_pop
) return boolean {
// Local variables
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var octetstring v_encoded_inner_ec_request;
var template (value) ToBeSignedData v_tbs;
var octetstring v_tbs_signed;
var Signature v_signature;
// Encode it
v_encoded_inner_ec_request := bit2oct(encvalue(p_inner_ec_request));
// Signed the encoded InnerEcRequestSignedForPop
v_tbs := m_toBeSignedData(
m_signedDataPayload(
m_etsiTs103097Data_unsecured(
v_encoded_inner_ec_request
)
),
m_headerInfo_inner_ec_request(
c_its_aid_SCR,
f_getCurrentTimeUtc()
)
);
// Signed the encoded InnerEcRequestSignedForPop
v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
if (PX_VE_ALG == e_nist_p256) {
v_signature := valueof(
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
v_signature := valueof(
m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
v_signature := valueof(
m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_tbs_signed, 0, 48)
),
substr(v_tbs_signed, 48, 48)
)
)
);
}
log("f_generate_inner_ec_request_signed_for_pop: v_signature= ", v_signature);
p_inner_ec_request_signed_for_pop := valueof(
m_etsiTs103097Data_signed(
m_signedData(
sha256,
v_tbs,
m_signerIdentifier_self,
log("<<< f_generate_inner_ec_request_signed_for_pop: p_inner_ec_request_signed_for_pop= ", p_inner_ec_request_signed_for_pop);
return true;
} // End of function f_generate_inner_ec_request_signed_for_pop
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
function f_verify_inner_ec_request_signed_for_pop(
in EtsiTs102941Data p_etsi_ts_102941_data,
out InnerEcRequest p_inner_ec_request
) return boolean {
var bitstring v_msg_bit;
log(">>> f_verify_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data);
// 1. Decode content
v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
if (decvalue(v_msg_bit, p_inner_ec_request) != 0) {
log("f_verify_inner_ec_request_signed_for_pop: Failed to decode InnerEcRequest");
return false;
} else {
log("f_verify_inner_ec_request_signed_for_pop: v_inner_ec_request= ", p_inner_ec_request);
// 2. Verify the InnerEcRequestSignedForPop signature
}
return true;
} // End of function f_verify_inner_ec_request_signed_for_pop
function f_generate_inner_ec_response(
in octetstring p_inner_ec_request_hash,
in EtsiTs103097Certificate p_certificate,
out InnerEcResponse p_inner_ec_response
) return boolean {
// Local variables
// Build the Proof of Possession InnerEcResponse
p_inner_ec_response := valueof(
m_innerEcResponse_ok(
substr(p_inner_ec_request_hash, 0, 16),
p_certificate
)
);
return true;
} // End of function f_generate_inner_ec_response
group inner_at_xxx {
function f_generate_inner_at_request(
in Certificate p_ea_certificate,
in Oct8 p_ea_hashed_id8,
in Certificate p_ec_certificate,
in octetstring p_ec_private_key,
out octetstring p_private_key,
out octetstring p_public_key_compressed,
out integer p_compressed_key_mode,
out octetstring p_private_enc_key,
out octetstring p_public_compressed_enc_key,
out integer p_compressed_enc_key_mode,
out InnerAtRequest p_inner_at_request
) return boolean {
// Local variables
var octetstring v_public_key_x;
var octetstring v_public_key_y;
var octetstring v_public_enc_key_x;
var octetstring v_public_enc_key_y;
var bitstring v_enc_value;
var octetstring v_ec_hash;
var Oct8 v_ec_hashed_id8;
var octetstring public_enc_key_x;
var octetstring public_enc_key_y;
var Oct32 v_hmac_key;
var octetstring v_message_to_tag;
var Oct16 v_key_tag;
var octetstring v_hash_shared_at_request;
var template (value) ToBeSignedData v_tbs;
var octetstring v_tbs_signed;
var Ieee1609Dot2Data v_signed_at_signature;
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
var HashAlgorithm v_hashId;
var Signature v_signature;
// Generate verification keys for the certificate to be requested
if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) {
log("f_generate_inner_at_request: Failed to generate verification key");
return false;
}
log ("f_generate_inner_at_request: AT verification private key: ", p_private_key);
log ("f_generate_inner_at_request: AT verification public compressed key: ", p_public_key_compressed);
log ("f_generate_inner_at_request: AT verification public compressed mode: ", p_compressed_key_mode);
// Generate encryption keys for the certificate to be requested
if (PX_INCLUDE_ENCRYPTION_KEYS) {
if (f_generate_key_pair(p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) {
log("f_generate_inner_at_request: Failed to generate encryption key");
return false;
}
} else {
p_private_enc_key := ''O;
p_public_compressed_enc_key := ''O;
p_compressed_enc_key_mode := -1;
}
// Calculate the whole certificate SHA
v_enc_value := encvalue(p_ec_certificate);
if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) {
v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
v_ec_hashed_id8 := f_HashedId8FromSha256(v_ec_hash);
v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
v_ec_hashed_id8 := f_HashedId8FromSha384(v_ec_hash);
log("f_generate_inner_at_request: v_ec_hash= ", v_ec_hash);
// Generate 32 octets length secret key
v_hmac_key := f_hashWithSha256(int2oct(f_getCurrentTime(), 12));
log("f_generate_inner_at_request: v_hmac_key= ", v_hmac_key);
// Generate tag based on the concatenation of verification keys & encryption keys
v_message_to_tag := v_public_key_x & v_public_key_y & v_public_enc_key_x & v_public_enc_key_y;
log("f_generate_inner_at_request: v_message_to_tag= ", v_message_to_tag); // FIXME encryption keys could be optional
v_key_tag := fx_hmac_sha256(v_hmac_key, v_message_to_tag); // TODO Rename and use a wrapper function
log("f_generate_inner_at_request: v_key_tag= ", v_key_tag);
// Build the SharedAtRequest
p_inner_at_request.sharedAtRequest := valueof(
m_shared_at_request(
p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
substr(v_key_tag, 0, 16), // Calculated keyTag
valueof(
m_certificate_subject_attributes( // FIXME Review subjectPermissions
p_ec_certificate.toBeSigned.appPermissions,
p_ec_certificate.toBeSigned.certRequestPermissions,
p_ec_certificate.toBeSigned.id,
p_ec_certificate.toBeSigned.validityPeriod,
p_ec_certificate.toBeSigned.region,
p_ec_certificate.toBeSigned.assuranceLevel
))) // Desired attributes
);
// Calculate the hash of the SharedAtRequest
v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
log("f_generate_inner_at_request: v_hash_shared_at_request= ", v_hash_shared_at_request);
// Build the ETsiTs103097Data-SignedExternalPayload
m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
m_headerInfo_inner_ec_request( // HeaderInfo
c_its_aid_SCR,
f_getCurrentTimeUtc())
);
log("f_generate_inner_at_request: v_tbs= ", v_tbs);
// Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
// In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted
if (ischosen(p_ec_certificate.signature_.ecdsaBrainpoolP384r1Signature)) {
v_hashId := sha384;
v_tbs_signed := f_signWithEcdsaBrainpoolp384WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
v_signature := valueof(
m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_tbs_signed, 0, 48)
),
substr(v_tbs_signed, 48, 48)
)
)
);
} else {
v_hashId := sha256;
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
if (ischosen(p_ec_certificate.signature_.ecdsaBrainpoolP256r1Signature)) {
v_tbs_signed := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
v_signature := valueof(
m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else if (ischosen(p_ec_certificate.signature_.ecdsaNistP256Signature)) {
v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
v_signature := valueof(
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else {
// Error
log("f_generate_inner_at_request: Failed to process signature");
return false;
}
v_signed_at_signature := valueof(
m_etsiTs103097Data_signed(
m_signedData(
m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is thehasheId8 of the EC certificate obtained from Enrolment request
log("f_generate_inner_at_request: v_signed_at_signature= ", v_signed_at_signature);
if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
var octetstring v_public_enc_key;
var integer v_compressed_mode;
var Oct12 v_nonce;
var Oct16 v_authentication_vector;
var Oct16 v_encrypted_sym_key;
var HashedId8 v_recipientId;
var octetstring v_public_compressed_ephemeral_key;
var integer v_public_compressed_ephemeral_mode;
var octetstring v_enc_signed_ec_signature;
var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
// Use EA certificate for the encryption
if (PX_EC_ALG == e_nist_p256) {
if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
v_compressed_mode := 0;
} else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
v_compressed_mode := 1;
} else {
log("f_generate_inner_at_request: Wrong NistP256 encryption variant");
return false;
}
v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
} else {
log("f_generate_inner_at_request: Wrong encryption variant");
return false;
}
if (v_compressed_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_enc_key));
} else {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_enc_key));
}
log("f_generate_inner_at_request: v_eccP256_curve_point= ", v_eccP256_curve_point);
log("f_generate_inner_at_request: v_encrypted_sym_key= ", v_encrypted_sym_key);
log("f_generate_inner_at_request: v_authentication_vector= ", v_authentication_vector);
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesNistP256(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
v_encrypted_sym_key,
v_authentication_vector
)));
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
v_compressed_mode := 0;
} else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
v_compressed_mode := 1;
} else {
log("f_generate_inner_at_request: Wrong BrainpoolP256r1 encryption variant");
return false;
}
v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
} else {
log("f_generate_inner_at_request: Wrong encryption variant");
return false;
}
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
v_encrypted_sym_key,
v_authentication_vector
)));
log("f_generate_inner_at_request: Wrong encryption variant");
v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
log("v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
if (v_public_compressed_ephemeral_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
}
p_inner_at_request.ecSignature := valueof(
m_ec_signature(
m_etsiTs103097Data_encrypted(
m_encryptedData(
{
m_recipientInfo_signedDataRecipInfo(
m_pKRecipientInfo(
v_recipientId,
v_encrypted_data_encryption_key ))
},
m_SymmetricCiphertext_aes128ccm(
m_aesCcmCiphertext(
v_enc_signed_ec_signature
)
)
)
} else { // Skip the encryption, alowed to be re-identified by the AA
p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature));
// Build the InnerAtRequest, EcSignature field is already set
if (p_compressed_key_mode == 0) {
v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_key_x);
v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_key_x);
}
if (p_compressed_enc_key_mode == 0) {
v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
}
p_inner_at_request.publicKeys := valueof( // The freshly generated public keys to be used for the requested AT certificate
m_publicKeys(
m_publicVerificationKey_ecdsaNistP256(
v_eccP256_curve_point
),
m_encryptionKey( // FIXME Encryption keys could be optional
-,
m_publicEncryptionKey_ecdsaNistP256(v_enc_eccP256_curve_point)
)
)
);
p_inner_at_request.hmacKey := v_hmac_key;
log("p_inner_at_request= ", p_inner_at_request);
return true;
} // End of function f_generate_inner_at_request
function f_generate_inner_at_response(
in octetstring p_authorization_request_hash,
in EtsiTs103097Certificate p_certificate,
out InnerAtResponse p_authorization_response
) return boolean {
// Local variables
// Build the Proof of Possession InnerEcResponse
p_authorization_response := valueof(
substr(p_authorization_request_hash, 0, 16),
p_certificate
} // End of function f_generate_inner_at_response
} // End of group inner_at_xxx
group authorization_validation_xxx {
} // End of group authorization_validation_xxx
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
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
function f_await_http_inner_ec_request_response(
out Oct32 p_private_key,
out Oct32 p_compressed_public_key,
out integer p_compressed_mode,
out InnerEcResponse p_inner_ec_response
) runs on ItsPkiHttp return boolean {
var HeaderLines v_headers;
var Oct32 v_request_hash;
var Oct16 v_encrypted_sym_key;
var Oct16 v_aes_sym_key;
var Oct16 v_authentication_vector;
var Oct12 v_nonce;
var octetstring v_salt;
var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
var EtsiTs102941Data v_etsi_ts_102941_data;
var HttpMessage v_response;
log(">>> f_await_http_inner_ec_request_response");
f_http_build_inner_ec_request(p_private_key, p_compressed_public_key, p_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash);
f_init_default_headers_list(-, "inner_ec_request", v_headers);
f_http_send(
v_headers,
m_http_request(
m_http_request_post(
PICS_HTTP_POST_URI_EC,
v_headers,
m_http_message_body_binary(
m_binary_body_ieee1609dot2_data(
v_ieee1609dot2_signed_and_encrypted_data
)))));
[not(PICS_MULTIPLE_END_POINT)] httpPort.receive(
mw_http_response(
mw_http_response_ok(
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentResponseMessage(
mw_encryptedData(
-,
mw_SymmetricCiphertext_aes128ccm
))))))) -> value v_response {
if (f_verify_pki_response_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
} else {
log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***");
// Verify the received EC certificate
log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode)) {
log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
log("p_inner_ec_response= ", p_inner_ec_response);
return true;
} else {
log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
} else {
log("f_await_http_inner_ec_request_response: Unexpected message received ***");
}
}
}
[PICS_MULTIPLE_END_POINT] httpEcPort.receive(
mw_http_response(
mw_http_response_ok(
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentResponseMessage(
mw_encryptedData(
-,
mw_SymmetricCiphertext_aes128ccm
))))))) -> value v_response {
if (f_verify_pki_response_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
} else {
log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***");
// Verify the received EC certificate
log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode)) {
log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
log("p_inner_ec_response= ", p_inner_ec_response);
return true;
} else {
log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
return true; // For debug mode only
}
} else {
log("f_await_http_inner_ec_request_response: Unexpected message received ***");
}
}
}
[] tc_ac.timeout {
log("f_await_http_inner_ec_request_response: Expected message not received ***");
}
} // End of 'alt' statement
return false;
} // End of function f_await_http_inner_ec_request_response
} // End of group awaiting_messages
* @desc Build a signed and encrypted PKI request message
* @param p_private_key Private key for signature
* @param p_signer_identifier Signer identifier for signature, could be self or certificate HashedId8
* @param p_recipientId Recipient identifier to be inclued in encrypted layer.
* If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built
* @param p_public_key_compressed The public compressed key (canonical form) for encryption
* @param p_compressed_mode The compressed mode of the public compressed key (canonical form) for encryption
* @param p_pki_message The PKI message to be secured
* @param p_ieee1609dot2_signed_and_encrypted_data The secured message
* @return true on success, false otherwise
*/
function f_build_pki_secured_request_message_signed_with_pop(
in octetstring p_private_key,
in SignerIdentifier p_signer_identifier,
in HashedId8 p_recipientId,
in octetstring p_public_key_compressed,
in integer p_compressed_mode,
in octetstring p_salt,
in octetstring p_pki_message,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out Oct32 p_request_hash
) return boolean {
// Local variables
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var template (value) ToBeSignedData v_tbs;
var octetstring v_tbs_signed;
var Signature v_signature;
var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data;
var octetstring v_encoded_request;
var HashedId8 v_recipientId;
var octetstring v_public_compressed_ephemeral_key;
var integer v_public_compressed_ephemeral_mode;
var octetstring v_encrypted_request;
var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
log(">>> f_build_pki_secured_request_message_signed_with_pop");
// Signed the encoded PKI message
v_tbs := m_toBeSignedData(
m_signedDataPayload(
m_headerInfo_inner_ec_request(c_its_aid_SCR, f_getCurrentTimeUtc())
log("f_build_pki_secured_request_message_signed_with_pop: signer: ", p_signer_identifier);
if (ischosen(p_signer_identifier.self_)) {
v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
} else {
var charstring v_certificate_id;
var octetstring v_hash;
fx_readCertificateFromDigest(p_signer_identifier.digest, v_certificate_id); // TODO Add a wrapper function
f_getCertificateHash(v_certificate_id, v_hash);
v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), v_hash, p_private_key);
}
// Add the signature and create EtsiTs103097Data-Signed data structure
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
if (PX_VE_ALG == e_nist_p256) {
v_signature := valueof(
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
v_signature := valueof(
m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
v_signature := valueof(
m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_tbs_signed, 0, 48)
),
substr(v_tbs_signed, 48, 48)
)
)
);
}
log("f_build_pki_secured_request_message_signed_with_pop: v_signature= ", v_signature);
v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed(
m_signedData(
sha256,
v_tbs,
p_signer_identifier,
// Encode EtsiTs103097Data-Signed data structure
v_encoded_request := bit2oct(encvalue(v_ieee1609dot2_signed_data));
// Encrypt encode EtsiTs103097Data-Signed data structure
if (PICS_SEC_FIXED_KEYS) {
p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
}
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_request := f_encryptWithEciesNistp256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_encrypted_request := f_encryptWithEciesBrainpoolp256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else {
log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant");
return false;
}
log("f_build_pki_secured_request_message_signed_with_pop: p_aes_sym_key= ", p_aes_sym_key);
log("f_build_pki_secured_request_message_signed_with_pop: p_encrypted_sym_key= ", p_encrypted_sym_key);
log("f_build_pki_secured_request_message_signed_with_pop: p_authentication_vector= ", p_authentication_vector);
log("f_build_pki_secured_request_message_signed_with_pop: p_nonce= ", p_nonce);
log("f_build_pki_secured_request_message_signed_with_pop: p_recipientId= ", p_recipientId);
if (p_recipientId == int2oct(0, 8)) {
log("f_build_pki_secured_request_message_signed_with_pop: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
} else {
v_recipientId := p_recipientId;
}
log("f_build_pki_secured_request_message_signed_with_pop: v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
if (v_public_compressed_ephemeral_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
} else {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
}
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesNistP256(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
p_encrypted_sym_key,
p_authentication_vector
)));
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
p_encrypted_sym_key,
p_authentication_vector
)));
} else {
log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant");
return false;
}
p_ieee1609dot2_signed_and_encrypted_data := valueof(
m_etsiTs103097Data_encrypted(
m_encryptedData(
{
m_recipientInfo_certRecipInfo(
m_pKRecipientInfo(
v_recipientId,
v_encrypted_data_encryption_key
))
},
m_SymmetricCiphertext_aes128ccm(
m_aesCcmCiphertext(
p_nonce,
v_encrypted_request
)
)
// The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure
v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data);
if (PICS_SEC_FIXED_KEYS) {
p_request_hash := '10ED97A2F2933DD3AC55F47022D125E18F5E1AA024613E616A75BA4979EFE318'O;
} else {
p_request_hash := f_hashWithSha256(bit2oct(v_enc_value));
}
log("f_build_pki_secured_request_message_signed_with_pop: p_request_hash= ", p_request_hash);
log("<<< f_build_pki_secured_request_message_signed_with_pop: ", p_pki_message);
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
return true;
} // End of function f_build_pki_secured_request_message_signed_with_pop
/**
* @desc Build a signed and encrypted PKI request message without POP with signature
* @param p_recipientId Recipient identifier to be inclued in encrypted layer.
* If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built
* @param p_public_key_compressed The public compressed key (canonical form) for encryption
* @param p_compressed_mode The compressed mode of the public compressed key (canonical form) for encryption
* @param p_pki_message The PKI message to be secured
* @param p_ieee1609dot2_signed_and_encrypted_data The secured message
* @return true on success, false otherwise
*/
function f_build_pki_secured_request_message(
in HashedId8 p_recipientId,
in octetstring p_public_key_compressed,
in integer p_compressed_mode,
in octetstring p_salt,
in octetstring p_pki_message,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out Oct32 p_request_hash
) return boolean {
// Local variables
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var HashedId8 v_recipientId;
var octetstring v_public_compressed_ephemeral_key;
var integer v_public_compressed_ephemeral_mode;
var octetstring v_encrypted_request;
var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
log(">>> f_build_pki_secured_request_message");
// Encrypt encode EtsiTs103097Data-Signed data structure
p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_request := f_encryptWithEciesNistp256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_encrypted_request := f_encryptWithEciesBrainpoolp256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else {
log("f_build_pki_secured_request_message: Wrong encryption variant");
return false;
}
log("f_build_pki_secured_request_message: p_aes_sym_key= ", p_aes_sym_key);
log("f_build_pki_secured_request_message: p_encrypted_sym_key= ", p_encrypted_sym_key);
log("f_build_pki_secured_request_message: p_authentication_vector= ", p_authentication_vector);
log("f_build_pki_secured_request_message: p_nonce= ", p_nonce);
log("f_build_pki_secured_request_message: p_recipientId= ", p_recipientId);
if (p_recipientId == int2oct(0, 8)) {
log("f_build_pki_secured_request_message: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
} else {
v_recipientId := p_recipientId;
}
log("f_build_pki_secured_request_message: v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
if (v_public_compressed_ephemeral_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesNistP256(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
p_encrypted_sym_key,
p_authentication_vector
)));
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
p_encrypted_sym_key,
p_authentication_vector
)));
}
p_ieee1609dot2_signed_and_encrypted_data := valueof(
m_etsiTs103097Data_encrypted(
m_encryptedData(
{
m_recipientInfo_certRecipInfo(
m_pKRecipientInfo(
v_recipientId,
v_encrypted_data_encryption_key
))
m_SymmetricCiphertext_aes128ccm(
m_aesCcmCiphertext(
v_encrypted_request
// The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure
v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data);
if (PICS_SEC_FIXED_KEYS) {
p_request_hash := '10ED97A2F2933DD3AC55F47022D125E18F5E1AA024613E616A75BA4979EFE318'O;
} else {
p_request_hash := f_hashWithSha256(bit2oct(v_enc_value));
}
log("f_build_pki_secured_request_message: p_request_hash= ", p_request_hash);
log("<<< f_build_pki_secured_request_message: ", p_ieee1609dot2_signed_and_encrypted_data);
} // End of function f_build_pki_secured_request_message
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
function f_build_pki_secured_request_message_for_authorization(
in HashedId8 p_recipientId,
in octetstring p_public_key_compressed,
in integer p_compressed_mode,
in octetstring p_salt,
in octetstring p_pki_message,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
out Oct32 p_request_hash
) return boolean {
// Local variables
var Ieee1609Dot2Data v_unsecured_data;
var octetstring v_pki_message;
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var HashedId8 v_recipientId;
var octetstring v_public_compressed_ephemeral_key;
var integer v_public_compressed_ephemeral_mode;
var octetstring v_encrypted_request;
var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
var bitstring v_enc_value;
log(">>> f_build_pki_secured_request_message");
// Add Ieee1609Dot2Data layer
v_unsecured_data := valueof(m_etsiTs103097Data_unsecured(p_pki_message));
v_pki_message := bit2oct(encvalue(v_unsecured_data));
// Encrypt encode EtsiTs103097Data-Signed data structure
if (PICS_SEC_FIXED_KEYS) {
p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
}
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_request := f_encryptWithEciesNistp256WithSha256(v_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else if (PX_EC_ALG == e_brainpool_p256_r1) {
v_encrypted_request := f_encryptWithEciesBrainpoolp256WithSha256(v_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
} else {
log("f_build_pki_secured_request_message: Wrong encryption variant");
return false;
}
log("f_build_pki_secured_request_message: p_aes_sym_key= ", p_aes_sym_key);
log("f_build_pki_secured_request_message: p_encrypted_sym_key= ", p_encrypted_sym_key);
log("f_build_pki_secured_request_message: p_authentication_vector= ", p_authentication_vector);
log("f_build_pki_secured_request_message: p_nonce= ", p_nonce);
log("f_build_pki_secured_request_message: p_recipientId= ", p_recipientId);
if (p_recipientId == int2oct(0, 8)) {
log("f_build_pki_secured_request_message: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
} else {
v_recipientId := p_recipientId;
}
log("f_build_pki_secured_request_message: v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
if (v_public_compressed_ephemeral_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
} else {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
}
if (PX_EC_ALG == e_nist_p256) {
v_encrypted_data_encryption_key := valueof(
m_encryptedDataEncryptionKey_eciesNistP256(
m_evciesP256EncryptedKey(
v_eccP256_curve_point,
p_encrypted_sym_key,
p_authentication_vector
)));