Commits (1)
...@@ -44,17 +44,55 @@ module LibItsHttp_Functions { ...@@ -44,17 +44,55 @@ module LibItsHttp_Functions {
group http_headers { group http_headers {
function f_init_default_headers_list( function f_init_default_headers_list(
in charstring p_header_content_type := PICS_HEADER_CONTENT_TYPE,
in charstring p_header_content_text := "",
out HeaderLines p_headers out HeaderLines p_headers
) { ) {
p_headers[0] := { c_header_host, { PICS_HEADER_HOST } }; var integer v_i := 0;
p_headers[1] := { c_header_content_type, { PICS_HEADER_CONTENT_TYPE } };
p_headers[2] := { c_header_content_length, { "0" } }; p_headers[v_i] := { c_header_host, { PICS_HEADER_HOST } };
p_headers[3] := { c_header_connection, { "keep-alive" } }; v_i := v_i + 1;
p_headers[4] := { c_header_pragma, { "no-cache" } }; p_headers[v_i] := { c_header_content_type, { p_header_content_type } };
p_headers[5] := { c_header_cache_control, { "no-cache" } }; v_i := v_i + 1;
if (p_header_content_text != "") {
p_headers[v_i] := { c_header_content_text, { p_header_content_text } };
v_i := v_i + 1;
}
p_headers[v_i] := { c_header_content_length, { "0" } };
v_i := v_i + 1;
p_headers[v_i] := { c_header_connection, { "keep-alive" } };
v_i := v_i + 1;
p_headers[v_i] := { c_header_pragma, { "no-cache" } };
v_i := v_i + 1;
p_headers[v_i] := { c_header_cache_control, { "no-cache" } };
} // End of function f_init_default_headers_list } // End of function f_init_default_headers_list
function f_set_headears_list(
in charstring_list p_headers_to_set,
in charstring_list p_headers_value,
inout HeaderLines p_headers
) {
// Sanity checks
if (lengthof(p_headers_to_set) == 0) {
return;
} else if (lengthof(p_headers) == 0) {
return;
}
for (var integer v_idx := 0; v_idx < lengthof(p_headers_to_set); v_idx := v_idx + 1) {
var integer v_jdx;
for (v_jdx := 0; v_jdx < lengthof(p_headers); v_jdx := v_jdx + 1) {
if (p_headers[v_jdx].header_name == p_headers_to_set[v_idx]) {
p_headers[v_jdx].header_value := p_headers_value; // NOTE Codec won't encode it
break;
}
if (v_jdx == lengthof(p_headers)) {
p_headers[v_jdx].header_value := p_headers_value;
}
} // End of 'for' statement
} // End of 'for' statement
} // End of function f_set_headears_list
function f_remove_headears_list( function f_remove_headears_list(
in charstring_list p_headers_to_remove, in charstring_list p_headers_to_remove,
inout HeaderLines p_headers inout HeaderLines p_headers
...@@ -67,15 +105,14 @@ module LibItsHttp_Functions { ...@@ -67,15 +105,14 @@ module LibItsHttp_Functions {
} }
for (var integer v_idx := 0; v_idx < lengthof(p_headers_to_remove); v_idx := v_idx + 1) { for (var integer v_idx := 0; v_idx < lengthof(p_headers_to_remove); v_idx := v_idx + 1) {
for (var integer v_jdx := 0; v_jdx < lengthof(p_headers); v_jdx := v_jdx + 1) { for (var integer v_jdx := 0; v_jdx < lengthof(p_headers); v_jdx := v_jdx + 1) {
if (p_headers[v_jdx].header_name == p_headers_to_remove[v_idx]) { if (p_headers[v_jdx].header_name == p_headers_to_remove[v_idx]) {
p_headers[v_jdx].header_value := omit; // NOTE Codec won't encode it p_headers[v_jdx].header_value := omit; // NOTE Codec won't encode it
break;
} }
} // End of 'for' statement } // End of 'for' statement
} // End of 'for' statement } // End of 'for' statement
} // End of function f_init_default_headers_list } // End of function f_remove_headears_list
} // End of group http_headers } // End of group http_headers
......
...@@ -17,6 +17,7 @@ module LibItsHttp_TypesAndValues { ...@@ -17,6 +17,7 @@ module LibItsHttp_TypesAndValues {
const charstring c_header_host := "Host"; const charstring c_header_host := "Host";
const charstring c_header_content_type := "Content-type"; const charstring c_header_content_type := "Content-type";
const charstring c_header_content_text := "Content-text";
const charstring c_header_content_length := "Content-length"; const charstring c_header_content_length := "Content-length";
const charstring c_header_accept := "Accept"; const charstring c_header_accept := "Accept";
const charstring c_header_connection := "Connection"; const charstring c_header_connection := "Connection";
......
...@@ -67,25 +67,31 @@ module LibItsPki_Functions { ...@@ -67,25 +67,31 @@ module LibItsPki_Functions {
*/ */
function f_cfHttpUp( function f_cfHttpUp(
in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant in charstring p_ea_certificate_id := "CERT_TS_A_EA", // TODO Use a constant
in charstring p_ec_certificate_id := "CERT_TS_A_EC", in charstring p_aa_certificate_id := "CERT_TS_A_AA"
in charstring p_peerCertificateId := "CERT_IUT_A_EA"
) runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ { ) runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ {
map(self:httpPort, system:httpPort); map(self:httpPort, system:httpPort);
f_connect4SelfOrClientSync(); f_connect4SelfOrClientSync();
f_initialiseSecuredMode(p_ea_certificate_id, p_peerCertificateId); 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_readCertificate(p_ea_certificate_id, vc_eaCertificate);
f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // f_readSigningKey(p_ea_certificate_id, vc_eaPrivateKey); // TODO To be removed
f_readCertificate(p_ec_certificate_id, vc_ecCertificate); // f_readCertificate(p_aa_certificate_id, vc_ecCertificate); // TODO To be removed
f_readSigningKey(p_ec_certificate_id, vc_ecPrivateKey); // f_readSigningKey(p_aa_certificate_id, vc_ecPrivateKey); // TODO To be removed
f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); // f_readEncryptingKey(p_ea_certificate_id, vc_eaPrivateEncKey); // TODO To be removed
f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8); f_getCertificateDigest(p_ea_certificate_id, vc_eaHashedId8);
f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash); f_getCertificateHash(p_ea_certificate_id, vc_eaWholeHash);
f_getCertificateDigest(p_ec_certificate_id, vc_ecHashedId8);
f_readCertificate(p_peerCertificateId, vc_peerEaCertificate); // Setup AA certificate shared with PKI AA entity
f_getCertificateHash(p_peerCertificateId, vc_eaPeerWholeHash); f_readCertificate(p_aa_certificate_id, vc_aaCertificate);
f_getCertificateDigest(p_aa_certificate_id, vc_aaHashedId8);
f_getCertificateHash(p_aa_certificate_id, vc_aaWholeHash);
log("vc_aaHashedId8= ", vc_aaHashedId8);
log("vc_aaWholeHash= ", vc_aaWholeHash);
// f_readCertificate(p_peerCertificateId, vc_peerEaCertificate); // TODO To be removed
// f_getCertificateHash(p_peerCertificateId, vc_eaPeerWholeHash); // TODO To be removed
activate(a_default_pki_http()); activate(a_default_pki_http());
} // End of function f_cfHttpUp } // End of function f_cfHttpUp
...@@ -132,13 +138,13 @@ module LibItsPki_Functions { ...@@ -132,13 +138,13 @@ module LibItsPki_Functions {
// Local variables // Local variables
// Load certificates // Load certificates
if( not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { if(not(f_loadCertificates(PX_IUT_SEC_CONFIG_NAME))) {
log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***");
setverdict(inconc); setverdict(inconc);
stop; stop;
} }
f_prepareCertificates(p_certificateId, vc_aaCertificate, vc_atCertificate); // f_prepareCertificates(p_certificateId, vc_aaCertificate, vc_atCertificate);
} // End of function f_initialiseSecuredMode() } // End of function f_initialiseSecuredMode()
function f_uninitialiseSecuredMode() runs on ItsSecurityBaseComponent { function f_uninitialiseSecuredMode() runs on ItsSecurityBaseComponent {
...@@ -220,7 +226,7 @@ module LibItsPki_Functions { ...@@ -220,7 +226,7 @@ module LibItsPki_Functions {
} // End of group ut_port } // End of group ut_port
group http { group http { // TODO Split into EinnerEc, Authorization & AuthorizationValidation
function f_http_build_inner_ec_request( // TODO Cleanup parameters function f_http_build_inner_ec_request( // TODO Cleanup parameters
out octetstring p_private_key, out octetstring p_private_key,
...@@ -256,14 +262,22 @@ module LibItsPki_Functions { ...@@ -256,14 +262,22 @@ module LibItsPki_Functions {
log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***"); log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error); 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: ", v_public_enc_key);
log("*** f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode); log("*** f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode);
log("*** f_http_build_inner_ec_request: First enrolment: ", PX_FIRST_ENROLMENT); log("*** f_http_build_inner_ec_request: First enrolment: ", PX_FIRST_ENROLMENT);
p_salt := vc_eaWholeHash; p_salt := vc_eaWholeHash;
if (PX_FIRST_ENROLMENT == true) { // This is the first enrolment, we used Factory keys if (PX_FIRST_ENROLMENT == true) { // This is the first enrolment, we used Factory keys
v_ret_code := f_build_pki_secured_message(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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); v_ret_code := f_build_pki_secured_request_message(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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
} else { // We use last valid EC certificate } else { // We use last valid EC certificate
v_ret_code := f_build_pki_secured_message(vc_ecPrivateKey, valueof(m_signerIdentifier_digest(vc_ecHashedId8)), 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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); var Oct32 v_ec_private_key;
var HashedId8 v_ec_hashed_id8;
// Retrieve EC certificate from the first enrolment
// TODO Set v_ec_private_key & v_ec_hashed_id8
v_ret_code := f_build_pki_secured_request_message(v_ec_private_key, valueof(m_signerIdentifier_digest(v_ec_hashed_id8)), v_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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
} }
if (v_ret_code == false) { if (v_ret_code == false) {
log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
...@@ -300,8 +314,13 @@ module LibItsPki_Functions { ...@@ -300,8 +314,13 @@ module LibItsPki_Functions {
log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
} }
log("v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop); log("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 // Secure InnerEcRequestSignedForPoP message
if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
...@@ -312,57 +331,98 @@ module LibItsPki_Functions { ...@@ -312,57 +331,98 @@ module LibItsPki_Functions {
log("*** f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode); log("*** f_http_build_inner_ec_request: Public encryption key comp: ", v_compressed_enc_key_mode);
p_salt := vc_eaWholeHash; p_salt := vc_eaWholeHash;
if (PX_FIRST_ENROLMENT == true) { // This is the first enrolment, we used Factory keys if (PX_FIRST_ENROLMENT == true) { // This is the first enrolment, we used Factory keys
v_ret_code := f_build_pki_secured_message(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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); v_ret_code := f_build_pki_secured_request_message(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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
} else { // We use last valid EC certificate } else { // We use last valid EC certificate
v_ret_code := f_build_pki_secured_message(vc_ecPrivateKey, valueof(m_signerIdentifier_digest(vc_ecHashedId8)), 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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash); var Oct32 v_ec_private_key;
var HashedId8 v_ec_hashed_id8;
// Retrieve EC certificate from the first enrolment
// TODO Set v_ec_private_key & v_ec_hashed_id8
v_ret_code := f_build_pki_secured_request_message(v_ec_private_key, valueof(m_signerIdentifier_digest(v_ec_hashed_id8)), v_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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
} }
if (v_ret_code == false) { if (v_ret_code == false) {
log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
return;
} }
log("*** f_http_build_invalid_enrolment_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data); 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 } // End of function f_http_build_invalid_enrolment_request
function f_http_build_inner_at_request( 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_key,
out octetstring p_publicKeyCompressed, out octetstring p_publicKeyCompressed,
out integer p_compressedMode, out integer p_compressedMode,
out octetstring p_private_enc_key,
out octetstring p_publicEncKeyCompressed,
out integer p_compressedEncMode,
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 Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
out Oct32 p_request_hash out Oct32 p_request_hash
) runs on ItsPkiHttp { ) runs on ItsPkiHttp {
// Local variables // Local variables
// Local variables var octetstring v_public_key_x;
var InnerAtRequest v_authorization_request; var octetstring v_public_key_y;
var bitstring v_authorization_request_msg; var octetstring v_public_enc_key_x;
var octetstring v_public_enc_key_y;
var octetstring v_public_enc_key; var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode; 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 verification keys for the certificate to be requested
if (f_generate_key_pair_nistp256(p_private_key, v_public_key_x, v_public_key_y, p_publicKeyCompressed, p_compressedMode) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate verification key ***");
f_selfOrClientSyncAndVerdict("error", e_error);
return;
}
// Generate encryption keys for the certificate to be requested
if (PX_INCLUDE_ENCRYPTION_KEYS) {
if (f_generate_key_pair_nistp256(p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_publicEncKeyCompressed, p_compressedEncMode) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate encryption key ***");
f_selfOrClientSyncAndVerdict("error", e_error);
return;
}
}
if (f_generate_authorization_request(vc_eaCertificate, vc_eaHashedId8, p_private_key, p_publicKeyCompressed, p_compressedMode, v_authorization_request) == false) { if (f_generate_inner_at_request(vc_eaCertificate, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, v_public_key_x, v_public_key_y, p_compressedMode, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_compressedEncMode, v_inner_at_request) == false) {
log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationValidationRequest ***"); log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationValidationRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
return;
} }
// Secure the Pki message log("v_inner_at_request= ", v_inner_at_request);
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 ***"); if (PX_AUTHORIZATION_REQUEST_WITH_POP) {
// TODO Set Ieee1609Dot2Data p_inner_at_request_data
} // else TODO Check what to do
// Secure InnerAtRequest message
if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
log("*** f_http_build_inner_ec_request: ERROR: Non canonical AA certificate ***");
f_selfOrClientSyncAndVerdict("error", e_error); 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: ", v_public_enc_key);
log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode); log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode);
log("*** f_http_build_authorization_request: First enrolment: ", PX_FIRST_ENROLMENT);
p_salt := vc_aaWholeHash;
/** log("*** f_http_build_authorization_request: p_salt: ", p_salt);
TODO: Load certificate according to the IUT role if(f_build_pki_secured_request_message(PICS_ITS_S_SIGN_NITSP256_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))), p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
==> a complete fucntion which set up the TestSustem certificate,keyy... according to the IUT role log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
**/
log("*** f_http_build_inner_ec_request: ERROR: Need to add TestSystem variable vc_aa ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
/* if (f_build_pki_secured_message(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/\*recipientId*\/, v_public_enc_key, v_compressed_enc_key_mode, vc_eaWholeHash, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_authorization_request))), p_ieee1609dot2_signed_and_encrypted_data, p_request_hash) == false) { */ }
/* log("*** f_http_build_authorization_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); */ log("*** f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
/* f_selfOrClientSyncAndVerdict("error", e_error); */ log("*** f_http_build_authorization_request: DEBUG: p_request_hash= ", p_request_hash);
/* } */ } // End of function f_http_build_authorization_request
log("*** f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data);
} // End of function f_http_build_inner_at_request
function f_http_build_authorization_validation_request( function f_http_build_authorization_validation_request(
out octetstring p_private_key, out octetstring p_private_key,
...@@ -376,10 +436,10 @@ module LibItsPki_Functions { ...@@ -376,10 +436,10 @@ module LibItsPki_Functions {
var octetstring v_public_enc_key; var octetstring v_public_enc_key;
var integer v_compressed_enc_key_mode; var integer v_compressed_enc_key_mode;
if (f_generate_authorization_validation_request(vc_eaCertificate, vc_eaHashedId8, p_private_key, p_publicKeyCompressed, p_compressedMode, v_authorization_validation_request) == false) { /* TODO if (f_generate_authorization_validation_request(vc_eaCertificate, vc_eaHashedId8, p_private_key, p_publicKeyCompressed, p_compressedMode, v_authorization_validation_request) == false) {
log("*** f_http_build_authorization_validation_request: ERROR: Failed to generate AuthorizationValidationRequest ***"); log("*** f_http_build_authorization_validation_request: ERROR: Failed to generate AuthorizationValidationRequest ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
} }*/
// Secure the Pki message // Secure the Pki message
if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) { 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 ***"); log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***");
...@@ -395,7 +455,7 @@ module LibItsPki_Functions { ...@@ -395,7 +455,7 @@ module LibItsPki_Functions {
**/ **/
log("*** f_http_build_inner_ec_request: ERROR: Need to add TestSystem variable vc_aa ***"); log("*** f_http_build_inner_ec_request: ERROR: Need to add TestSystem variable vc_aa ***");
f_selfOrClientSyncAndVerdict("error", e_error); f_selfOrClientSyncAndVerdict("error", e_error);
/* if (f_build_pki_secured_message(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/\*recipientId*\/, v_public_enc_key, v_compressed_enc_key_mode, vc_eaWholeHash, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), p_ieee1609dot2_signed_and_encrypted_data, p_request_hash) == false) { */ /* if (f_build_pki_secured_request_message(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/\*recipientId*\/, v_public_enc_key, v_compressed_enc_key_mode, vc_eaWholeHash, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), p_ieee1609dot2_signed_and_encrypted_data, p_request_hash) == false) { */
/* log("*** f_http_build_authorization_validation_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); */ /* log("*** f_http_build_authorization_validation_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***"); */
/* f_selfOrClientSyncAndVerdict("error", e_error); */ /* f_selfOrClientSyncAndVerdict("error", e_error); */
/* } */ /* } */
...@@ -639,89 +699,63 @@ module LibItsPki_Functions { ...@@ -639,89 +699,63 @@ module LibItsPki_Functions {
group inner_at_xxx { group inner_at_xxx {
function f_generate_inner_at_request( function f_generate_inner_at_request(
in Certificate p_ea_certificate,
in Oct8 p_ea_hashed_id8,
in Certificate p_ec_certificate, in Certificate p_ec_certificate,
in octetstring p_ec_private_key,
in octetstring p_private_key, in octetstring p_private_key,
in Certificate p_ea_certificate, in octetstring p_public_key_x,
in HashedId8 p_eaHashedId8, in octetstring p_public_key_y,
in boolean p_itss_privacy, in integer p_compressed_key_mode,
out octetstring p_private_enc_key, in octetstring p_private_enc_key,
out octetstring p_publicEncKeyCompressed, in octetstring p_public_enc_key_x,
out integer p_compressedMode, in octetstring p_public_enc_key_y,
out InnerAtRequest p_inner_at_request, in integer p_compressed_enc_key_mode,
out Ieee1609Dot2Data p_inner_at_request_data out InnerAtRequest p_inner_at_request
) return boolean { ) return boolean {
// Local variables // Local variables
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_x;
var octetstring public_enc_key_y; var octetstring public_enc_key_y;
var template (value) EccP256CurvePoint v_eccP256_curve_point;
var Oct32 v_hmac_key; var Oct32 v_hmac_key;
var octetstring v_message_to_tag; var octetstring v_message_to_tag;
var Oct16 v_key_tag; var Oct16 v_key_tag;
var octetstring v_whole_certificate_hash;
var octetstring v_hash_shared_at_request; var octetstring v_hash_shared_at_request;
var template (value) ToBeSignedData v_tbs; var template (value) ToBeSignedData v_tbs;
var octetstring v_tbs_signed; var octetstring v_tbs_signed;
var Ieee1609Dot2Data v_signed_ec_signature; var Ieee1609Dot2Data v_signed_ec_signature;
var template (value) EccP256CurvePoint v_eccP256_curve_point;
// Generate encryption keys for the certificate to be requested var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
if (f_generate_key_pair_nistp256(p_private_enc_key, public_enc_key_x, public_enc_key_y, p_publicEncKeyCompressed, p_compressedMode) == false) { var HashAlgorithm v_hashId;
return false;
} // Calculate the whole certificate SHA
if (p_compressedMode == 0) { v_enc_value := encvalue(p_ec_certificate);
v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(p_publicEncKeyCompressed); 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);
} else { } else {
v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(p_publicEncKeyCompressed); v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
v_ec_hashed_id8 := f_HashedId8FromSha384(v_ec_hash);
} }
log("v_ec_hash= ", v_ec_hash);
// Generate 32 octets length secret key // Generate 32 octets length secret key
v_hmac_key := f_hashWithSha256(int2oct(f_getCurrentTime(), 12)); v_hmac_key := f_hashWithSha256(int2oct(f_getCurrentTime(), 12));
log("v_hmac_key=", v_hmac_key); log("v_hmac_key= ", v_hmac_key);
// Generate tag based on the concatenation of ??? // Generate tag based on the concatenation of verification keys & encryption keys
if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey)) { v_message_to_tag := p_public_key_x & p_public_key_y & p_public_enc_key_x & p_public_enc_key_y;
if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) { log("v_message_to_tag= ", v_message_to_tag); // FIXME encryption keys could be optional
if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) {
v_message_to_tag := '02'O & p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0;
} else {
v_message_to_tag := '03'O & p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1;
}
} else {
// TODO
/* if (ischosen(p_ec_certificate.verifyKeyIndicator.ecdsaBrainpoolP256.compressed_y_0)) { */
/* v_message_to_tag := '02'O & p_ec_certificate.verifyKeyIndicator.ecdsaBrainpoolP256.compressed_y_0; */
/* } else { */
/* v_message_to_tag := '03'O & p_ec_certificate.verifyKeyIndicator.ecdsaBrainpoolP256.compressed_y_1; */
/* } */
}
} else {
return false;
}
if (p_compressedMode == 0) {
v_message_to_tag := v_message_to_tag & '02'O & p_publicEncKeyCompressed;
} else {
v_message_to_tag := v_message_to_tag & '03'O & p_publicEncKeyCompressed;
}
log("v_message_to_tag=", v_message_to_tag);
v_key_tag := fx_hmac_sha256(v_hmac_key, v_message_to_tag); // TODO Rename and use a wrapper function v_key_tag := fx_hmac_sha256(v_hmac_key, v_message_to_tag); // TODO Rename and use a wrapper function
log("v_key_tag=", v_key_tag); log("v_key_tag= ", v_key_tag);
// Build the SharedAtRequest // Build the SharedAtRequest
p_inner_at_request.publicKeys := valueof(
m_publicKeys(
m_publicVerificationKey_ecdsaNistP256(
p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256
),
m_encryptionKey(
-,
m_publicEncryptionKey_ecdsaNistP256(v_eccP256_curve_point)
)
)
);
p_inner_at_request.hmacKey := v_hmac_key;
p_inner_at_request.sharedAtRequest := valueof( p_inner_at_request.sharedAtRequest := valueof(
m_shared_at_request( m_shared_at_request(
p_eaHashedId8, p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
v_key_tag, substr(v_key_tag, 0, 16), // Calculated keyTag
valueof( valueof(
m_certificate_subject_attributes( // FIXME Review subjectPermissions m_certificate_subject_attributes( // FIXME Review subjectPermissions
p_ec_certificate.toBeSigned.appPermissions, p_ec_certificate.toBeSigned.appPermissions,
...@@ -730,31 +764,34 @@ module LibItsPki_Functions { ...@@ -730,31 +764,34 @@ module LibItsPki_Functions {
p_ec_certificate.toBeSigned.validityPeriod, p_ec_certificate.toBeSigned.validityPeriod,
p_ec_certificate.toBeSigned.region, p_ec_certificate.toBeSigned.region,
p_ec_certificate.toBeSigned.assuranceLevel 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))); v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
log("v_hash_shared_at_request=", v_hash_shared_at_request); log("v_hash_shared_at_request= ", v_hash_shared_at_request);
// Build the ToBeSigned payload
// Build the ETsiTs103097Data-SignedExternalPayload
v_tbs := m_toBeSignedData( v_tbs := m_toBeSignedData(
m_signedDataPayload_ext(v_hash_shared_at_request), m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
m_headerInfo_inner_ec_request( m_headerInfo_inner_ec_request( // HeaderInfo
c_its_aid_SCR, c_its_aid_SCR,
f_getCurrentTimeUtc()) f_getCurrentTimeUtc())
); );
log("v_tbs=", v_tbs); log("v_tbs= ", v_tbs);
// Signed ToBeSigned payload // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
v_whole_certificate_hash := f_hashWithSha256(bit2oct(encvalue(p_ec_certificate))); v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
log("v_whole_certificate_hash=", v_whole_certificate_hash); // In case of ITS-S privacy, v_signed_ec_signature contained the data to be encrypted
v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_whole_certificate_hash, p_private_key); if (ischosen(p_ec_certificate.signature_.ecdsaBrainpoolP384r1Signature)) {
v_hashId := sha384;
} else {
v_hashId := sha256;
}
v_signed_ec_signature := valueof( v_signed_ec_signature := valueof(
m_etsiTs103097Data_signed( m_etsiTs103097Data_signed(
m_signedData( m_signedData(
sha256, v_hashId,
v_tbs, v_tbs,
m_signerIdentifier_digest( m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is thehasheId8 of the EC certificate obtained from Enrolment request
f_HashedId8FromSha256(
v_whole_certificate_hash
)
),
m_signature_ecdsaNistP256( m_signature_ecdsaNistP256(
m_ecdsaP256Signature( m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only( m_eccP256CurvePoint_x_only(
...@@ -766,8 +803,9 @@ module LibItsPki_Functions { ...@@ -766,8 +803,9 @@ module LibItsPki_Functions {
) )
) )
); );
// Encrypt EcSignature with EA certificate log("v_signed_ec_signature= ", v_signed_ec_signature);
if (p_itss_privacy) {
if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
var octetstring v_public_enc_key; var octetstring v_public_enc_key;
var integer v_compressed_mode; var integer v_compressed_mode;
var Oct12 v_nonce; var Oct12 v_nonce;
...@@ -779,6 +817,7 @@ module LibItsPki_Functions { ...@@ -779,6 +817,7 @@ module LibItsPki_Functions {
var integer v_ephemeralKeyModeCompressed; var integer v_ephemeralKeyModeCompressed;
var octetstring v_enc_signed_ec_signature; var octetstring v_enc_signed_ec_signature;
// Use EA certificate for the encryption
if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { 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_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
v_compressed_mode := 0; v_compressed_mode := 0;
...@@ -788,9 +827,9 @@ module LibItsPki_Functions { ...@@ -788,9 +827,9 @@ module LibItsPki_Functions {
} else { } else {
return false; return false;
} }
v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce); v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
v_recipientId := p_eaHashedId8; v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
log("v_recipientId=", v_recipientId); log("v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form) // Fill Certificate template with the public compressed keys (canonical form)
if (v_ephemeralKeyModeCompressed == 0) { if (v_ephemeralKeyModeCompressed == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed)); v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed));
...@@ -822,150 +861,69 @@ module LibItsPki_Functions { ...@@ -822,150 +861,69 @@ module LibItsPki_Functions {
) )
) )
); );
} else { } 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_ec_signature)); p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_ec_signature));
} }
log("p_inner_at_request=", p_inner_at_request); // Build the InnerAtRequest, EcSignature field is already set
if (p_compressed_key_mode == 0) {
return true; v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(p_public_key_x);
} // End of function f_generate_inner_at_request } else {
v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(p_public_key_x);
function f_generate_inner_at_response(
in Certificate p_ec_certificate,
in octetstring p_private_key,
in HashedId8 p_eaHashedId8,
out octetstring p_private_enc_key,
out octetstring p_publicEncKeyX,
out octetstring p_publicEncKeyY,
out octetstring p_publicEncKeyCompressed,
out integer p_compressedMode,
out InnerAtRequest p_inner_at_request,
out Ieee1609Dot2Data p_inner_at_request_data
) return boolean {
// Local variables
return false;
} // End of function f_generate_inner_at_response
} // End of group inner_at_xxx
group authorization_xxx {
function f_generate_authorization_request(
in Certificate p_ea_certificate,
in HashedId8 p_ea_certificate_hashed_id8,
out octetstring p_private_key,
out octetstring p_publicKeyCompressed,
out integer p_compressedMode,
out InnerAtRequest p_authorization_request
) return boolean {
// Local variables
var octetstring v_private_enc_key;
var Oct32 v_publicEncKeyCompressed;
var integer v_compressedMode;
var InnerEcRequest v_inner_ec_request;
var Certificate v_ec_certificate;
var InnerAtRequest v_inner_at_request;
var Ieee1609Dot2Data v_inner_at_request_data;
if (f_generate_inner_ec_request(p_private_key, p_publicKeyCompressed, p_compressedMode, v_inner_ec_request) == false) {
return false;
}
if (f_generate_ec_certificate(p_private_key, v_inner_ec_request, v_ec_certificate) == false) {
return false;
} }
if (f_generate_inner_at_request(v_ec_certificate, p_private_key, p_ea_certificate, p_ea_certificate_hashed_id8, true, v_private_enc_key, v_publicEncKeyCompressed, v_compressedMode, v_inner_at_request, v_inner_at_request_data) == false) { if (p_compressed_enc_key_mode == 0) {
return false; v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(p_public_enc_key_x);
} else {
v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(p_public_enc_key_x);
} }
p_inner_at_request.publicKeys := valueof( // The freshly generated public keys to be used for the requested AT certificate
p_authorization_request.sharedAtRequest := v_inner_at_request.sharedAtRequest; m_publicKeys(
p_authorization_request.ecSignature := v_inner_at_request.ecSignature; m_publicVerificationKey_ecdsaNistP256(
v_eccP256_curve_point
log("f_generate_authorization_request: ", p_authorization_request); ),
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; return true;
} // End of function f_generate_authorization_request } // End of function f_generate_inner_at_request
function f_generate_authorization_response( function f_generate_inner_at_response(
in octetstring p_authorization_request_hash, in octetstring p_authorization_request_hash,
in CertificateSubjectAttributes p_Certificate_subject_attributes, in EtsiTs103097Certificate p_certificate,
out InnerAtResponse p_authorization_response out InnerAtResponse p_authorization_response
) return boolean { ) return boolean {
// Local variables // Local variables
// Build the Proof of Possession InnerAtResponse // Build the Proof of Possession InnerEcResponse
/*p_authorization_response := valueof( p_authorization_response := valueof(
m_innerAtResponse_ok( m_innerAtResponse_ok(
p_authorization_request_hash, substr(p_authorization_request_hash, 0, 16),
p_Certificate_subject_attributes p_certificate
) )
);*/ );
return true; return true;
} // End of function f_generate_authorization_response } // End of function f_generate_inner_at_response
} // End of group authorization_xxx
group authorization_validation_xxx {
function f_generate_authorization_validation_request(
in Certificate p_ea_certificate,
in HashedId8 p_ea_certificate_hashed_id8,
out octetstring p_private_key,
out octetstring p_publicKeyCompressed,
out integer p_compressedMode,
out AuthorizationValidationRequest p_authorization_validation_request
) return boolean {
// Local variables
var octetstring v_private_enc_key;
var Oct32 v_publicEncKeyCompressed;
var integer v_compressedMode;
var InnerEcRequest v_inner_ec_request;
var Certificate v_ec_certificate;
var InnerAtRequest v_inner_at_request;
var Ieee1609Dot2Data v_inner_at_request_data;
if (f_generate_inner_ec_request(p_private_key, p_publicKeyCompressed, p_compressedMode, v_inner_ec_request) == false) {
return false;
}
if (f_generate_ec_certificate(p_private_key, v_inner_ec_request, v_ec_certificate) == false) {
return false;
}
if (f_generate_inner_at_request(v_ec_certificate, p_private_key, p_ea_certificate, p_ea_certificate_hashed_id8, true, v_private_enc_key, v_publicEncKeyCompressed, v_compressedMode, v_inner_at_request, v_inner_at_request_data) == false) {
return false;
}
p_authorization_validation_request.sharedAtRequest := v_inner_at_request.sharedAtRequest;
p_authorization_validation_request.ecSignature := v_inner_at_request.ecSignature;
log("f_generate_authorization_validation_request: ", p_authorization_validation_request);
return true; } // End of group inner_at_xxx
} // End of function f_generate_authorization_validation_request
function f_generate_authorization_validation_response( group authorization_xxx {
in octetstring p_authorization_validation_request_hash,
in CertificateSubjectAttributes p_Certificate_subject_attributes,
out AuthorizationValidationResponse p_authorization_validation_response
) return boolean {
// Local variables
// Build the Proof of Possession InnerEcResponse } // End of group authorization_xxx
p_authorization_validation_response := valueof(
m_authorizationValidationResponse_ok(
substr(p_authorization_validation_request_hash, 0, 16),
p_Certificate_subject_attributes
)
);
return true; group authorization_validation_xxx {
} // End of function f_generate_authorization_validation_response
} // End of group authorization_validation_xxx } // End of group authorization_validation_xxx
group pki_functions { group pki_functions {
/** /**
* @desc Build a signed and encrypted PKI message * @desc Build a signed and encrypted PKI request message
* @param p_private_key Private key for signature * @param p_private_key Private key for signature
* @param p_signer_identifier Signer identifier for signature, could be self or certificate HashedId8 * @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. * @param p_recipientId Recipient identifier to be inclued in encrypted layer.
...@@ -976,7 +934,7 @@ module LibItsPki_Functions { ...@@ -976,7 +934,7 @@ module LibItsPki_Functions {
* @param p_ieee1609dot2_signed_and_encrypted_data The secured message * @param p_ieee1609dot2_signed_and_encrypted_data The secured message
* @return true on success, false otherwise * @return true on success, false otherwise
*/ */
function f_build_pki_secured_message( function f_build_pki_secured_request_message(
in octetstring p_private_key, in octetstring p_private_key,
in SignerIdentifier p_signer_identifier, in SignerIdentifier p_signer_identifier,
in HashedId8 p_recipientId, in HashedId8 p_recipientId,
...@@ -1037,27 +995,29 @@ module LibItsPki_Functions { ...@@ -1037,27 +995,29 @@ module LibItsPki_Functions {
// Encode EtsiTs103097Data-Signed data structure // Encode EtsiTs103097Data-Signed data structure
v_encoded_inner_ec_request := bit2oct(encvalue(v_ieee1609dot2_signed_data)); v_encoded_inner_ec_request := bit2oct(encvalue(v_ieee1609dot2_signed_data));
// Calculate the SHA256 of v_encoded_inner_ec_request // Calculate the SHA256 of v_encoded_inner_ec_request
if (PICS_SEC_FIXED_KEYS) {
p_request_hash := '10ED97A2F2933DD3AC55F47022D125E18F5E1AA024613E616A75BA4979EFE318'O;
} else {
p_request_hash := f_hashWithSha256(v_encoded_inner_ec_request); p_request_hash := f_hashWithSha256(v_encoded_inner_ec_request);
log("p_request_hash= ", p_request_hash); log("p_request_hash= ", p_request_hash);
}
// Encrypt encode EtsiTs103097Data-Signed data structure // Encrypt encode EtsiTs103097Data-Signed data structure
if (PICS_SEC_FIXED_KEYS) { if (PICS_SEC_FIXED_KEYS) {
p_publicKeyCompressed := '8C5E20FE31935F6FA682A1F6D46E4468534FFEA1A698B14B0B12513EED8DEB11'O; p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
p_compressedMode := 0;
p_salt := '9169155B08B07674CBADF75FB46A7B0D'O;
} }
v_encrypted_inner_ec_request := f_encryptWithEciesNistp256WithSha256(v_encoded_inner_ec_request, p_publicKeyCompressed, p_compressedMode, p_salt, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS); v_encrypted_inner_ec_request := f_encryptWithEciesNistp256WithSha256(v_encoded_inner_ec_request, p_publicKeyCompressed, p_compressedMode, p_salt, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
log("p_aes_sym_key=", p_aes_sym_key); log("p_aes_sym_key= ", p_aes_sym_key);
log("p_encrypted_sym_key=", p_encrypted_sym_key); log("p_encrypted_sym_key= ", p_encrypted_sym_key);
log("p_authentication_vector=", p_authentication_vector); log("p_authentication_vector= ", p_authentication_vector);
log("p_nonce=", p_nonce); log("p_nonce= ", p_nonce);
log("p_recipientId=", p_recipientId); log("p_recipientId= ", p_recipientId);
if (p_recipientId == int2oct(0, 8)) { if (p_recipientId == int2oct(0, 8)) {
log("f_hashWithSha256(v_encrypted_sym_key)=", f_hashWithSha256(p_encrypted_sym_key)); log("f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key)); v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
} else { } else {
v_recipientId := p_recipientId; v_recipientId := p_recipientId;
} }
log("v_recipientId=", v_recipientId); log("v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form) // Fill Certificate template with the public compressed keys (canonical form)
if (v_ephemeralKeyModeCompressed == 0) { if (v_ephemeralKeyModeCompressed == 0) {
v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed)); v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed));
...@@ -1089,7 +1049,94 @@ module LibItsPki_Functions { ...@@ -1089,7 +1049,94 @@ module LibItsPki_Functions {
); );
return true; return true;
} // End of function f_build_pki_secured_message } // End of function f_build_pki_secured_request_message
/**
* @desc Build a signed and encrypted PKI response 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_publicKeyCompressed The public compressed key (canonical form) for encryption
* @param p_compressedMode 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_response_message(
in octetstring p_private_key,
in SignerIdentifier p_signer_identifier,
in octetstring p_pki_message,
in Oct16 p_aes_sym_key,
in Oct12 p_nonce,
out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
) return boolean {
// Local variables
var template (value) ToBeSignedData v_tbs;
var octetstring v_tbs_signed;
var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data;
var octetstring v_encoded_inner_ec_response;
var HashedId8 v_recipientId;
var octetstring v_encrypted_inner_ec_response;
// Signed the encoded PKI message
v_tbs := m_toBeSignedData(
m_signedDataPayload(
m_etsiTs103097Data_unsecured(p_pki_message)
),
m_headerInfo_inner_ec_response(c_its_aid_SCR, f_getCurrentTimeUtc())
);
if (ischosen(p_signer_identifier.self_)) {
v_tbs_signed := f_signWithEcdsaNistp256WithSha256(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_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_hash, p_private_key);
}
// Add the signature and create EtsiTs103097Data-Signed data structure
v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed(
m_signedData(
sha256,
v_tbs,
p_signer_identifier,
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(
substr(v_tbs_signed, 0, 32)
),
substr(v_tbs_signed, 32, 32)
)
)
)
);
// Encode EtsiTs103097Data-Signed data structure
v_encoded_inner_ec_response := bit2oct(encvalue(v_ieee1609dot2_signed_data));
v_encrypted_inner_ec_response := fx_encrypt_aes_128_ccm_test(p_aes_sym_key, p_nonce, v_encoded_inner_ec_response);
v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_aes_sym_key));
log("v_recipientId= ", v_recipientId);
// Fill Certificate template with the public compressed keys (canonical form)
p_ieee1609dot2_signed_and_encrypted_data := valueof(
m_etsiTs103097Data_encrypted(
m_encryptedData(
{
m_recipientInfo_pskRecipInfo(
v_recipientId
)
},
m_SymmetricCiphertext_aes128ccm(
m_aesCcmCiphertext(
p_nonce,
v_encrypted_inner_ec_response
)
)
)
)
);
return true;
} // End of function f_build_pki_secured_response_message
/** /**
* @desc Verify the protocol element of the Pki message. * @desc Verify the protocol element of the Pki message.
...@@ -1125,9 +1172,9 @@ module LibItsPki_Functions { ...@@ -1125,9 +1172,9 @@ module LibItsPki_Functions {
var boolean v_ret; var boolean v_ret;
log(">>> f_verify_pki_message: p_private_enc_key= ", p_private_enc_key); log(">>> f_verify_pki_message: p_private_enc_key= ", p_private_enc_key);
log(">>> f_verify_pki_message: p_aes_sym_key=", p_aes_sym_key); log(">>> f_verify_pki_message: p_aes_sym_key= ", p_aes_sym_key);
log(">>> f_verify_pki_message: p_authentication_vector=", p_authentication_vector); log(">>> f_verify_pki_message: p_authentication_vector= ", p_authentication_vector);
log(">>> f_verify_pki_message: p_issuer=", p_issuer); log(">>> f_verify_pki_message: p_issuer= ", p_issuer);
// TODO Check p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.recipients[0].pskRecipInfo. See IEEE Std 1609.2-2017 Clause 6.3.34 PreSharedKeyRecipientInfo // TODO Check p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.recipients[0].pskRecipInfo. See IEEE Std 1609.2-2017 Clause 6.3.34 PreSharedKeyRecipientInfo
...@@ -1262,6 +1309,8 @@ module LibItsPki_Functions { ...@@ -1262,6 +1309,8 @@ module LibItsPki_Functions {
out octetstring p_public_enc_key, out octetstring p_public_enc_key,
out integer p_compressed_enc_key_mode out integer p_compressed_enc_key_mode
) return boolean { ) return boolean {
log(">>> f_extract_enc_key: ", p_certificate);
if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256)) { if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256)) {
if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) { if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0; p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
...@@ -1270,7 +1319,7 @@ module LibItsPki_Functions { ...@@ -1270,7 +1319,7 @@ module LibItsPki_Functions {
p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1; p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
p_compressed_enc_key_mode := 1; p_compressed_enc_key_mode := 1;
} else { } else {
log("f_extract_enc_key: Non canonical EA certificate"); log("f_extract_enc_key: Non canonical certificate: ", p_certificate);
return false; return false;
} }
} else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1)) { } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1)) {
...@@ -1281,11 +1330,11 @@ module LibItsPki_Functions { ...@@ -1281,11 +1330,11 @@ module LibItsPki_Functions {
p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1; p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
p_compressed_enc_key_mode := 0; p_compressed_enc_key_mode := 0;
} else { } else {
log("f_extract_enc_key: Non canonical EA certificate"); log("f_extract_enc_key: Non canonical certificate: ", p_certificate);
return false; return false;
} }
} else { } else {
log("f_extract_enc_key: Invalid EA certificate"); log("f_extract_enc_key: Invalid certificate: ", p_certificate);
return false; return false;
} }
......
...@@ -48,12 +48,17 @@ module LibItsPki_Pics { ...@@ -48,12 +48,17 @@ module LibItsPki_Pics {
/** /**
* @desc Certificate used by the Test System acting as AA * @desc Certificate used by the Test System acting as AA
*/ */
modulepar charstring PICS_TS_AA_CERTIFICATE_ID := "CERT_TS_A_EA"; modulepar charstring PICS_TS_AA_CERTIFICATE_ID := "CERT_AA";
/** /**
* @desc Certificate used by the Test System * @desc Certificate used by the Test System
*/ */
modulepar charstring PICS_HTTP_GET_URI := "/its/inner_ec_request"; modulepar charstring PICS_HTTP_POST_URI := "/its/inner_ec_request";
/**
* @desc ITS-S with privacy
*/
modulepar boolean PICS_ITS_S_WITH_PRIVACY := true;
/** /**
* @desc Factory private key for verification Nist P256 * @desc Factory private key for verification Nist P256
......
module LibItsPki_Pixits { module LibItsPki_Pixits {
/**
* @desc Is the first enrolment?
*/
modulepar boolean PX_FIRST_ENROLMENT := true; modulepar boolean PX_FIRST_ENROLMENT := true;
/**
* @desc Do the encryption keys be included in Authorization Request?
*/
modulepar boolean PX_INCLUDE_ENCRYPTION_KEYS := true;
/**
* @desc Do the Authorization Request use SignedWithPop mechanism?
*/
modulepar boolean PX_AUTHORIZATION_REQUEST_WITH_POP := true;
} // End of module LibItsPki_Pixits } // End of module LibItsPki_Pixits
...@@ -55,23 +55,23 @@ module LibItsPki_Templates { ...@@ -55,23 +55,23 @@ module LibItsPki_Templates {
} }
} // End of template m_etsiTs102941Data_inner_ec_response } // End of template m_etsiTs102941Data_inner_ec_response
template (value) EtsiTs102941Data m_etsiTs102941Data_inner_at_request( template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_request(
in template (value) InnerAtRequest p_inner_at_request in template (value) InnerAtRequest p_inner_at_request
) := { ) := {
version := PkiProtocolVersion, version := PkiProtocolVersion,
content := { content := {
authorizationRequest := p_inner_at_request authorizationRequest := p_inner_at_request
} }
} // End of template m_etsiTs102941Data_inner_at_request } // End of template m_etsiTs102941Data_authorization_request
template (value) EtsiTs102941Data m_etsiTs102941Data_inner_at_response( template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_response(
in template (value) InnerAtResponse p_inner_at_response in template (value) InnerAtResponse p_inner_at_response
) := { ) := {
version := PkiProtocolVersion, version := PkiProtocolVersion,
content := { content := {
authorizationResponse := p_inner_at_response authorizationResponse := p_inner_at_response
} }
} // End of template m_etsiTs102941Data_inner_at_response } // End of template m_etsiTs102941Data_authorization_response
template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_validation_request( template (value) EtsiTs102941Data m_etsiTs102941Data_authorization_validation_request(
in template (value) AuthorizationValidationRequest p_authorization_validation_request in template (value) AuthorizationValidationRequest p_authorization_validation_request
......
...@@ -67,14 +67,16 @@ module LibItsPki_TestSystem { ...@@ -67,14 +67,16 @@ module LibItsPki_TestSystem {
type component ItsPkiHttp extends ItsSecurityBaseComponent, HttpComponent { type component ItsPkiHttp extends ItsSecurityBaseComponent, HttpComponent {
var Certificate vc_eaCertificate; /** Test Adapter EA certificate */ var Certificate vc_eaCertificate; /** Test Adapter EA certificate */
var octetstring vc_eaPrivateKey; /** Test Adapter EA private key for signature */ var octetstring vc_eaPrivateKey; /** Test Adapter EA private key for signature */
var Certificate vc_ecCertificate; /** Test Adapter EC certificate */ // var Certificate vc_ecCertificate; /** Test Adapter AA certificate */
var octetstring vc_ecPrivateKey; /** Test Adapter EC private key for signature */ // var octetstring vc_ecPrivateKey; /** Test Adapter AA private key for signature */
var octetstring vc_eaPrivateEncKey; /** Test Adapter EA private key for encryption */ var octetstring vc_eaPrivateEncKey; /** Test Adapter EA private key for encryption */
var HashedId8 vc_eaHashedId8; /** Test Adapter EA HashedId8 for decryption of IUT's response */ var HashedId8 vc_eaHashedId8; /** Test Adapter EA HashedId8 for decryption of IUT's response */
var octetstring vc_eaWholeHash; /** TS EA whole-hash for signature check */ var octetstring vc_eaWholeHash; /** TS EA whole-hash for signature check */
var HashedId8 vc_ecHashedId8; /** Test Adapter EC HashedId8 for decryption of IUT's response */ var HashedId8 vc_aaHashedId8; /** Test Adapter AA HashedId8 for decryption of IUT's response */
var Certificate vc_peerEaCertificate; /** IUT EA certificate for signature check */ var octetstring vc_aaWholeHash; /** TS AA whole-hash for signature check */
var octetstring vc_eaPeerWholeHash; /** IUT EA whole-hash for signature check */ // var HashedId8 vc_ecHashedId8; /** Test Adapter AA HashedId8 for decryption of IUT's response */
// var Certificate vc_peerEaCertificate; /** IUT EA certificate for signature check */
// var octetstring vc_eaPeerWholeHash; /** IUT EA whole-hash for signature check */
} // End of component ItsPki } // End of component ItsPki
/** /**
......
...@@ -608,11 +608,11 @@ module LibItsSecurity_Functions { ...@@ -608,11 +608,11 @@ module LibItsSecurity_Functions {
out Oct32 p_publicKeyCompressed, out Oct32 p_publicKeyCompressed,
out integer p_compressedMode out integer p_compressedMode
) return boolean { ) return boolean {
if (PICS_SEC_FIXED_KEYS) { if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
p_privateKey := 'D418760F0CB2DCB856BC3C7217AD3AA36DB6742AE1DB655A3D28DF88CBBF84E1'O; p_privateKey := '43481BC44C073C1432DB6EC4F0EF57062BEA08E4C19F811567325AD1FD1C6577'O;
p_publicKeyX := 'EE9CC7FBD9EDECEA41F7C8BD258E8D2E988E75BD069ADDCA1E5A38E534AC6818'O; p_publicKeyX := '0B5D74B033531C51D17B4F218DD4E39289AE4BF2EE3D7BAB7C07DAF0C14F0317'O;
p_publicKeyY := '5AE3C8D9FE0B1FC7438F29417C240F8BF81C358EC1A4D0C6E98D8EDBCC714017'O; p_publicKeyY := '5D49B139A9237832FDE24D77555878CE65D6C2284A1BDA4CE08ABDD4071E0255'O;
p_publicKeyCompressed := 'EE9CC7FBD9EDECEA41F7C8BD258E8D2E988E75BD069ADDCA1E5A38E534AC6818'O; p_publicKeyCompressed := '0B5D74B033531C51D17B4F218DD4E39289AE4BF2EE3D7BAB7C07DAF0C14F0317'O;
p_compressedMode := 1; p_compressedMode := 1;
return true; return true;
......
...@@ -1015,6 +1015,11 @@ module LibItsSecurity_Templates { ...@@ -1015,6 +1015,11 @@ module LibItsSecurity_Templates {
in template (value) Time64 p_generationTime in template (value) Time64 p_generationTime
) modifies m_headerInfo_gn := {}; ) modifies m_headerInfo_gn := {};
template (omit) HeaderInfo m_headerInfo_inner_ec_response(
in template (value) Psid p_psid := c_its_aid_GN,
in template (value) Time64 p_generationTime
) modifies m_headerInfo_gn := {};
} // End of group headerFields } // End of group headerFields
group signatures { group signatures {
......