TestCodec_ChainOfCertificates.ttcn 24.5 KB
Newer Older
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;
  
garciay's avatar
garciay committed
  // 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, 
    Oct32                     private_key,
    Oct32                     public_key_x,
    Oct32                     public_key_y,
    HashedId8                 hashid8
  }
      
  type record chain_sec_info {
    sec_info ca,
    sec_info ea,
    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;
garciay's avatar
garciay committed
    var template (value) GnNonSecuredPacket v_gnNonSecuredPacket;
    var template (value) EtsiTs103097Data v_secured_data;
    var template (value) GeoNetworkingPdu v_gnSecuredPacket;
    
    // Generate CA certificate
    v_chain_sec_info.ca.cert := f_create_ca_certificate_sha256_1(v_chain_sec_info.ca);
    v_enc_msg := encvalue(v_chain_sec_info.ca.cert);
    v_chain_sec_info.ca.hashid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg)));
    // Verify signature of CA certificate by itself
    v_enc_msg := encvalue(v_chain_sec_info.ca.cert.toBeSigned);
    if (f_verifyWithEcdsaNistp256WithSha256(
                                            bit2oct(v_enc_msg), 
garciay's avatar
garciay committed
                                            v_chain_sec_info.ca.cert.signature_.ecdsaNistP256Signature.sSig,
                                            v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.x,
                                            v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.y
                                           ) == false) {
      setverdict(fail);
    } else {
      setverdict(pass)
    }
    
    // Generate EA certificate
    v_chain_sec_info.ea.cert := f_create_at_certificate_sha256_1(v_chain_sec_info.ca, v_chain_sec_info.ea);
    v_enc_msg := encvalue(v_chain_sec_info.ea.cert);
    v_chain_sec_info.ea.hashid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg)));
    // Verify signature of EA certificate by CA certificate
    v_enc_msg := encvalue(v_chain_sec_info.ea.cert.toBeSigned);
    if (f_verifyWithEcdsaNistp256WithSha256(
                                            bit2oct(v_enc_msg), 
garciay's avatar
garciay committed
                                            v_chain_sec_info.ea.cert.signature_.ecdsaNistP256Signature.sSig,
                                            v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.x,
                                            v_chain_sec_info.ca.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.y
                                           ) == false) {
      setverdict(fail);
    } else {
      setverdict(pass)
    }

    // Generate AT certificate
    v_chain_sec_info.at.cert := f_create_at_certificate_sha256_1(v_chain_sec_info.ea, v_chain_sec_info.at);
    v_enc_msg := encvalue(v_chain_sec_info.at.cert);
    v_chain_sec_info.at.hashid8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_enc_msg)));
garciay's avatar
garciay committed
    // Verify signature of AT certificate by EA certificate
    v_enc_msg := encvalue(v_chain_sec_info.at.cert.toBeSigned);
    if (f_verifyWithEcdsaNistp256WithSha256(
                                            bit2oct(v_enc_msg), 
garciay's avatar
garciay committed
                                            v_chain_sec_info.at.cert.signature_.ecdsaNistP256Signature.sSig,
                                            v_chain_sec_info.ea.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.x,
                                            v_chain_sec_info.ea.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.y
                                           ) == false) {
      setverdict(fail);
    } else {
      setverdict(pass)
    }

garciay's avatar
garciay committed
    log("tc_full_check_certificate_1: Final chain = ", v_chain_sec_info);
    
    // 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_sha256(v_gnNonSecuredPacket, v_chain_sec_info.at);
garciay's avatar
garciay committed
    // Finalyse the GeoNetworking message
  v_gnSecuredPacket := m_geoNwSecPdu(v_gnNonSecuredPacket, v_secured_data);
    log("tc_full_check_certificate_1: Final GeoNetworking secured message: ", v_gnSecuredPacket);
    // Verify signature of EA certificate by CA certificate
    if (f_verifyWithEcdsaNistp256WithSha256(
                                            valueof(v_gnSecuredPacket.gnPacket.securedMsg.content.signedData.tbsData.payload.data.content.unsecuredData),
                                            valueof(v_gnSecuredPacket.gnPacket.securedMsg.content.signedData.signature_.ecdsaNistP256Signature.sSig),
                                            v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.x,
                                            v_chain_sec_info.at.cert.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.uncompressedP256.y
                                           ) == false) {
      setverdict(fail);
    } else {
      setverdict(pass)
    }
    
    // TODO Add encryption support
    
  } // End of testcase tc_full_check_certificate_1
  
  /**
   * @desc Function to generate a CA certificate / NistP256
   * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Authorization tickets
   */
  function f_create_ca_certificate_sha256_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 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
garciay's avatar
garciay committed
      valueof(m_appPermissions(36, { bitmapSsp := '830001'O })),
      valueof(m_appPermissions(37, { 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;
      
    // 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);
    // Store Private key in binary format
garciay's avatar
garciay committed
    // 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
                                                                                                                    ))
                                                                },
garciay's avatar
garciay committed
                                                              m_verificationKeyIndicator_verificationKey(
                                                                                                         m_publicVerificationKey_ecdsaNistP256(
                                                                                                                                               m_eccP256CurvePoint_uncompressed( // Signed by itself
                                                                                                                                                                                p_ca_sec_info.public_key_x,
                                                                                                                                                                                p_ca_sec_info.public_key_y
                                                                                                                                                                               ))),
                                                              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), p_ca_sec_info.private_key);
  v_cert.signature_ := m_signature_ecdsaNistP256(
                                                 m_ecdsaNistP256Signature(
                                                                          m_eccP256CurvePoint_uncompressed(
                                                                                                           p_ca_sec_info.public_key_x,
                                                                                                           p_ca_sec_info.public_key_y
                                                                                                          ),
                                                                          v_sig
                                                                         )
                                                );
