/** * @author ETSI / STF544 * @version $URL$ * $Id$ * @desc Module containing functions for ITS PKI ATS * @copyright ETSI Copyright Notification * No part may be reproduced except as authorized by written permission. * The copyright and the foregoing restriction extend to reproduction in all media. * All rights reserved. * */ module LibItsPki_Functions { // LibCommon import from LibCommon_Time all; import from LibCommon_VerdictControl all; import from LibCommon_Sync all; import from LibCommon_BasicTypesAndValues all; import from LibCommon_DataStrings all; // LibIts import from IEEE1609dot2BaseTypes language "ASN.1:1997" all; import from IEEE1609dot2 language "ASN.1:1997" all; import from EtsiTs102941BaseTypes language "ASN.1:1997" all; import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all; import from EtsiTs102941MessagesItss language "ASN.1:1997" all; import from EtsiTs103097Module language "ASN.1:1997" all; import from ITS_Container language "ASN.1:1997" all; import from CAM_PDU_Descriptions language "ASN.1:1997" all; // LibItsCommon import from LibItsCommon_TypesAndValues all; import from LibItsCommon_Functions all; import from LibItsCommon_ASN1_NamedNumbers all; import from LibItsCommon_Pixits all; // LibItsSecurity import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pixits all; // LibItsHttp import from LibItsHttp_TypesAndValues all; import from LibItsHttp_TestSystem all; // LibItsPki import from LibItsPki_Templates all; import from LibItsPki_TestSystem all; group pkiConfigurationFunctions { /** * @desc Setups default configuration * @param p_certificateId The certificate identifier the TA shall use in case of secured IUT */ function f_cfUp( in charstring p_certificateId := "CERT_TS_A_EA" // TODO Use a constant ) runs on ItsPki /* TITAN TODO: system ItsPkiSystem */ { map(self:pkiPort, system:pkiPort); map(self:acPkiPort, system:acPkiPort); f_connect4SelfOrClientSync(); if( not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); stop; } f_prepareCertificates(p_certificateId, vc_aaCertificate, vc_atCertificate); f_readCertificate(p_certificateId, vc_eaCertificate); } // End of function f_cfUp /** * @desc Setups default configuration * @param p_certificateId The certificate identifier the TA shall use in case of secured IUT */ function f_cfHttpUp( in charstring p_certificateId := "CERT_TS_A_EA" // TODO Use a constant ) runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ { map(self:httpPort, system:httpPort); f_connect4SelfOrClientSync(); if( not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); stop; } f_prepareCertificates(p_certificateId, vc_aaCertificate, vc_atCertificate); f_readCertificate(p_certificateId, vc_eaCertificate); } // End of function f_cfHttpUp /** * @desc Deletes default configuration */ function f_cfDown() runs on ItsPki /* TITAN TODO: system ItsPkiSystem */ { unmap(self:pkiPort, system:pkiPort); unmap(self:acPkiPort, system:acPkiPort); f_disconnect4SelfOrClientSync(); } // End of function f_cfDown /** * @desc Deletes default configuration */ function f_cfHttpDown() runs on ItsPkiHttp /* TITAN TODO: system ItsPkiHttpSystem */ { unmap(self:httpPort, system:httpPort); f_disconnect4SelfOrClientSync(); } // End of function f_cfHttpDown /** * @desc Initialise secure mode if required */ function f_initialiseSecuredMode() runs on ItsPki { // Local variables // Load certificates if( not f_loadCertificates(PX_IUT_SEC_CONFIG_NAME) ) { log("*** INFO: TEST CASE NOW STOPPING ITSELF! ***"); stop; } } // End of function f_initialiseSecuredMode() function f_uninitialiseSecuredMode() runs on ItsPki { f_unloadCertificates(); } // End of function f_uninitialiseSecuredMode() } // End of pkiConfigurationFunctions group inner_ec_xxx { function f_generate_inner_ec_request( out Oct32 p_private_key, out Oct32 p_publicKeyX, out Oct32 p_publicKeyY, out Oct32 p_publicKeyCompressed, out integer p_compressedMode, out InnerEcRequest p_inner_ec_request ) return boolean { // Local variables var template (value) EccP256CurvePoint v_eccP256_curve_point; // Generate keys for the certificate to be requested if (f_generate_key_pair_nistp256(p_private_key, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode) == false) { return false; } log("p_private_key = ", p_private_key); log("p_public_key X= ", p_publicKeyX); log("p_public_key Y= ", p_publicKeyY); log("p_public_key compressed= ", p_publicKeyCompressed, p_compressedMode); if (p_compressedMode == 0) { v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(p_publicKeyCompressed); } else { v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(p_publicKeyCompressed); } // Build the Proof of Possession InnerEcRequest p_inner_ec_request := valueof( m_innerEcRequest( "CanonicalItsId", // TODO Use PIXIT m_publicKeys( m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point), m_encryptionKey( -, m_publicEncryptionKey_ecdsaNistP256(v_eccP256_curve_point) ) ), m_certificateSubjectAttributes( { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs valueof(m_appPermissions(36, { bitmapSsp := '830001'O })), // TODO Use PIXIT valueof(m_appPermissions(37, { bitmapSsp := '830001'O })) // TODO Use PIXIT }, m_validityPeriod( 17469212, m_duration_years(10) // TODO Use PIXIT ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(12), // TODO Use PIXIT m_identifiedRegion_country_only(34) // TODO Use PIXIT } ), 'C0'O // TODO Use PIXIT ) ) ); return true; } // End of function f_generate_inner_ec_request function f_generate_inner_ec_request_signed_for_pop( in Oct32 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 Oct32 v_tbs_signed; // Encode it v_encoded_inner_ec_request := bit2oct(encvalue(p_inner_ec_request)); // Signed the encoded InnerEcRequestSignedForPop v_tbs := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured( v_encoded_inner_ec_request ) ), m_headerInfo_inner_ec_request( c_its_aid_SCR, f_getCurrentTime()) ); // Signed the encoded InnerEcRequestSignedForPop v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key); // Finalyse signed InnerEcRequestSignedForPop p_inner_ec_request_signed_for_pop := valueof( m_etsiTs103097Data_signed( m_signedData( sha256, v_tbs, m_signerIdentifier_self, m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_tbs_signed, 0, 32) ), substr(v_tbs_signed, 32, 32) ) ) ) ) ); return true; } // End of function f_generate_inner_ec_request_signed_for_pop } // End of group inner_ec_xxx group pki_functions { function f_build_pki_secured_message( in Oct32 p_private_key, in SignerIdentifier p_signer_identifier, in HashedId8 p_recipientId, in Oct32 p_publicKeyCompressed, in integer p_compressedMode, in octetstring p_pki_message, out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data ) return boolean { // Local variables var template (value) EccP256CurvePoint v_eccP256_curve_point; var template (value) ToBeSignedData v_tbs; var Oct32 v_tbs_signed; var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data; var octetstring v_encoded_inner_ec_request; var Oct12 v_nonce; var Oct16 v_authentication_vector; var Oct16 v_encrypted_sym_key; var HashedId8 v_recipientId; var Oct32 v_publicEphemeralKeyCompressed; var integer v_ephemeralKeyModeCompressed; var octetstring v_encrypted_inner_ec_request; // Signed the encoded PKI message v_tbs := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(p_pki_message) ), m_headerInfo_inner_ec_request(12345, f_getCurrentTime()) // TODO Use PIXIT ); 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_request := bit2oct(encvalue(v_ieee1609dot2_signed_data)); // Encrypt encode EtsiTs103097Data-Signed data structure v_encrypted_inner_ec_request := f_encryptWithEciesNistp256WithSha256(v_encoded_inner_ec_request, p_publicKeyCompressed, p_compressedMode, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, v_encrypted_sym_key, v_authentication_vector, v_nonce); log("p_recipientId=", p_recipientId); if (p_recipientId == int2oct(0, 8)) { log("v_encrypted_sym_key=", v_encrypted_sym_key); log("f_hashWithSha256(v_encrypted_sym_key=", f_hashWithSha256(v_encrypted_sym_key)); v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(v_encrypted_sym_key)); } else { v_recipientId := p_recipientId; } log("v_recipientId=", v_recipientId); // Fill Certificate template with the public compressed keys (canonical form) if (v_ephemeralKeyModeCompressed == 0) { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed)); } else { v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_publicEphemeralKeyCompressed)); } p_ieee1609dot2_signed_and_encrypted_data := valueof( m_etsiTs103097Data_encrypted( m_encryptedData( { m_recipientInfo_signedDataRecipInfo( m_pKRecipientInfo( v_recipientId, m_encryptedDataEncryptionKey_eciesNistP256( m_evciesP256EncryptedKey( v_eccP256_curve_point, v_encrypted_sym_key, v_authentication_vector )))) }, m_SymmetricCiphertext_aes128ccm( m_aesCcmCiphertext( v_nonce, v_encrypted_inner_ec_request ) ) ) ) ); return true; } // End of function f_build_pki_secured_message function f_generate_inner_ec_response( in Oct32 p_inner_ec_request_hashed_id, 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_hashed_id, 0, 16), p_certificate ) ); return true; } // End of function f_generate_inner_ec_response } // End of group inner_ec_xxx } // End of module LibItsPki_Functions