LibItsPki_Functions.ttcn 387 KB
Newer Older
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                  m_ec_signature(
                                                                 m_etsiTs103097Data_encrypted(
                                                                                              m_encryptedData(
                                                                                                              {
                                                                                                                m_recipientInfo_certRecipInfo(
                                                                                                                                              m_pKRecipientInfo(
                                                                                                                                                                v_recipientId,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                                                                                                                v_encrypted_data_encryption_key                                                                                                                                                            ))
                                                                                                                },
                                                                                                              m_symmetricCiphertext_aes128ccm(
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                                                                                              m_aesCcmCiphertext(
                                                                                                                                                                 v_nonce,
                                                                                                                                                                 v_enc_signed_ec_signature
                                                                                                                                                                 )
                                                                                                                                              )
                                                                                                              )
                                                                                              )
                                                                 )
                                                  );
      } else if (p_enc_algo == e_sm2_p256) { // FIXME FSCOM

ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else { // Skip the encryption, alowed to be re-identified by the AA
        p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature));
      }
      // Build the InnerAtRequest, EcSignature field is already set
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
      } else {
        var EccP384CurvePoint v_eccP384_curve_point;
        if (p_compressed_key_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      }
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        if (p_compressed_enc_key_mode == 0) {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
        } else {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
        }
        if (p_enc_algo == e_nist_p256) {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point));
        } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        } else {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point));
        }
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key,
                                                              m_encryptionKey( // FIXME Encryption keys could be optional
                                                                              -,
                                                                              v_public_encryption_key
                                                                              )
                                                              )
                                                  );
      } else {
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key
                                                              )
                                                  );
      }
      p_inner_at_request.hmacKey := v_hmac_key;
      log("f_generate_inner_at_request: p_inner_at_request= ", p_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_at_request
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_at_request_with_wrong_parameters(
                                                               in Certificate p_aa_certificate,
                                                               in SignAlgorithm p_enc_algo := PX_EC_ALG_FOR_AT,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                               in Oct8 p_aa_hashed_id8,
                                                               in Certificate p_ea_certificate,
                                                               in octetstring p_salt,
                                                               in Oct8 p_ea_hashed_id8,
                                                               in Certificate p_ec_certificate,
                                                               in octetstring p_ec_private_key,
                                                               in boolean p_alter_hmac := false,
                                                               in boolean p_alter_signer_digest := false,
                                                               in template (omit) Time32 p_start := omit,
                                                               in template (omit) Duration p_duration := omit,
                                                               in template (omit) Time64 p_generation_time := omit,
                                                               out octetstring p_private_key,
                                                               out octetstring p_public_key_compressed,
                                                               out integer p_compressed_key_mode,
                                                               out octetstring p_private_enc_key,
                                                               out octetstring p_public_compressed_enc_key,
                                                               out integer p_compressed_enc_key_mode,
                                                               out InnerAtRequest p_inner_at_request
                                                               ) return boolean {
      // Local variables
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var bitstring v_enc_value;
      var octetstring v_ec_hash;
      var PublicVerificationKey v_public_verification_key;
      var BasePublicEncryptionKey v_public_encryption_key;
      var Oct8 v_ec_hashed_id8;
      var octetstring public_enc_key_x;
      var octetstring public_enc_key_y;
      var Oct32 v_hmac_key;
      var PublicVerificationKey v_verification_tag;
      var PublicEncryptionKey v_encryption_tag;
      var octetstring v_encoded_tag;
      var Oct16 v_key_tag;
      var octetstring v_hash_shared_at_request;
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var Ieee1609Dot2Data v_signed_at_signature;
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
      var HashAlgorithm v_hashId;
      var Signature v_signature;
      var Time32 v_start;
      var Duration v_duration;
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM })),
        valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM }))
        };

      log("f_generate_inner_at_request_with_wrong_parameters: p_enc_algo=", p_enc_algo);

      // Generate verification keys for the certificate to be requested
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) {
        log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate verification key");
        return false;
      }
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification private key: ", p_private_key);
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed key: ", p_public_key_compressed);
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed mode: ", p_compressed_key_mode);
      // Generate encryption keys for the certificate to be requested
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        if (f_generate_key_pair_for_encryption(p_enc_algo, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) {
          log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate encryption key");
          return false;
        } else {
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption private key: ", p_private_enc_key);
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed key: ", p_public_compressed_enc_key);
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed mode: ", p_compressed_enc_key_mode);
        }
      } else {
        p_private_enc_key := ''O;
        v_public_enc_key_x := ''O;
        v_public_enc_key_y := ''O;
        p_public_compressed_enc_key := ''O;
        p_compressed_enc_key_mode := -1;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Calculate the whole certificate SHA
      v_enc_value := encvalue(p_ec_certificate);
      if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) {
        v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_hashedId8FromSha256(v_ec_hash);
      } else {
        v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_hashedId8FromSha384(v_ec_hash);
      }
      log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hash= ", v_ec_hash);
      log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hashed_id8= ", v_ec_hashed_id8);
      if (p_alter_signer_digest == true) {
        v_ec_hashed_id8 := int2oct((f_getCurrentTimeUtc() * 1000), 8);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered v_ec_hashed_id8= ", v_ec_hashed_id8);
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Generate 32 octets length secret key
      v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12));
      log("f_generate_inner_at_request_with_wrong_parameters: v_hmac_key= ", v_hmac_key);

      // Generate tag based on the concatenation of verification keys & encryption keys
      if (f_generate_key_tag(p_public_key_compressed, p_compressed_key_mode, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_encoded_tag) == false) {
        log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate Key tag");
        return false;
      }
      log("f_generate_inner_at_request_with_wrong_parameters: v_encoded_tag= ", v_encoded_tag);
      // Generate hmac key
      v_key_tag := substr(
                          fx_hmac_sha256( // TODO Rename and use a wrapper function
                                         v_hmac_key,
                                         v_encoded_tag
                                         ),
                          0,
                          16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
      log("f_generate_inner_at_request_with_wrong_parameters: v_key_tag= ", v_key_tag);
      if (p_alter_hmac == true) {
        v_hmac_key[0] := 'aa'O;
        v_hmac_key[1] := 'bb'O;
        log("f_generate_inner_at_request_with_wrong_parameters: Altered key_tag= ", v_hmac_key);
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Build the SharedAtRequest
      if (not(ispresent(p_start))) {
        v_start := p_ec_certificate.toBeSigned.validityPeriod.start_;
      } else {
        v_start := valueof(p_start);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.start= ", v_start);
      }
      if (not(ispresent(p_duration))) {
        v_duration := p_ec_certificate.toBeSigned.validityPeriod.duration;
      } else {
        v_duration := valueof(p_duration);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.duration= ", v_duration);
      }
      p_inner_at_request.sharedAtRequest := valueof(
                                                    m_shared_at_request(
                                                                        p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
                                                                        v_key_tag, // Calculated keyTag
                                                                        valueof(
                                                                                m_certificate_subject_attributes(
                                                                                                                 v_appPermissions,
                                                                                                                 p_ec_certificate.toBeSigned.certRequestPermissions,
                                                                                                                 { none_ := NULL },//p_ec_certificate.toBeSigned.id,
                                                                                                                 m_validityPeriod(v_start, v_duration),
                                                                                                                 p_ec_certificate.toBeSigned.region,
                                                                                                                 p_ec_certificate.toBeSigned.assuranceLevel
                                                                                                                 ))) // Desired attributes
                                                    );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Calculate the hash of the SharedAtRequest
      v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
      log("f_generate_inner_at_request_with_wrong_parameters: v_hash_shared_at_request= ", v_hash_shared_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Build the ETsiTs103097Data-SignedExternalPayload
      if (ispresent(p_generation_time)) {
        v_tbs := m_toBeSignedData(
                                  m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                  m_headerInfo_inner_pki_request( // HeaderInfo
                                                                 -,
                                                                 valueof(p_generation_time) * 1000) //us
                                  );
        log("f_generate_inner_at_request_with_wrong_parameters: Altered generation time: v_tbs= ", v_tbs);
      } else {
        v_tbs := m_toBeSignedData(
                                  m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                  m_headerInfo_inner_pki_request( // HeaderInfo
                                                                 -,
                                                                 f_getCurrentTime() * 1000) //us
                                  );
        log("f_generate_inner_at_request_with_wrong_parameters: v_tbs= ", v_tbs);
      }
      // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
      // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted
      // TODO Simplify with f_signWithEcdsa
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
        v_hashId := sha384;
        v_tbs_signed := f_signWithEcdsaBrainpoolp384r1WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 48)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 48, 48)
                                                                                     )
                                                                )
                                                        );
      } else {
        v_hashId := sha256;
        if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
          v_tbs_signed := f_signWithEcdsaBrainpoolp256r1WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaBrainpoolP256r1(
                                                                  m_ecdsaP256Signature(
                                                                                       m_eccP256CurvePoint_x_only(
                                                                                                                  substr(v_tbs_signed, 0, 32)
                                                                                                                  ),
                                                                                       substr(v_tbs_signed, 32, 32)
                                                                                       )
                                                                  )
                                 );
        } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
          v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaNistP256(
                                                           m_ecdsaP256Signature(
                                                                                m_eccP256CurvePoint_x_only(
                                                                                                           substr(v_tbs_signed, 0, 32)
                                                                                                           ),
                                                                                substr(v_tbs_signed, 32, 32)
                                                                                )
                                                           )
                                 );
        } else {
          // Error
          log("f_generate_inner_at_request_with_wrong_parameters: Failed to process signature");
          return false;
        }
      }
      v_signed_at_signature := valueof(
                                       m_etsiTs103097Data_signed(
                                                                 m_signedData(
                                                                              v_hashId,
                                                                              v_tbs,
                                                                              m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is the hasheId8 of the EC certificate obtained from Enrolment request
                                                                              v_signature
                                                                              )
                                                                 )
                                       );
      log("f_generate_inner_at_request_with_wrong_parameters: v_signed_at_signature= ", v_signed_at_signature);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
        var octetstring v_public_enc_key;
        var integer v_compressed_mode;
        var Oct12 v_nonce;
        var Oct16 v_authentication_vector;
        var Oct16 v_aes_sym_key;
        var Oct16 v_encrypted_sym_key;
        var HashedId8 v_recipientId;
        var octetstring v_public_compressed_ephemeral_key;
        var integer v_public_compressed_ephemeral_mode;
        var octetstring v_enc_signed_ec_signature;
        var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        // Use EA certificate for the encryption
        if (p_enc_algo == e_nist_p256) {
          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_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request_with_wrong_parameters: Wrong NistP256 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                                m_evciesP256EncryptedKey(
                                                                                                                         v_eccP256_curve_point,
                                                                                                                         v_encrypted_sym_key,
                                                                                                                         v_authentication_vector
                                                                                                                         )));
        } else if (p_enc_algo == e_brainpool_p256_r1) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request_with_wrong_parameters: Wrong BrainpoolP256r1 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256r1WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                       m_evciesP256EncryptedKey(
                                                                                                                                v_eccP256_curve_point,
                                                                                                                                v_encrypted_sym_key,
                                                                                                                                v_authentication_vector
                                                                                                                                )));
        } else if (p_enc_algo == e_sm2_p256) { // FIXME FSCOM

ASN.1 Documenter's avatar
ASN.1 Documenter committed
        } else {
          log("f_generate_inner_at_request_with_wrong_parameters: Wrong encryption variant");
          return false;
        }
        log("f_generate_inner_at_request_with_wrong_parameters: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key);
        v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
        log("f_generate_inner_at_request_with_wrong_parameters: v_recipientId= ", v_recipientId);
        // Fill Certificate template with the public compressed keys (canonical form)
        p_inner_at_request.ecSignature := valueof(
                                                  m_ec_signature(
                                                                 m_etsiTs103097Data_encrypted(
                                                                                              m_encryptedData(
                                                                                                              {
                                                                                                                m_recipientInfo_certRecipInfo(
                                                                                                                                              m_pKRecipientInfo(
                                                                                                                                                                v_recipientId,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                                                                                                                v_encrypted_data_encryption_key                                                                                                                                                            ))
                                                                                                                },
                                                                                                              m_symmetricCiphertext_aes128ccm(
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                                                                                              m_aesCcmCiphertext(
                                                                                                                                                                 v_nonce,
                                                                                                                                                                 v_enc_signed_ec_signature
                                                                                                                                                                 )
                                                                                                                                              )
                                                                                                              )
                                                                                              )
                                                                 )
                                                  );
      } else { // Skip the encryption, alowed to be re-identified by the AA
        p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature));
      }
      // Build the InnerAtRequest, EcSignature field is already set
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
      } else {
        var EccP384CurvePoint v_eccP384_curve_point;
        if (p_compressed_key_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      }
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        if (p_compressed_enc_key_mode == 0) {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
        } else {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
        }
        if (p_enc_algo == e_nist_p256) {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point));
        } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        } else {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point));
        }
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key,
                                                              m_encryptionKey( // FIXME Encryption keys could be optional
                                                                              -,
                                                                              v_public_encryption_key
                                                                              )
                                                              )
                                                  );
      } else {
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key
                                                              )
                                                  );
      }
      p_inner_at_request.hmacKey := v_hmac_key;
      log("f_generate_inner_at_request_with_wrong_parameters: p_inner_at_request= ", p_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_at_request_with_wrong_parameters
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_verify_inner_at_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      in EtsiTs103097Certificate p_ec_certificate,
                                                      out InnerAtRequest p_inner_at_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_at_request_signed_for_pop: p_etsi_ts_102941_data=", p_etsi_ts_102941_data);
      log(">>> f_verify_inner_at_request_signed_for_pop: p_ec_certificate=", p_ec_certificate);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 1. Extract content
      p_inner_at_request := p_etsi_ts_102941_data.content.authorizationRequest;

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_verify_inner_at_request_signed_for_pop: ", p_inner_at_request);
      return true;
    } // End of function f_verify_inner_at_request_signed_for_pop
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_at_response(
                                          in octetstring p_authorization_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerAtResponse p_authorization_response
                                          ) return boolean {
      // Local variables
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Build the Proof of Possession InnerEcResponse
      p_authorization_response := valueof(
                                          m_innerAtResponse_ok(
                                                               substr(p_authorization_request_hash, 0, 16),
                                                               p_certificate
                                                               )
                                          );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_at_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group inner_at_xxx

  group bfk {

    function f_generate_ee_ra_cert_request(
                                           out octetstring p_caterpillar_private_key,
                                           out octetstring p_caterpillar_public_key_compressed,
                                           out integer p_caterpillar_compressed_mode,
                                           out octetstring p_caterpillar_enc_private_key,
                                           out octetstring p_caterpillar_enc_public_key_compressed,
                                           out integer p_caterpillar_enc_compressed_mode,
                                           out EeRaCertRequest p_ee_ra_cert_request
                                           ) runs on ItsPkiHttp return boolean {
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var EccP256CurvePoint v_ecc_p256_curve_point;
      var EccP256CurvePoint v_ecc_enc_p256_curve_point;
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(36, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM })),
        valueof(m_appPermissions(37, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_DENM }))
      };
      var PublicVerificationKey v_public_verification_key;
      var template (value) ToBeSignedCertificate v_tbs;
      log (">>> f_generate_ee_ra_cert_request");
      log("f_generate_ee_ra_cert_request: PX_VE_ALG=", PX_VE_ALG);

      // Generate caterpillar signing keys
      if (PX_BFK_TEST_VECTORS) {
        p_caterpillar_private_key := 'D418760F0CB2DCB856BC3C7217AD3AA36DB6742AE1DB655A3D28DF88CBBF84E1'O;
        p_caterpillar_public_key_compressed := 'EE9CC7FBD9EDECEA41F7C8BD258E8D2E988E75BD069ADDCA1E5A38E534AC6818'O;
        p_caterpillar_compressed_mode := 1;
      } else {
        if (f_generate_key_pair(p_caterpillar_private_key, v_public_key_x, v_public_key_y, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode) == false) {
          log("f_generate_ee_ra_cert_request: Failed to generate caterpillar keys");
          return false;
        }
      }
      log ("f_generate_ee_ra_cert_request: Caterpillar private key: ", p_caterpillar_private_key);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed key: ", p_caterpillar_public_key_compressed);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed mode: ", p_caterpillar_compressed_mode);
      if (p_caterpillar_compressed_mode == 0) {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_caterpillar_public_key_compressed));
      } else {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_caterpillar_public_key_compressed));
      }

      if (PX_EC_ALG_FOR_EC == e_nist_p256) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaNistP256(
                                                                                   v_ecc_p256_curve_point
                                                                                   ));
      } else if (PX_EC_ALG_FOR_EC == e_nist_p384) { // FIXME FSCOM
        // v_public_verification_key := valueof(
        //                                      m_publicVerificationKey_ecdsaNistP384(
        //                                                                            v_ecc_p384_curve_point
        //                                                                            ));
      } else if (PX_EC_ALG_FOR_EC == e_brainpool_p256_r1) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaBrainpoolP256r1(
                                                                                          v_ecc_p256_curve_point
                                                                                          ));
      } else if (PX_EC_ALG_FOR_EC == e_brainpool_p384_r1) { // FIXME FSCOM
        // v_public_verification_key := valueof(
        //                                      m_publicVerificationKey_ecdsaBrainpoolP384r1(
        //                                                                                   v_ecc_p384_curve_point
        //                                                                                   ));
      } else if (PX_EC_ALG_FOR_EC == e_sm2_p256) { // FIXME FSCOM
      } else {
        log("f_generate_ee_ra_cert_request: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
        return false;
      }

      v_tbs := m_bfk_to_be_signed_certificate(
                                              { none_ := NULL },
                                              v_appPermissions,
                                              m_verificationKeyIndicator_verificationKey(
                                                                                        v_public_verification_key
                                                                                        ),
                                              m_validityPeriod(
                                                              f_getCurrentTime() / 1000,
                                                              m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)
                                                              ),
                                              m_geographicRegion_identifiedRegion(
                                                                                  {
                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2),
                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                    }
                                                                                  ),
                                              PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                              );

      // Generate caterpillar encryption keys
      if (f_generate_key_pair_for_encryption(e_nist_p256, p_caterpillar_enc_private_key, v_public_key_x, v_public_key_y, p_caterpillar_enc_public_key_compressed, p_caterpillar_enc_compressed_mode) == false) {
        log("f_generate_ee_ra_cert_request: Failed to generate caterpillar keys");
        return false;
      }
      log ("f_generate_ee_ra_cert_request: Caterpillar private key: ", p_caterpillar_enc_private_key);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed key: ", p_caterpillar_enc_public_key_compressed);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed mode: ", p_caterpillar_enc_compressed_mode);
      if (p_caterpillar_enc_compressed_mode == 0) {
        v_ecc_enc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_caterpillar_enc_public_key_compressed));
      } else {
        v_ecc_enc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_caterpillar_enc_public_key_compressed));
      }
      if (PICS_SECPKI_ORIGINAL_BFK_KEY) {
        var octetstring v_signing_expansion_key;
        var octetstring v_enc_expansion_key;
        f_generate_bkf_signing_expension_keys(v_signing_expansion_key);


        log ("f_generate_ee_ra_cert_request: v_signing_expansion_key: ", v_signing_expansion_key);
        var octetstring v_expanded_caterpillar_private_key;
        f_bfk_expend_private_key(v_signing_expansion_key, p_caterpillar_private_key, v_expanded_caterpillar_private_key);
        log ("f_generate_ee_ra_cert_request: v_expanded_caterpillar_private_key: ", v_expanded_caterpillar_private_key);
        var octetstring v_caterpillar_expended_public_key_compressed;
        var integer v_caterpillar_expended_compressed_mode;
        f_bfk_expend_public_key(v_signing_expansion_key, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode, v_caterpillar_expended_public_key_compressed, v_caterpillar_expended_compressed_mode);
        log ("f_generate_ee_ra_cert_request: v_caterpillar_expended_public_key_compressed: ", v_caterpillar_expended_public_key_compressed);
        log ("f_generate_ee_ra_cert_request: v_caterpillar_expended_compressed_mode: ", v_caterpillar_expended_compressed_mode);
        var boolean v_verif := f_bfk_verify_expended_keys(v_expanded_caterpillar_private_key, v_caterpillar_expended_public_key_compressed, v_caterpillar_expended_compressed_mode);
        stop;






























        f_generate_bkf_enc_expension_keys(v_enc_expansion_key);
        log ("f_generate_ee_ra_cert_request: v_signing_expansion_key: ", v_signing_expansion_key);
        log ("f_generate_ee_ra_cert_request: v_enc_expansion_key: ", v_enc_expansion_key);
        p_ee_ra_cert_request := valueof(
                                        m_butterfly_authorization_request( 
                                                                          f_getCurrentTime(), 
                                                                          explicit, 
                                                                          v_tbs,
                                                                          m_additional_params_original(
                                                                                                      m_butterfly_params_original(
                                                                                                                                  m_butterfly_expansion_aes128(
                                                                                                                                                               v_signing_expansion_key
                                                                                                                                                               ),
                                                                                                                                  m_encryptionKey(
                                                                                                                                                  -,
                                                                                                                                                  m_publicEncryptionKey_eciesNistP256(
                                                                                                                                                                                      v_ecc_enc_p256_curve_point
                                                                                                                                                  )),
                                                                                                                                  m_butterfly_expansion_aes128(
                                                                                                                                                               v_enc_expansion_key
                                        )))));
      } else if (PICS_SECPKI_UNIFIED_BFK_KEY) {
        var octetstring v_expansion_key;
        f_generate_bkf_signing_expension_keys(v_expansion_key);
        log ("f_generate_ee_ra_cert_request: v_expansion_key: ", v_expansion_key);
        p_ee_ra_cert_request := valueof(
                                        m_butterfly_authorization_request( 
                                                                          f_getCurrentTime(), 
                                                                          explicit, 
                                                                          v_tbs,
                                                                          m_additional_params_unified(
                                                                                                      m_butterfly_expansion_aes128(
                                                                                                                                   v_expansion_key
                                        ))));
      } else {
        log("f_generate_ee_ra_cert_request: Wrong configuration, at least one (PICS_SECPKI_ORIGINAL_BFK_KEY, PICS_SECPKI_UNIFIED_BFK_KEY) of shall be set to true");
        return false;
      }
      log("f_generate_ee_ra_cert_request: p_ee_ra_cert_request: ", p_ee_ra_cert_request);

      return true;
    } // End of function f_generate_ee_ra_cert_request

    function f_generate_ee_ra_download_request(
                                               in charstring p_filename,
                                               out EeRaDownloadRequest p_ee_ra_download_request
                                               ) runs on ItsPkiHttp return boolean {
      p_ee_ra_download_request := valueof(m_ee_ra_download_request(f_getCurrentTimeUtc(), p_filename));
      log("f_generate_ee_ra_download_request: p_ee_ra_download_request: ", p_ee_ra_download_request);

      return true
    } // End of function f_generate_ee_ra_download_request

  } // End of group bfk

