Newer
Older
v_public_verification_key := valueof(
m_publicVerificationKey_ecdsaNistP256(
v_ecc_p256_curve_point
));
} else if (PX_EC_ALG_FOR_EC == e_brainpool_p256_r1) {
v_public_verification_key := valueof(
m_publicVerificationKey_ecdsaBrainpoolP256r1(
v_ecc_p256_curve_point
));
} else {
log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
v_cert := m_etsiTs103097Certificate(
m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(f_hashWithSha256('616263'O))),
m_toBeSignedCertificate_at(
v_appPermissions,
m_verificationKeyIndicator_verificationKey(
v_public_verification_key
),
),
m_geographicRegion_identifiedRegion(
{
m_identifiedRegion_country_only(12),
m_identifiedRegion_country_only(34)
}
)
)
);
// Encode it ==> Get octetstring
v_tbs := encvalue(v_cert.toBeSigned);
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
// Sign the certificate
v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key);
if ((PX_VE_ALG == e_nist_p256) or (PX_VE_ALG == e_brainpool_p256_r1)) {
v_cert.signature_ := m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_sig, 0, 48)
),
substr(v_sig, 48, 48)
)
);
}
log("f_generate_ec_certificate: v_cert= ", v_cert);
p_ec_certificate := valueof(v_cert);
return true;
} // End of function f_generate_ec_certificate
function f_generate_ec_certificate_for_inner_ec_response(
in InnerEcRequest p_inner_ec_request,
in octetstring p_private_key,
in octetstring p_digest,
out EtsiTs103097Certificate p_ec_certificate
) return boolean {
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
var EtsiTs103097Certificate v_cert;
var IssuerIdentifier v_issuer;
var bitstring v_tbs;
var octetstring v_sig;
log(">>> f_generate_ec_certificate_for_inner_ec_response");
v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_HashedId8FromSha384
v_cert := valueof(
m_etsiTs103097Certificate(
v_issuer,
m_toBeSignedCertificate_ec(
p_inner_ec_request.requestedSubjectAttributes.id,
p_inner_ec_request.requestedSubjectAttributes.appPermissions,
m_verificationKeyIndicator_verificationKey(
p_inner_ec_request.publicKeys.verificationKey
),
p_inner_ec_request.requestedSubjectAttributes.validityPeriod,
p_inner_ec_request.requestedSubjectAttributes.region,
p_inner_ec_request.requestedSubjectAttributes.assuranceLevel,
p_inner_ec_request.publicKeys.encryptionKey
)
)
);
// Encode it ==> Get octetstring
v_tbs := encvalue(v_cert.toBeSigned);
// Sign the certificate
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
if (PX_VE_ALG == e_nist_p256) {
v_cert.signature_ := valueof(
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
v_cert.signature_ := valueof(
m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
)
);
v_cert.signature_ := valueof(
m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_sig, 0, 48)
),
substr(v_sig, 48, 48)
)
)
);
p_ec_certificate := valueof(v_cert);
log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate= ", p_ec_certificate);
return true;
} // End of function f_generate_ec_certificate_for_inner_ec_response
function f_generate_at_certificate(
in octetstring p_private_key,
in InnerEcRequest p_inner_ec_request,
out Certificate p_at_certificate
) return boolean {
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;
v_public_verification_key := valueof(
m_publicVerificationKey_ecdsaNistP256(
p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256
));
} else if (PX_EC_ALG_FOR_AT == e_brainpool_p256_r1) {
v_public_verification_key := valueof(
m_publicVerificationKey_ecdsaBrainpoolP256r1(
p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1
));
} else {
// Error
log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
v_cert := m_etsiTs103097Certificate(
m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(f_hashWithSha256('616263'O))),
m_toBeSignedCertificate_at(
v_appPermissions,
m_verificationKeyIndicator_verificationKey(
v_public_verification_key
),
),
m_geographicRegion_identifiedRegion(
{
m_identifiedRegion_country_only(12),
m_identifiedRegion_country_only(34)
}
)
)
);
// Encode it ==> Get octetstring
v_tbs := encvalue(v_cert.toBeSigned);
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
// Sign the certificate
v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key);
if ((PX_VE_ALG == e_nist_p256) or (PX_VE_ALG == e_brainpool_p256_r1)) {
v_cert.signature_ := m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_sig, 0, 48)
),
substr(v_sig, 48, 48)
)
);
}
log("v_cert= ", v_cert);
p_at_certificate := valueof(v_cert);
return true;
} // End of function f_generate_at_certificate
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
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
function f_generate_at_certificate_for_authorization_response(
in InnerAtRequest p_inner_at_request,
in octetstring p_private_key,
in octetstring p_digest,
out EtsiTs103097Certificate p_at_certificate
) return boolean {
var EtsiTs103097Certificate v_cert;
var IssuerIdentifier v_issuer;
var bitstring v_tbs;
var octetstring v_sig;
log(">>> f_generate_at_certificate_for_authorization_response");
/*v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_HashedId8FromSha384
v_cert := valueof(
m_etsiTs103097Certificate(
v_issuer,
m_toBeSignedCertificate_ec(
p_inner_at_request.requestedSubjectAttributes.id,
p_inner_at_request.requestedSubjectAttributes.appPermissions,
m_verificationKeyIndicator_verificationKey(
p_inner_at_request.publicKeys.verificationKey
),
p_inner_at_request.requestedSubjectAttributes.validityPeriod,
p_inner_at_request.requestedSubjectAttributes.region,
p_inner_at_request.requestedSubjectAttributes.assuranceLevel,
p_inner_at_request.publicKeys.encryptionKey
)
)
);
// Encode it ==> Get octetstring
v_tbs := encvalue(v_cert.toBeSigned);
// Sign the certificate
v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
if (PX_VE_ALG == e_nist_p256) {
v_cert.signature_ := valueof(
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
v_cert.signature_ := valueof(
m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_sig, 0, 32)
),
substr(v_sig, 32, 32)
)
)
);
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
v_cert.signature_ := valueof(
m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(
substr(v_sig, 0, 48)
),
substr(v_sig, 48, 48)
)
)
);
}
p_at_certificate := valueof(v_cert);*/
log("f_generate_at_certificate_for_authorization_response: p_at_certificate= ", p_at_certificate);
return true;
} // End of function f_generate_at_certificate_for_authorization_response
} // End of group generate_certificates
out octetstring p_private_key,
out octetstring p_public_key_compressed,
out integer p_compressed_mode,
out InnerEcRequest p_inner_ec_request
) return boolean {
var EccP256CurvePoint v_eccP256_curve_point;
log (">>> f_generate_inner_ec_request");
// Generate keys for the certificate to be requested
if (f_generate_key_pair(p_private_key, v_publicKeyX, v_publicKeyY, p_public_key_compressed, p_compressed_mode) == false) {
log ("f_generate_inner_ec_request: failed to generate keys");
if (p_compressed_mode == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
// Build the Proof of Possession InnerEcRequest
p_inner_ec_request := valueof(
m_innerEcRequest(
m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)
),
m_certificateSubjectAttributes(
{ // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := '01C0'O }))
omit/*YANN TO restore m_geographicRegion_identifiedRegion(
{
m_identifiedRegion_country_only(12), // TODO Use PIXIT
m_identifiedRegion_country_only(34) // TODO Use PIXIT
}
if (PICS_SECPKI_REENROLMENT) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential
log("f_generate_inner_ec_request: This is a re-enrolment");
p_inner_ec_request.itsId := PX_EC_HASHED_ID8;
}
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
)
),
);
// Signed the encoded InnerEcRequestSignedForPop
v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
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
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_aa_certificate,
in Oct8 p_aa_hashed_id8,
in Certificate p_ea_certificate,
in octetstring p_salt,
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 PublicVerificationKey v_verification_tag;
var PublicEncryptionKey v_encryption_tag;
var octetstring v_encoded_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;
var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := '01FFFC'O })),
valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := '01FFFFFF'O })) // TODO Use PIXIT
// 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_for_encryption(PX_EC_ALG_FOR_AT, 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 {
log ("f_generate_inner_at_request: AT encryption private key: ", p_private_enc_key);
log ("f_generate_inner_at_request: AT encryption public compressed key: ", p_public_compressed_enc_key);
log ("f_generate_inner_at_request: AT encryption public compressed mode: ", p_compressed_enc_key_mode);
v_public_enc_key_x := ''O;
v_public_enc_key_y := ''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_getCurrentTimeUtc() * 1000), 12));
log("f_generate_inner_at_request: v_hmac_key= ", v_hmac_key);
// Generate tag based on the concatenation of verification keys & encryption keys
if (PX_VE_ALG == e_nist_p256) {
if (p_compressed_key_mode == 0) {
v_verification_tag.ecdsaNistP256.compressed_y_0 := p_public_key_compressed;
} else {
v_verification_tag.ecdsaNistP256.compressed_y_1 := p_public_key_compressed;
}
} else if (PX_VE_ALG == e_brainpool_p256_r1) {
if (p_compressed_key_mode == 0) {
v_verification_tag.ecdsaBrainpoolP256r1.compressed_y_0 := p_public_key_compressed;
} else {
v_verification_tag.ecdsaBrainpoolP256r1.compressed_y_1 := p_public_key_compressed;
}
} else if (PX_VE_ALG == e_brainpool_p384_r1) {
if (p_compressed_key_mode == 0) {
v_verification_tag.ecdsaBrainpoolP384r1.compressed_y_0 := p_public_key_compressed;
} else {
v_verification_tag.ecdsaBrainpoolP384r1.compressed_y_1 := p_public_key_compressed;
}
log("f_generate_inner_at_request: Failed to generate HMAC tag");
return false;
log("f_generate_inner_at_request: v_verification_tag= ", v_verification_tag);
v_encoded_tag := bit2oct(encvalue(v_verification_tag));
v_encryption_tag.supportedSymmAlg := aes128Ccm;
if (PX_EC_ALG_FOR_AT == e_nist_p256) {
if (p_compressed_enc_key_mode == 0) {
v_encryption_tag.publicKey.eciesNistP256.compressed_y_0 := p_public_compressed_enc_key;
} else {
v_encryption_tag.publicKey.eciesNistP256.compressed_y_1 := p_public_compressed_enc_key;
}
} else if (PX_EC_ALG_FOR_AT == e_brainpool_p256_r1) {
if (p_compressed_enc_key_mode == 0) {
v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_0 := p_public_compressed_enc_key;
} else {
v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_1 := p_public_compressed_enc_key;
}
log("f_generate_inner_at_request: Failed to generate HMAC tag (enc)");
return false;
log("f_generate_inner_at_request: v_encryption_tag= ", v_encryption_tag);
v_encoded_tag := v_encoded_tag & bit2oct(encvalue(v_encryption_tag));
log("f_generate_inner_at_request: v_encoded_tag= ", v_encoded_tag);
v_key_tag := substr(
fx_hmac_sha256( // TODO Rename and use a wrapper function
v_hmac_key,
),
0,
16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
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
m_certificate_subject_attributes( // FIXME Review fsubjectPermissions
v_appPermissions,//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,/*m_geographicRegion_identifiedRegion(
{
m_identifiedRegion_country_only(250),
m_identifiedRegion_country_only(380)
}
)
,*/
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_pki_request( // HeaderInfo
-,
(f_getCurrentTime()) * 1000) //us
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
// TODO Simplify with f_signWithEcdsa
if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
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;
if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
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.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
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 (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;
} 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, p_salt, 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);
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));
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_FOR_AT == 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;
} 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_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, 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);
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));
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");
log("f_generate_inner_at_request: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key);
v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
log("f_generate_inner_at_request: v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
p_inner_at_request.ecSignature := valueof(
m_ec_signature(
m_etsiTs103097Data_encrypted(
m_encryptedData(
{
m_recipientInfo_certRecipInfo(
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);
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
if (PX_INCLUDE_ENCRYPTION_KEYS) {
p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition 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)
)
)
);
} else {
p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate
m_publicKeys(
m_publicVerificationKey_ecdsaNistP256(
v_eccP256_curve_point
)
)
);
}
p_inner_at_request.hmacKey := v_hmac_key;
log("f_generate_inner_at_request: p_inner_at_request= ", p_inner_at_request);
return true;
} // End of function f_generate_inner_at_request
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
function f_verify_inner_at_request_signed_for_pop(
in EtsiTs102941Data p_etsi_ts_102941_data,
out InnerAtRequest p_inner_at_request
) return boolean {
var bitstring v_msg_bit;
log(">>> f_verify_inner_at_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_at_request) != 0) {
log("f_verify_inner_at_request_signed_for_pop: Failed to decode InnerEcRequest");
return false;
} else {
log("f_verify_inner_at_request_signed_for_pop: v_inner_at_request= ", p_inner_at_request);
// 2. Verify the InnerEcRequestSignedForPop signature
// TODO
}
return true;
} // End of function f_verify_inner_at_request_signed_for_pop
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
group awaiting_messages {
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,
in boolean p_strict_checks := true
) 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: p_strict_checks=", p_strict_checks);
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
)))));
[] a_await_ec_http_request_from_iut(
mw_http_response(
mw_http_response_ok(
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentResponseMessage(
mw_encryptedData(
-,
mw_SymmetricCiphertext_aes128ccm
)))))),
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, p_strict_checks, v_etsi_ts_102941_data) == false) {
log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
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)))) == false) {
log("f_await_http_inner_ec_request_response: Unexpected message received ***");
if (p_strict_checks) {
return false;
}
}
if (ispresent(v_etsi_ts_102941_data.content.enrolmentResponse) and ispresent(v_etsi_ts_102941_data.content.enrolmentResponse.certificate)) {
if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode) == false) {
log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
if (p_strict_checks) {
return false;
p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
log("p_inner_ec_response= ", p_inner_ec_response);
} else {
log("f_await_http_inner_ec_request_response: Invalid message received ***");
return false;
}
[] tc_ac.timeout {
log("f_await_http_inner_ec_request_response: Expected message not received ***");
}
} // End of 'alt' statement
} // End of function f_await_http_inner_ec_request_response
function f_await_ec_request_send_response(
out InnerEcResponse p_inner_ec_response
) runs on ItsPkiHttp return boolean {
var HttpMessage v_request;
var boolean v_result := false;
log(">>> f_await_ec_request_send_response");
tc_ac.start;
alt {
[] a_await_ec_http_request_from_iut(
mw_http_request(
mw_http_request_post(
PICS_HTTP_POST_URI_EC,
-,
mw_http_message_body_binary(
mw_binary_body_ieee1609dot2_data(
mw_enrolmentRequestMessage(
mw_encryptedData(
-,
mw_SymmetricCiphertext_aes128ccm
)))))),
v_request
) {
var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;