garciay's avatar
garciay committed
    log("f_create_ca_certificate_sha256_1: Signed template ", valueof(v_cert));
    
    // Final CA certificate
    return valueof(v_cert);
  } // End of function f_create_ca_certificate_sha256_1
  
  /**
   * @desc EA certificate / NistP256
   * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Enrollment certificate
   */
  function f_create_ea_certificate_sha256_1(
                                            in sec_info p_ca_sec_info,
                                            out sec_info p_ea_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 EA 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
garciay's avatar
garciay committed
      valueof(m_appPermissions(36, { bitmapSsp := '830001'O })),
      valueof(m_appPermissions(37, { bitmapSsp := '830001'O }))
    };
    var Oct32 v_sig := int2oct(0, 32);
    var bitstring v_enc_msg := ''B;
      
    // Generate Private/Public keys
    f_generate_key_pair_nistp256(p_ea_sec_info.private_key, p_ea_sec_info.public_key_x, p_ea_sec_info.public_key_y);
    // Store Private key in binary format
garciay's avatar
garciay committed
    // Fill Certificate template with the public key
  v_cert := m_etsiTs103097Certificate(
                                      m_issuerIdentifier_sha256AndDigest(p_ca_sec_info.hashid8),
                                      m_toBeSignedCertificate_ea(
                                                                 { name := v_certId },
                                                                 v_appPermissions,
                                                                 m_verificationKeyIndicator_verificationKey(
                                                                                                            m_publicVerificationKey_ecdsaNistP256(
                                                                                                                                                  m_eccP256CurvePoint_uncompressed(
                                                                                                                                                                                   p_ea_sec_info.public_key_x,
                                                                                                                                                                                   p_ea_sec_info.public_key_y
                                                                                                                                                                                   ))),
                                                                 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), p_ca_sec_info.private_key);
  v_cert.signature_ := m_signature_ecdsaNistP256(
                                                 m_ecdsaNistP256Signature(
                                                                          m_eccP256CurvePoint_uncompressed(
                                                                                                           p_ca_sec_info.public_key_x,
                                                                                                           p_ca_sec_info.public_key_y
                                                                                                          ),
                                                                          v_sig
                                                                         )
                                                );
garciay's avatar
garciay committed
    log("f_create_ea_certificate_sha256_1: Signed template ", valueof(v_cert));
    
    // Final EA certificate
    return valueof(v_cert);
  } // End of function f_create_ea_certificate_sha256_1

  /**
   * @desc AT certificate / NistP256
   * @see ETSI TS 103 097 V1.3.1 Clause 7.2.1 Enrollment certificate
   */
  function f_create_at_certificate_sha256_1(
                                            in sec_info p_ea_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 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
garciay's avatar
garciay committed
      valueof(m_appPermissions(36, { bitmapSsp := '830001'O })),
      valueof(m_appPermissions(37, { bitmapSsp := '830001'O }))
    };
    var Oct32 v_sig := int2oct(0, 32);
    var bitstring v_enc_msg := ''B;
      
    // 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);
    // Store Private key in binary format
garciay's avatar
garciay committed
    // Fill Certificate template with the public key
  v_cert := m_etsiTs103097Certificate(
                                      m_issuerIdentifier_sha256AndDigest(p_ea_sec_info.hashid8),
                                      m_toBeSignedCertificate_ea(
                                                                 { name := v_certId },
                                                                 v_appPermissions,
                                                                 m_verificationKeyIndicator_verificationKey(
                                                                                                            m_publicVerificationKey_ecdsaNistP256(
                                                                                                                                                  m_eccP256CurvePoint_uncompressed(
                                                                                                                                                                                   p_at_sec_info.public_key_x,
                                                                                                                                                                                   p_at_sec_info.public_key_y
                                                                                                                                                                                   ))),
                                                                 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), p_ea_sec_info.private_key);
  v_cert.signature_ := m_signature_ecdsaNistP256(
                                                 m_ecdsaNistP256Signature(
                                                                          m_eccP256CurvePoint_uncompressed(
                                                                                                           p_ea_sec_info.public_key_x,
                                                                                                           p_ea_sec_info.public_key_y
                                                                                                          ),
                                                                          v_sig
                                                                         )
                                                );
garciay's avatar
garciay committed
    log("f_create_at_certificate_sha256_1: Signed template ", valueof(v_cert));
    
    // Final AT certificate
    return valueof(v_cert);
  } // End of function f_create_at_certificate_sha256_1

garciay's avatar
garciay committed
  function f_build_and_sign_secured_message_sha256(
                                                   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;
garciay's avatar
garciay committed
    // 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,
                                                       123456
                                                       )
                                       );
    // Signed it
  v_sig := f_signWithEcdsaNistp256WithSha256(v_raw_payload_to_be_signed, 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.hashid8 },
                                                           m_signature_ecdsaNistP256(
                                                                                     m_ecdsaNistP256Signature(
                                                                                                              m_eccP256CurvePoint_x_only(
                                                                                                                                         p_at_sec_info.public_key_x
                                                                                                                                         ),
                                                                                                              v_sig
                                                                                                              )
                                                                                     )
                                                           )
                                              );
    log("f_build_and_sign_secured_message_sha256: v_secured_data = ", v_secured_data);
    
    return valueof(v_secured_data);
  } // End of function f_build_and_sign_secured_message_sha256
  
} // End of module TestCodec_ChainOfCertificates