ASN.1 Documenter's avatar
ASN.1 Documenter committed
  group dc {

    function f_build_dc(
                        in charstring p_rca_certificate_id,
                        out EtsiTs103097Certificate p_rca_certificate
                        ) {
      log(">>> f_build_dc");

      // Load certificate
      f_readCertificate(p_rca_certificate_id, p_rca_certificate);
    }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_verify_rca_ctl_response_message(
                                               in EtsiTs103097Data p_etsi_ts_103097_signed_data,
                                               in boolean p_check_security := true,
                                               out ToBeSignedRcaCtl p_to_be_signed_rca_ctl
                                               ) return boolean {
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var Certificate v_certificate;
      var charstring v_certificate_id;
      var octetstring v_issuer;
      var EtsiTs102941Data v_etsi_ts_102941_data;

      log(">>> f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data);

      // 1. Verify signature
      log("f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      if (ispresent(p_etsi_ts_103097_signed_data.content.signedData.signer.digest)) {
        if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
          log("f_verify_rca_ctl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest);
          if (p_check_security == true) {
            return false;
          }
        }
        log("f_verify_rca_ctl_response_message (1): v_certificate: ", v_certificate);
        f_getCertificateHash(v_certificate_id, v_issuer);
      } else {
        v_certificate := p_etsi_ts_103097_signed_data.content.signedData.signer.certificate[0];
        log("f_verify_rca_ctl_response_message (2): v_certificate: ", v_certificate);
        if (ispresent(v_certificate.issuer.sha256AndDigest)) {
          v_issuer := v_certificate.issuer.sha256AndDigest;
        } if (ispresent(v_certificate.issuer.sha384AndDigest)) {
          v_issuer := v_certificate.issuer.sha384AndDigest;
        } else { // self_
          if (v_certificate.issuer.self_ == sha256) {
            v_issuer := int2oct(0, 32);
          } else {
            v_issuer := int2oct(0, 48);
          }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      }
      if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_rca_ctl_response_message: Failed to verify signature");
        if (p_check_security == true) {
          return false;
        }
      }
      v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) {
        log("f_verify_rca_ctl_response_message: Failed to decode EtsiTs102941Data");
        return false;
      } else {
        log("f_verify_rca_ctl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data);
        log("f_verify_pki_response_message: RcaCertificateTrustListMessage matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl));
        if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl) == false) {
          log("f_verify_rca_ctl_response_message: Failed to decode certificateTrustListRca");
          return false;
        } else {
          var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000;
          p_to_be_signed_rca_ctl := v_etsi_ts_102941_data.content.certificateTrustListRca;
          log("f_verify_rca_ctl_response_message: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl);
          if (p_to_be_signed_rca_ctl.nextUpdate <= v_time) {
            log("f_verify_rca_ctl_response_message: Invalid nextUpdate value: compared values=", p_to_be_signed_rca_ctl.nextUpdate, "/", v_time);
            return false;
          }
          // TODO Verify RCA certificate & signature
        }
      }

      return true;
    }

    function f_verify_rca_crl_response_message(
                                               in EtsiTs103097Data p_etsi_ts_103097_signed_data,
                                               in boolean p_check_security := true,
                                               out ToBeSignedCrl p_to_be_signed_crl
                                               ) return boolean {
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var Certificate v_certificate;
      var charstring v_certificate_id;
      var octetstring v_issuer;
      var EtsiTs102941Data v_etsi_ts_102941_data;

      log(">>> f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data);

      // 1. Verify signature
      log("f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
        log("f_verify_rca_crl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest);
        if (p_check_security == true) {
          return false;
        }
      }
      f_getCertificateHash(v_certificate_id, v_issuer);
      if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_rca_crl_response_message: Failed to verify signature");
        if (p_check_security == true) {
          return false;
        }
      }
      v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) {
        log("f_verify_rca_crl_response_message: Failed to decode EtsiTs102941Data");
        return false;
      } else {
        log("f_verify_rca_crl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data);
        log("f_verify_pki_response_message: CertificateRevocationList matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl));
        if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl) == false) {
          log("f_verify_rca_crl_response_message: Failed to decode certificateRevocationList");
          return false;
        } else {
          var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000;
          p_to_be_signed_crl := v_etsi_ts_102941_data.content.certificateRevocationList;
          log("f_verify_rca_crl_response_message: p_to_be_signed_crl= ", p_to_be_signed_crl);
          if (p_to_be_signed_crl.thisUpdate >= v_time) {
            log("f_verify_rca_crl_response_message: Invalid thisUpdate value");
            return false;
          }
          if (p_to_be_signed_crl.nextUpdate <= v_time) {
            log("f_verify_rca_crl_response_message: Invalid nextUpdate value");
            return false;
          }
          // TODO Verify RCA certificate & signature
        }
      }

      return true;
    }

    /**
     * @desc this function is used to retrieve the root certificate from SubCA entity
     * @param p_certificate The root certificate
     * @return 0 on success, -1 otherwise
     */
    function f_get_root_ca_certificate(
                                       in charstring p_iut_certificate := "CERT_IUT_A_CA",
                                       in boolean p_explicit_type := false,
                                       out Certificate p_certificate
                                       ) runs on ItsPkiHttp return integer {
      var Headers v_headers;
      var HttpMessage v_response;
      var octetstring v_os;
      var bitstring v_msg_bit;
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      log(">>> f_get_root_ca_certificate");
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      // Get root certificate
      f_cfHttpUp_ca();
      f_init_default_headers_list(PICS_HEADER_CTL_CONTENT_TYPE, "ca_request", v_headers);
      // Test Body
      f_http_send(
                  v_headers,
                  m_http_request(
                                  m_http_request_get(
                                                    PICS_HTTP_GET_URI_DC,
                                                    v_headers
                                                    )));
      tc_ac.start;
      alt {
        [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(
                                                        mw_http_response(
                                                                          mw_http_response_ok(
                                                                                              mw_http_message_body_binary(
                                                                                                                          mw_binary_body_ieee1609dot2_certificate
                                                                                                                          )))) -> value v_response {
          tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
        [PICS_MULTIPLE_END_POINT] httpCaPort.receive(
                                                      mw_http_response(
                                                                      mw_http_response_ok(
                                                                                          mw_http_message_body_binary(
                                                                                                                      mw_binary_body_ieee1609dot2_certificate
                                                                                                                      )))) -> value v_response {
          tc_ac.stop;
        }
        [] tc_ac.timeout {
        }
      } // End of 'alt' statement
      f_cfHttpDown_ca();
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      if (not(isvalue(v_response))) {
        log("f_get_root_ca_certificate: fail to get certificate");
        return -1;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("v_response.response.body.binary_body.ieee1609dot2_certificate: ", v_response.response.body.binary_body.ieee1609dot2_certificate);
      p_certificate := v_response.response.body.binary_body.ieee1609dot2_certificate;
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      log("<<< f_get_root_ca_certificate: ", p_certificate);
      return 0;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    }

    function f_verify_rca_certificate(
                                      in charstring p_authorized_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_RCA",
                                      in Certificate p_certificate,
                                      in boolean p_check_implicit := false,
                                      in boolean p_check_reconstruction_value := false,
                                      in boolean p_check_no_signature := false,
                                      in boolean p_check_region_restriction := false,
                                      in boolean p_check_signature_content := false,
                                      in boolean p_check_app_permissions := false,
                                      in boolean p_check_app_ssps := false,
                                      in boolean p_check_app_validity_period := false
                                      ) return boolean {
      var CertificateType v_type_ := explicit;
      var template Signature v_signature_ := ?;
      var template IssuerIdentifier v_issuer := ?;
      var template PublicVerificationKey v_public_verification_key := ?;
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      log(">>> f_verify_rca_certificate: p_authorized_certificate= ", p_authorized_certificate);
      log(">>> f_verify_rca_certificate: p_certificate= ", p_certificate);

      if (p_check_implicit == true) {
        v_type_ := implicit;
      }
      if (p_check_no_signature == true) {
        v_signature_ := omit;
      }
      if (match(p_certificate, mw_etsiTs103097Certificate(-, -, v_signature_, v_type_)) == false) {
        log("f_verify_rca_certificate: version/explicit mismatch");
        return false;
      }
      if (p_check_reconstruction_value == false) {
        if (match(p_certificate, mw_etsiTs103097Certificate(
                                                            -,
                                                            mw_toBeSignedCertificate_ca(
                                                                                        (mw_certificateId_none, mw_certificateId_name),
                                                                                        -,
                                                                                        -,
                                                                                        mw_verificationKeyIndicator_verificationKey
                                                                                        ),
                                                            v_signature_
                                                            )) == false) {
          log("f_verify_rca_certificate: verificationKey mismatch");
          return false;
        }
        if (p_check_signature_content) {
          var template PublicVerificationKey v_publicVerificationKey;
          if (PICS_SEC_SHA256) {
            v_signature_ := mw_signature_ecdsaNistP256;
            v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaNistP256;
          } else if (PICS_SEC_BRAINPOOL_P256R1) {
            v_signature_ := mw_signature_ecdsaBrainpoolP256r1;
            v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP256r1;
          } else if (PICS_SEC_BRAINPOOL_P384R1) {
            v_signature_ := mw_signature_ecdsaBrainpoolP384r1;
            v_issuer := (mw_issuerIdentifier_self(sha384), mw_issuerIdentifier_sha384AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP384r1;
          }
          if (match(p_certificate, mw_etsiTs103097Certificate(
                                                              v_issuer,
                                                              mw_toBeSignedCertificate_ca(
                                                                                          (mw_certificateId_none, mw_certificateId_name),
                                                                                          -,
                                                                                          -,
                                                                                          mw_verificationKeyIndicator_verificationKey(v_public_verification_key),
                                                                                          -, -, -, -,
                                                                                          -//mw_encryptionKey
                                                                                          ),
                                                              v_signature_
                                                              )) == false) {
            log("f_verify_rca_certificate: signature mismatch");
            return false;
          }
          // Verify Signature
          if (ischosen(p_certificate.issuer.self_)) {
            v_publicVerificationKey := p_certificate.toBeSigned.verifyKeyIndicator.verificationKey;