module TestCodec_ChainOfCertificates { // LibCommon 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 EtsiTs103097Module language "ASN.1:1997" all; // LibItsGeoNetworking import from LibItsGeoNetworking_EncdecDeclarations all; import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_Templates all; // LibItsSecurity import from LibItsSecurity_EncdecDeclarations all; import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pixits all; // TestCodec import from TestCodec_TestAndSystem all; type record sec_info { EtsiTs103097Certificate cert, octetstring enc_cert, Oct32 private_key, Oct32 public_key_x, Oct32 public_key_y, Oct32 public_key_compressed, integer compressed_mode, HashedId8 hashedid8, HashedId8 issuer } type record chain_sec_info { sec_info ca, sec_info aa, sec_info at } testcase tc_full_check_certificate_1() runs on TCType system TCType { var chain_sec_info v_chain_sec_info; var bitstring v_enc_msg := ''B; var template (value) GnNonSecuredPacket v_gnNonSecuredPacket; var template (value) EtsiTs103097Data v_secured_data; var template (value) GeoNetworkingPdu v_gnSecuredPacket; var octetstring v_publicKeyCompressed; var integer v_publicKeyCompressedMode; // Generate CA certificate v_chain_sec_info.ca.cert := f_create_ca_certificate_nistP256_1(v_chain_sec_info.ca); v_enc_msg := encvalue(v_chain_sec_info.ca.cert); v_chain_sec_info.ca.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.ca.hashedid8 := f_HashedId8FromSha256(v_chain_sec_info.ca.enc_cert); v_chain_sec_info.ca.issuer := v_chain_sec_info.ca.hashedid8; // Verify signature of CA certificate by itself v_enc_msg := encvalue(v_chain_sec_info.ca.cert.toBeSigned); if (ischosen(v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaNistp256WithSha256( bit2oct(v_enc_msg), int2oct(0, 32), v_chain_sec_info.ca.cert.signature_.ecdsaNistP256Signature.rSig.x_only & v_chain_sec_info.ca.cert.signature_.ecdsaNistP256Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass); log("Root keys: ", v_chain_sec_info.ca.cert); } // Generate AA certificate v_chain_sec_info.aa.cert := f_create_aa_certificate_nistP256_1(v_chain_sec_info.ca, v_chain_sec_info.aa); v_enc_msg := encvalue(v_chain_sec_info.aa.cert); v_chain_sec_info.aa.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.aa.hashedid8 := f_HashedId8FromSha256(v_chain_sec_info.aa.enc_cert); v_chain_sec_info.aa.issuer := v_chain_sec_info.ca.hashedid8; // Verify signature of AA certificate by CA certificate v_enc_msg := encvalue(v_chain_sec_info.aa.cert.toBeSigned); if (ischosen(v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaNistp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.ca.enc_cert), v_chain_sec_info.aa.cert.signature_.ecdsaNistP256Signature.rSig.x_only & v_chain_sec_info.aa.cert.signature_.ecdsaNistP256Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { v_enc_msg := encvalue(v_chain_sec_info.aa.cert); log("AA keys: ", v_chain_sec_info.aa.cert); setverdict(pass) } // Generate AT certificate v_chain_sec_info.at.cert := f_create_at_certificate_nistP256_1(v_chain_sec_info.aa, v_chain_sec_info.at); v_enc_msg := encvalue(v_chain_sec_info.at.cert); v_chain_sec_info.at.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.at.hashedid8 := f_HashedId8FromSha256(v_chain_sec_info.at.enc_cert); v_chain_sec_info.at.issuer := v_chain_sec_info.aa.hashedid8; // Verify signature of AT certificate by AA certificate v_enc_msg := encvalue(v_chain_sec_info.at.cert.toBeSigned); if (ischosen(v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaNistp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.aa.enc_cert), v_chain_sec_info.at.cert.signature_.ecdsaNistP256Signature.rSig.x_only & v_chain_sec_info.at.cert.signature_.ecdsaNistP256Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass); v_enc_msg := encvalue(v_chain_sec_info.at.cert); log("AT keys: ", v_chain_sec_info.at.cert); } log("tc_full_check_certificate_1: Final chain = ", v_chain_sec_info); // Store Private key in binary format fx_loadCertificates("/home/vagrant/tmp/Yann", ""); fx_store_certificate("CERT_TEST_A_ROOT", v_chain_sec_info.ca.enc_cert, v_chain_sec_info.ca.private_key, v_chain_sec_info.ca.public_key_x, v_chain_sec_info.ca.public_key_y, v_chain_sec_info.ca.public_key_compressed, v_chain_sec_info.ca.compressed_mode, v_chain_sec_info.ca.hashedid8, v_chain_sec_info.ca.issuer, omit, omit, omit); fx_store_certificate("CERT_TS_A_AA", v_chain_sec_info.aa.enc_cert, v_chain_sec_info.aa.private_key, v_chain_sec_info.aa.public_key_x, v_chain_sec_info.aa.public_key_y, v_chain_sec_info.aa.public_key_compressed, v_chain_sec_info.aa.compressed_mode, v_chain_sec_info.aa.hashedid8, v_chain_sec_info.aa.issuer, omit, omit, omit); fx_store_certificate("CERT_TS_A_AT", v_chain_sec_info.at.enc_cert, v_chain_sec_info.at.private_key, v_chain_sec_info.at.public_key_x, v_chain_sec_info.at.public_key_y, v_chain_sec_info.at.public_key_compressed, v_chain_sec_info.at.compressed_mode, v_chain_sec_info.at.hashedid8, v_chain_sec_info.at.issuer, omit, omit, omit); // Create a basic GeoNetworking message v_gnNonSecuredPacket := m_geoNwShbPacket( LongPosVector: { gnAddr := { typeOfAddress := e_manual, stationType := e_roadSideUnit, stationCountryCode := 33, mid := 'a4fedecabeef'O }, timestamp_ := 123456, latitude := 4856, longitude := 675, pai := '1'B, speed := 55, heading := 9876 } ); // Build the secured message and sign it v_secured_data := f_build_and_sign_secured_message_nistP256_1(v_gnNonSecuredPacket, v_chain_sec_info.at); // Verify signature of secured messagee by AT certificate v_enc_msg := encvalue(v_secured_data.content.signedData.tbsData); if (ischosen(v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaNistp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.at.enc_cert), valueof(v_secured_data.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only) & valueof(v_secured_data.content.signedData.signature_.ecdsaNistP256Signature.sSig), v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass) } // Finalyse the GeoNetworking message // TODO Create a chain of certificates // TODO Add encryption support } // End of testcase tc_full_check_certificate_1 testcase tc_full_check_certificate_2() runs on TCType system TCType { var chain_sec_info v_chain_sec_info; var bitstring v_enc_msg := ''B; var template (value) GnNonSecuredPacket v_gnNonSecuredPacket; var template (value) EtsiTs103097Data v_secured_data; var template (value) GeoNetworkingPdu v_gnSecuredPacket; var octetstring v_publicKeyCompressed; var integer v_publicKeyCompressedMode; // Generate CA certificate v_chain_sec_info.ca.cert := f_create_ca_certificate_brainpoolP256_1(v_chain_sec_info.ca); v_enc_msg := encvalue(v_chain_sec_info.ca.cert); v_chain_sec_info.ca.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.ca.hashedid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg))); v_chain_sec_info.ca.issuer := v_chain_sec_info.ca.hashedid8; // Verify signature of CA certificate by itself v_enc_msg := encvalue(v_chain_sec_info.ca.cert.toBeSigned); if (ischosen(v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaBrainpoolp256WithSha256( bit2oct(v_enc_msg), int2oct(0, 32), v_chain_sec_info.ca.cert.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & v_chain_sec_info.ca.cert.signature_.ecdsaBrainpoolP256r1Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass) } // Generate AA certificate v_chain_sec_info.aa.cert := f_create_aa_certificate_brainpoolP256_1(v_chain_sec_info.ca, v_chain_sec_info.aa); v_enc_msg := encvalue(v_chain_sec_info.aa.cert); v_chain_sec_info.aa.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.aa.hashedid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg))); v_chain_sec_info.aa.issuer := v_chain_sec_info.ca.hashedid8; // Verify signature of AA certificate by CA certificate v_enc_msg := encvalue(v_chain_sec_info.aa.cert.toBeSigned); if (ischosen(v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaBrainpoolp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.ca.enc_cert), v_chain_sec_info.aa.cert.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & v_chain_sec_info.aa.cert.signature_.ecdsaBrainpoolP256r1Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass) } // Generate AT certificate v_chain_sec_info.at.cert := f_create_at_certificate_brainpoolP256_1(v_chain_sec_info.aa, v_chain_sec_info.at); v_enc_msg := encvalue(v_chain_sec_info.at.cert); v_chain_sec_info.at.enc_cert := bit2oct(v_enc_msg); v_chain_sec_info.at.hashedid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg))); v_chain_sec_info.at.issuer := v_chain_sec_info.aa.hashedid8; // Verify signature of AT certificate by AA certificate v_enc_msg := encvalue(v_chain_sec_info.at.cert.toBeSigned); if (ischosen(v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.aa.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaBrainpoolp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.aa.enc_cert), v_chain_sec_info.at.cert.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & v_chain_sec_info.at.cert.signature_.ecdsaBrainpoolP256r1Signature.sSig, v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass); } log("tc_full_check_certificate_2: Final chain = ", v_chain_sec_info); // Store Private key in binary format fx_loadCertificates("/home/vagrant/tmp/Yann", ""); fx_store_certificate("CERT_TEST_B_ROOT", v_chain_sec_info.ca.enc_cert, v_chain_sec_info.ca.private_key, v_chain_sec_info.ca.public_key_x, v_chain_sec_info.ca.public_key_y, v_chain_sec_info.ca.public_key_compressed, v_chain_sec_info.ca.compressed_mode, v_chain_sec_info.ca.hashedid8, v_chain_sec_info.ca.issuer, omit, omit, omit); fx_store_certificate("CERT_TS_B_AA", v_chain_sec_info.aa.enc_cert, v_chain_sec_info.aa.private_key, v_chain_sec_info.aa.public_key_x, v_chain_sec_info.aa.public_key_y, v_chain_sec_info.aa.public_key_compressed, v_chain_sec_info.aa.compressed_mode, v_chain_sec_info.aa.hashedid8, v_chain_sec_info.aa.issuer, omit, omit, omit); fx_store_certificate("CERT_TS_B_AT", v_chain_sec_info.at.enc_cert, v_chain_sec_info.at.private_key, v_chain_sec_info.at.public_key_x, v_chain_sec_info.at.public_key_y, v_chain_sec_info.at.public_key_compressed, v_chain_sec_info.at.compressed_mode, v_chain_sec_info.at.hashedid8, v_chain_sec_info.at.issuer, omit, omit, omit); // Create a basic GeoNetworking message v_gnNonSecuredPacket := m_geoNwShbPacket( LongPosVector: { gnAddr := { typeOfAddress := e_manual, stationType := e_roadSideUnit, stationCountryCode := 33, mid := 'a4fedecabeef'O }, timestamp_ := 123456, latitude := 4856, longitude := 675, pai := '1'B, speed := 55, heading := 9876 } ); // Build the secured message and sign it v_secured_data := f_build_and_sign_secured_message_brainpoolP256_1(v_gnNonSecuredPacket, v_chain_sec_info.at); // Verify signature of secured message by AT certificate v_enc_msg := encvalue(v_secured_data.content.signedData.tbsData); if (ischosen(v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) { v_publicKeyCompressed := v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0; v_publicKeyCompressedMode := 0; } else { v_publicKeyCompressed := v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1; v_publicKeyCompressedMode := 1; } if (f_verifyWithEcdsaBrainpoolp256WithSha256( bit2oct(v_enc_msg), f_hashWithSha256(v_chain_sec_info.at.enc_cert), valueof(v_secured_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only) & valueof(v_secured_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig), v_publicKeyCompressed, v_publicKeyCompressedMode ) == false) { setverdict(fail); } else { setverdict(pass); } // Finalyse the GeoNetworking message // TODO Create a chain of certificates // TODO Add encryption support } // End of testcase tc_full_check_certificate_2 /** * @desc Function to generate a CA certificate / NistP256 * @see ETSI TS 103 097 V1.3.1 7.2.3 Root CA certificates */ function f_create_ca_certificate_nistP256_1( out sec_info p_ca_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 NistP256 Root Certificate"; var HashAlgorithm v_self := sha256; // ETSI TS 103 097 V1.3.1 Clause 7.2.3 Root CA certificates Bullet 1 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var SequenceOfPsidSspRange v_certIssuePermissions := { // ETSI TS 103 097 V1.3.1 Clause 7.2.3 Root CA certificates Bullet 3 valueof(m_psidSspRange(1)) }; var HashedId8 v_sha256AndDigest; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_nistp256(p_ca_sec_info.private_key, p_ca_sec_info.public_key_x, p_ca_sec_info.public_key_y, p_ca_sec_info.public_key_compressed, p_ca_sec_info.compressed_mode); if (p_ca_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_ca_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_ca_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_self(v_self), m_toBeSignedCertificate_ca( { name := v_certId }, v_appPermissions, { m_psidGroupPermissions( m_subjectPermissions_explicit( v_certIssuePermissions )) }, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ) ) ); // Encode it ==> Get octetstring v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (NIST p-256) v_sig := f_signWithEcdsaNistp256WithSha256(bit2oct(v_enc_msg), int2oct(0, 32), p_ca_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_ca_certificate_nistP256_1: Signed template ", valueof(v_cert)); // Final CA certificate return valueof(v_cert); } // End of function f_create_ca_certificate_nistP256_1 /** * @desc Function to generate a CA certificate / BrainpoolP256 * @see ETSI TS 103 097 V1.3.1 Clause 77.2.3 Root CA certificates */ function f_create_ca_certificate_brainpoolP256_1( out sec_info p_ca_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 BrainpoolP256 Root Certificate"; var HashAlgorithm v_self := sha256; // ETSI TS 103 097 V1.3.1 Clause 7.2.3 Root CA certificates Bullet 1 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var SequenceOfPsidSspRange v_certIssuePermissions := { // ETSI TS 103 097 V1.3.1 Clause 7.2.3 Root CA certificates Bullet 3 valueof(m_psidSspRange(1)) }; var HashedId8 v_sha256AndDigest; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_brainpoolp256(p_ca_sec_info.private_key, p_ca_sec_info.public_key_x, p_ca_sec_info.public_key_y, p_ca_sec_info.public_key_compressed, p_ca_sec_info.compressed_mode); if (p_ca_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_ca_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_ca_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_self(v_self), m_toBeSignedCertificate_ca( { name := v_certId }, v_appPermissions, { m_psidGroupPermissions( m_subjectPermissions_explicit( v_certIssuePermissions )) }, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP256r1( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ) ) ); // Encode it ==> Get octetstring v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (BRAINPOOL P-256) v_sig := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(v_enc_msg), int2oct(0, 32), p_ca_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_ca_certificate_brainpoolP256_1: Signed template ", valueof(v_cert)); // Final CA certificate return valueof(v_cert); } // End of function f_create_ca_certificate_brainpoolP256_1 /** * @desc AA certificate / NistP256 * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Enrollment certificate */ function f_create_aa_certificate_nistP256_1( in sec_info p_ca_sec_info, out sec_info p_aa_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 NistP256 AA Certificate"; // ETSI TS 103 097 V1.3.1 Clause 7.2.2 Enrolment credential #5 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_nistp256(p_aa_sec_info.private_key, p_aa_sec_info.public_key_x, p_aa_sec_info.public_key_y, p_aa_sec_info.public_key_compressed, p_aa_sec_info.compressed_mode); if (p_aa_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_aa_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_aa_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_sha256AndDigest(p_ca_sec_info.hashedid8), m_toBeSignedCertificate_aa( { name := v_certId }, v_appPermissions, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(12), m_identifiedRegion_country_only(34) } ) ) ); // Encode it ==> Get octetstring v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (NIST P-256) v_sig := f_signWithEcdsaNistp256WithSha256(bit2oct(v_enc_msg), f_hashWithSha256(p_ca_sec_info.enc_cert), p_ca_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_aa_certificate_nistP256_1: Signed template ", valueof(v_cert)); // Final AA certificate return valueof(v_cert); } // End of function f_create_aa_certificate_nistP256_1 /** * @desc AA certificate / BrainpoolP256 * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Enrollment certificate */ function f_create_aa_certificate_brainpoolP256_1( in sec_info p_ca_sec_info, out sec_info p_aa_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 BrainpoolP256 AA Certificate"; // ETSI TS 103 097 V1.3.1 Clause 7.2.2 Enrolment credential #5 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_brainpoolp256(p_aa_sec_info.private_key, p_aa_sec_info.public_key_x, p_aa_sec_info.public_key_y, p_aa_sec_info.public_key_compressed, p_aa_sec_info.compressed_mode); if (p_aa_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_aa_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_aa_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_sha256AndDigest(p_ca_sec_info.hashedid8), m_toBeSignedCertificate_aa( { name := v_certId }, v_appPermissions, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP256r1( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(12), m_identifiedRegion_country_only(34) } ) ) ); // Encode it ==> Get octetstring v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (BRAINPOOL P-256) v_sig := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(v_enc_msg), f_hashWithSha256(p_ca_sec_info.enc_cert), p_ca_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_aa_certificate_brainpoolP256_1: Signed template ", valueof(v_cert)); // Final AA certificate return valueof(v_cert); } // End of function f_create_aa_certificate_brainpoolP256_1 /** * @desc AT certificate / NistP256 * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Authorization tickets */ function f_create_at_certificate_nistP256_1( in sec_info p_aa_sec_info, out sec_info p_at_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 NistP256 AT Certificate"; // ETSI TS 103 097 V1.3.1 Clause 7.2.1 Authorization tickets #2 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_nistp256(p_at_sec_info.private_key, p_at_sec_info.public_key_x, p_at_sec_info.public_key_y, p_at_sec_info.public_key_compressed, p_at_sec_info.compressed_mode); if (p_at_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_at_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_at_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_sha256AndDigest(p_aa_sec_info.hashedid8), m_toBeSignedCertificate_aa( { name := v_certId }, v_appPermissions, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(12), m_identifiedRegion_country_only(34) } ) ) ); // Encode it ==> Get octetstring log("Encode template ", valueof(v_cert)); v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (NIST P-256) v_sig := f_signWithEcdsaNistp256WithSha256(bit2oct(v_enc_msg), f_hashWithSha256(p_aa_sec_info.enc_cert), p_aa_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_at_certificate_nistP256_1: Signed template ", valueof(v_cert)); // Final AT certificate return valueof(v_cert); } // End of function f_create_at_certificate_nistP256_1 /** * @desc AT certificate / BrainpoolP256 * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Authorization tickets */ function f_create_at_certificate_brainpoolP256_1( in sec_info p_aa_sec_info, out sec_info p_at_sec_info ) runs on TCType return EtsiTs103097Certificate { var template (value) EtsiTs103097Certificate v_cert; // ETSI TS 103 097 V1.3.1 Clause 6 Bullet 1 var charstring v_certId := "STF538 BrainpoolP256 AT Certificate"; // ETSI TS 103 097 V1.3.1 Clause 7.2.1 Authorization tickets #2 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 })), valueof(m_appPermissions(38, { bitmapSsp := '830001'O })) }; var Oct32 v_sig := int2oct(0, 32); var bitstring v_enc_msg := ''B; var EccP256CurvePoint v_eccPoint; // Generate Private/Public keys f_generate_key_pair_brainpoolp256(p_at_sec_info.private_key, p_at_sec_info.public_key_x, p_at_sec_info.public_key_y, p_at_sec_info.public_key_compressed, p_at_sec_info.compressed_mode); if (p_at_sec_info.compressed_mode == 0) { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_0(p_at_sec_info.public_key_compressed)); } else { v_eccPoint := valueof(m_eccP256CurvePoint_compressed_y_1(p_at_sec_info.public_key_compressed)); } // Fill Certificate template with the public key v_cert := m_etsiTs103097Certificate( m_issuerIdentifier_sha256AndDigest(p_aa_sec_info.hashedid8), m_toBeSignedCertificate_aa( { name := v_certId }, v_appPermissions, m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP256r1( v_eccPoint )), m_validityPeriod( 17469212, m_duration_years(10) ), m_geographicRegion_identifiedRegion( { m_identifiedRegion_country_only(12), m_identifiedRegion_country_only(34) } ) ) ); // Encode it ==> Get octetstring log("Encode template ", valueof(v_cert)); v_enc_msg := encvalue(v_cert.toBeSigned); // Sign the certificate using ECDSA/SHA-256 (BRAINPOOL P-256) v_sig := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(v_enc_msg), f_hashWithSha256(p_aa_sec_info.enc_cert), p_aa_sec_info.private_key); v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ); log("f_create_at_certificate_brainpoolP256_1: Signed template ", valueof(v_cert)); // Final AT certificate return valueof(v_cert); } // End of function f_create_at_certificate_brainpoolP256_1 function f_build_and_sign_secured_message_nistP256_1( in template (value) GnNonSecuredPacket p_gnNonSecuredPacket, in sec_info p_at_sec_info ) runs on TCType return EtsiTs103097Data { var octetstring v_raw_payload_to_be_signed; var template (value) ToBeSignedData v_toBeSignedData; var Oct32 v_sig := '0000000000000000000000000000000000000000000000000000000000000000'O; var EtsiTs103097Data v_secured_data; // Build the message to be signed v_raw_payload_to_be_signed := bit2oct(encvalue(p_gnNonSecuredPacket)); v_toBeSignedData := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(v_raw_payload_to_be_signed) ), m_headerInfo_gn( -, 12345 ) ); // Signed it v_raw_payload_to_be_signed := bit2oct(encvalue(v_toBeSignedData)); v_sig := f_signWithEcdsaNistp256WithSha256(v_raw_payload_to_be_signed, f_hashWithSha256(p_at_sec_info.enc_cert), p_at_sec_info.private_key); // Finalize the secured message v_secured_data := valueof( m_etsiTs103097Data_signed( m_signedData( sha256, v_toBeSignedData, { digest := p_at_sec_info.hashedid8 }, m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ) ) ); log("f_build_and_sign_secured_message_nistP256_1: v_secured_data = ", v_secured_data); return v_secured_data; } // End of function f_build_and_sign_secured_message_nistP256_1 function f_build_and_sign_secured_message_brainpoolP256_1( in template (value) GnNonSecuredPacket p_gnNonSecuredPacket, in sec_info p_at_sec_info ) runs on TCType return EtsiTs103097Data { var octetstring v_raw_payload_to_be_signed; var template (value) ToBeSignedData v_toBeSignedData; var Oct32 v_sig := '0000000000000000000000000000000000000000000000000000000000000000'O; var template (value) EtsiTs103097Data v_secured_data; // Build the message to be signed v_raw_payload_to_be_signed := bit2oct(encvalue(p_gnNonSecuredPacket)); v_toBeSignedData := m_toBeSignedData( m_signedDataPayload( m_etsiTs103097Data_unsecured(v_raw_payload_to_be_signed) ), m_headerInfo_gn( -, 12345 ) ); // Signed it v_raw_payload_to_be_signed := bit2oct(encvalue(v_toBeSignedData)); v_sig := f_signWithEcdsaBrainpoolp256WithSha256(v_raw_payload_to_be_signed, f_hashWithSha256(p_at_sec_info.enc_cert), p_at_sec_info.private_key); // Finalize the secured message v_secured_data := m_etsiTs103097Data_signed( m_signedData( sha256, v_toBeSignedData, { digest := p_at_sec_info.hashedid8 }, m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_sig, 0, 32) ), substr(v_sig, 32, 32) ) ) ) ); log("f_build_and_sign_secured_message_brainpoolP256_1: v_secured_data = ", v_secured_data); return valueof(v_secured_data); } // End of function f_build_and_sign_secured_message_brainpoolP256_1 } // End of module TestCodec_ChainOfCertificates