LibItsPki_Functions.ttcn 425 KB
Newer Older
      // Secure RaAcaCertRequest
      if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_butterfly_cert_request: ERROR: Non canonical EA certificate ***");
        return false;
      }
      log("f_http_build_butterfly_cert_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_butterfly_cert_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      v_result := f_build_pki_secured_request_message_signed_with_pop(vc_eaPrivateKey, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ra_aca_cert_request(p_ra_aca_cert_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
      if (v_result == false) {
        log("*** f_http_build_butterfly_cert_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        return false;
      } else {
        log("f_http_build_butterfly_cert_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_butterfly_cert_request: p_request_hash= ", p_request_hash);
      }

      return true;
    } // End of function f_http_build_butterfly_cert_request

    function f_http_build_butterfly_cert_response(
                                                  in HashedId8 p_request_hash,
                                                  in octetstring p_private_key := ''O,
                                                  in octetstring p_digest := ''O,
                                                  in Oct16 p_aes_sym_key,
                                                  out AcaRaCertResponse p_aca_ra_cert_response,
                                                  out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var boolean v_result := false;

      log(">>> f_http_build_butterfly_cert_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_butterfly_cert_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_butterfly_cert_response: p_digest= ", p_digest);
      log(">>> f_http_build_butterfly_cert_response: p_aes_sym_key= ", p_aes_sym_key);

      p_aca_ra_cert_response := valueof(
                                        m_ra_aca_cert_response(
                                                               f_getCurrentTimeUtc(),
                                                               p_request_hash,
                                                               m_aca_response_plain(m_etsiTs103097Data_unsecured(''O)) // FIXME FSCOM
                                        ));

      // Secure the response
      log("f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_aca_ra_cert_response(p_aca_ra_cert_response)));
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      // TODO Consider  Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest))
      if (f_build_pki_secured_response_message(p_private_key,
                                               valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),//  in SignerIdentifier p_signer_identifier,
                                               v_msg,
                                               p_aes_sym_key,
                                               v_nonce,
                                               p_ieee1609dot2_signed_and_encrypted_data
                                               ) == false) {
        log("f_http_build_butterfly_cert_response: Failed to generate the certificate");
      } else {
        v_result := true;
      }

      log("<<< f_http_build_butterfly_cert_response: v_result= ", v_result);
      log("<<< f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response);
      return v_result;

    } // End of function f_http_build_butterfly_cert_response

    function f_http_build_butterfly_at_download_request_message(
                                                                in charstring p_filename,
                                                                out Oct16 p_aes_sym_key,
                                                                out Oct16 p_encrypted_sym_key,
                                                                out Oct16 p_authentication_vector,
                                                                out Oct12 p_nonce,
                                                                out octetstring p_salt,
                                                                out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                out Oct32 p_request_hash
                                                                ) runs on ItsPkiHttp return boolean {
      var EeRaDownloadRequest v_ee_ra_download_request;
      var Ieee1609Dot2Data v_ee_ra_download_request_signed;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var octetstring v_private_key;
      var boolean v_result;

      log(">>> f_http_build_butterfly_at_download_request_message: p_filename: ", p_filename);

      // Generate EeRaDownloadRequest
      if (f_generate_ee_ra_download_request(p_filename, v_ee_ra_download_request) == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequest ***");
        return false;
      }
      log ("f_http_build_butterfly_at_download_request_message: v_ee_ra_download_request: ", v_ee_ra_download_request);

      // Secure EeRaDownloadRequest
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Non canonical EA certificate ***");
        return false;
      }
      log("f_http_build_butterfly_at_download_request_message: Public encryption key: ", v_public_enc_key);
      log("f_http_build_butterfly_at_download_request_message: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.

      log("f_http_build_butterfly_at_download_request_message: vc_ec_keys_counter: ", vc_ec_keys_counter);
      log("f_http_build_butterfly_at_download_request_message: vc_ec_private_keys: ", vc_ec_private_keys);
      log("f_http_build_butterfly_at_download_request_message: vc_ec_cert_hashed_id8: ", vc_ec_hashed_id8);
      v_result := f_build_pki_secured_request_message_signed_with_pop(vc_ec_private_keys[vc_ec_keys_counter - 1], valueof(m_signerIdentifier_digest(vc_ec_hashed_id8[vc_ec_keys_counter - 1])), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_download_request(v_ee_ra_download_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
      if (v_result == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        return false;
      } else {
        log("f_http_build_butterfly_at_download_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_butterfly_at_download_request_message: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_butterfly_at_download_request_message

ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_dc_request( // TODO Cleanup parameters
                                     in charstring p_ea_certificate_id,
                                     in charstring p_aa_certificate_id,
                                     in charstring p_rca_certificate_id,
                                     out octetstring p_private_key,
                                     out octetstring p_public_key_compressed,
                                     out integer p_compressed_mode,
                                     out Oct16 p_aes_sym_key,
                                     out Oct16 p_encrypted_sym_key,
                                     out Oct16 p_authentication_vector,
                                     out Oct12 p_nonce,
                                     out octetstring p_salt,
                                     out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                     out Oct32 p_request_hash
                                     ) runs on ItsPkiHttp {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function 
  } // End of group http

  group generate_certificates {

    function f_generate_ec_certificate(
                                       out octetstring p_private_key,
                                       out Certificate p_ec_certificate
                                       ) return boolean {
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring p_public_key_compressed;
      var integer p_compressed_mode;
      var EccP256CurvePoint v_ecc_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 template (value) EtsiTs103097Certificate v_cert;
      var bitstring v_tbs;
      var Oct32 v_sig;
      var bitstring v_enc_msg;
      var PublicVerificationKey v_public_verification_key;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_generate_ec_certificate");
      log("f_generate_ec_certificate: PX_EC_ALG_FOR_EC=", PX_EC_ALG_FOR_EC);
      log("f_generate_ec_certificate: PX_VE_ALG=", PX_VE_ALG);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Generate verification keys for the certificate
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) {
        log("f_generate_ec_certificate: Failed to generate verification key");
        return false;
      }
      if (p_compressed_mode == 0) {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
      } else {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_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
        //                                                                            ));
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } 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
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
        return false;
      }
      v_cert := m_etsiTs103097Certificate(
                                          m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(f_hashWithSha256('616263'O))),
                                          m_toBeSignedCertificate_at(
                                                                     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
                                                                     )
                                          );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        v_cert.signature_ := m_signature_ecdsaNistP256(
                                                       m_ecdsaP256Signature(
                                                                            m_eccP256CurvePoint_x_only(
                                                                                                       substr(v_sig, 0, 32)
                                                                                                       ),
                                                                            substr(v_sig, 32, 32)
                                                                            )
                                                       );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) { // FIXME FSCOM
        v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1(
                                                              m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 32)
                                                                                                              ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                              );
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
      } else if (PX_VE_ALG == e_nist_p384) {
        v_cert.signature_ := m_signature_ecdsaNistP384(
                                                       m_ecdsaP384Signature(
                                                                            m_eccP384CurvePoint_x_only(
                                                                                                       substr(v_sig, 0, 48)
                                                                                                       ),
                                                                             substr(v_sig, 48, 48)
                                                                             )
                                                        );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1(
                                                              m_ecdsaP384Signature(
                                                                                   m_eccP384CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 48)
                                                                                                              ),
                                                                                   substr(v_sig, 48, 48)
                                                                                   )
                                                              );
      }
      log("f_generate_ec_certificate: v_cert= ", v_cert);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      p_ec_certificate := valueof(v_cert);
      return true;
    } // End of function f_generate_ec_certificate
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_ec_certificate_for_inner_ec_response(
                                                             in InnerEcRequest p_inner_ec_request,
                                                             in octetstring p_private_key,
                                                             in octetstring p_digest,
                                                             out EtsiTs103097Certificate p_ec_certificate,
                                                             out HashedId8 p_ec_certificate_hashed_id8
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                             ) return boolean {
      var CertificateId v_certificate_id;
      var EtsiTs103097Certificate v_cert;
      var IssuerIdentifier v_issuer;
      var bitstring v_tbs;
      var octetstring v_sig;
      var ValidityPeriod v_valPeriod;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_generate_ec_certificate_for_inner_ec_response: p_inner_ec_request: ", p_inner_ec_request);
      log(">>> f_generate_ec_certificate_for_inner_ec_response: p_digest: ", p_digest);

      v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384
      if (not(ispresent(p_inner_ec_request.requestedSubjectAttributes.id))) {
        v_certificate_id := { none_ := NULL };
      } else {
        v_certificate_id := p_inner_ec_request.requestedSubjectAttributes.id;
      }
      if (ispresent(p_inner_ec_request.requestedSubjectAttributes.validityPeriod)) {
        v_valPeriod := p_inner_ec_request.requestedSubjectAttributes.validityPeriod;
      } else {
        v_valPeriod := valueof(m_validityPeriod(f_getCurrentTime() / 1000, m_duration_in_hours(24)));
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      v_cert := valueof(
                        m_etsiTs103097Certificate(
                                                  v_issuer,
                                                  m_toBeSignedCertificate_ec(
                                                                             v_certificate_id,
                                                                             p_inner_ec_request.requestedSubjectAttributes.appPermissions,
                                                                             m_verificationKeyIndicator_verificationKey(
                                                                                                                        p_inner_ec_request.publicKeys.verificationKey
                                                                                                                        ),
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                             p_inner_ec_request.requestedSubjectAttributes.region,
                                                                             p_inner_ec_request.requestedSubjectAttributes.assuranceLevel,
                                                                             p_inner_ec_request.publicKeys.encryptionKey
                                                                             )
                                                  )
                        );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 32)
                                                                                                               ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                               )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP256r1(
                                                                      m_ecdsaP256Signature(
                                                                                           m_eccP256CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 32)
                                                                                                                      ),
                                                                                           substr(v_sig, 32, 32)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP384r1(
                                                                      m_ecdsaP384Signature(
                                                                                           m_eccP384CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 48)
                                                                                                                      ),
                                                                                           substr(v_sig, 48, 48)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_nist_p384) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP384(
                                                               m_ecdsaP384Signature(
                                                                                    m_eccP384CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 48)
                                                                                                               ),
                                                                                    substr(v_sig, 48, 48)
                                                                                    )
                                                                )
                                     );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      p_ec_certificate := valueof(v_cert);

      // Encode it and calculate HashedId8
      v_tbs := encvalue(p_ec_certificate);
      p_ec_certificate_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(bit2oct(v_tbs)));
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate= ", p_ec_certificate);
      log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate_hashed_id8= ", p_ec_certificate_hashed_id8);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_ec_certificate_for_inner_ec_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_at_certificate_for_inner_at_response(
                                                             in InnerAtRequest p_inner_at_request,
                                                             in octetstring p_private_key,
                                                             in octetstring p_digest,
                                                             out EtsiTs103097Certificate p_at_certificate
                                                             ) return boolean {
      var EtsiTs103097Certificate v_cert;
      var IssuerIdentifier v_issuer;
      var bitstring v_tbs;
      var octetstring v_sig;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384
      v_cert := valueof(
                        m_etsiTs103097Certificate(
                                                  v_issuer,
                                                  m_toBeSignedCertificate_at(
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions,
                                                                             m_verificationKeyIndicator_verificationKey(
                                                                                                                        p_inner_at_request.publicKeys.verificationKey
                                                                                                                        ),
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod,
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.region,
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.assuranceLevel,
                                                                             p_inner_at_request.publicKeys.encryptionKey
                                                                             )
                                                  )
                        );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
      log("f_generate_at_certificate_for_inner_at_response: PX_VE_ALG=", PX_VE_ALG);
      if (PX_VE_ALG == e_nist_p256) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 32)
                                                                                                               ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                               )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP256r1(
                                                                      m_ecdsaP256Signature(
                                                                                           m_eccP256CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 32)
                                                                                                                      ),
                                                                                           substr(v_sig, 32, 32)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP384r1(
                                                                      m_ecdsaP384Signature(
                                                                                           m_eccP384CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 48)
                                                                                                                      ),
                                                                                           substr(v_sig, 48, 48)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_nist_p384) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP384(
                                                               m_ecdsaP384Signature(
                                                                                    m_eccP384CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 48)
                                                                                                              ),
                                                                                    substr(v_sig, 48, 48)
                                                                                    )
                                                              )
                                     );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      p_at_certificate := valueof(v_cert);
      log("f_generate_at_certificate_for_inner_at_response: p_at_certificate= ", p_at_certificate);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_at_certificate_for_inner_at_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_at_certificate_for_authorization_response(
                                                                  in InnerAtRequest p_inner_at_request,
                                                                  in octetstring p_private_key,
                                                                  in octetstring p_digest,
                                                                  out EtsiTs103097Certificate p_at_certificate
                                                                  ) return boolean {
      var EtsiTs103097Certificate v_cert;
      var IssuerIdentifier v_issuer;
      var bitstring v_tbs;
      var octetstring v_sig;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_generate_at_certificate_for_authorization_response");

      v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_hashedId8FromSha384
      v_cert := valueof(
                        m_etsiTs103097Certificate(
                                                  v_issuer,
                                                  m_toBeSignedCertificate_ec(
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.id,
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.appPermissions,
                                                                             m_verificationKeyIndicator_verificationKey(
                                                                                                                        p_inner_at_request.publicKeys.verificationKey
                                                                                                                        ),
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.validityPeriod,
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.region,
                                                                             p_inner_at_request.sharedAtRequest.requestedSubjectAttributes.assuranceLevel,
                                                                             p_inner_at_request.publicKeys.encryptionKey
                                                                             )
                                                  )
                        );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 32)
                                                                                                               ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                               )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP256r1(
                                                                      m_ecdsaP256Signature(
                                                                                           m_eccP256CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 32)
                                                                                                                      ),
                                                                                           substr(v_sig, 32, 32)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP384r1(
                                                                      m_ecdsaP384Signature(
                                                                                           m_eccP384CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 48)
                                                                                                                      ),
                                                                                           substr(v_sig, 48, 48)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_nist_p384) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP384(
                                                               m_ecdsaP384Signature(
                                                                                    m_eccP384CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 48)
                                                                                                              ),
                                                                                    substr(v_sig, 48, 48)
                                                                                    )
                                                              )
                                     );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      p_at_certificate := valueof(v_cert);
      log("f_generate_at_certificate_for_authorization_response: p_at_certificate= ", p_at_certificate);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_at_certificate_for_authorization_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group generate_certificates 
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  group inner_ec_xxx {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_ec_request(
                                         out octetstring p_private_key,
                                         out octetstring p_public_key_compressed,
                                         out integer p_compressed_mode,
                                         out InnerEcRequest p_inner_ec_request
                                         ) runs on ItsPkiHttp return boolean {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Local variables
      var Oct32 v_public_key_x;
      var Oct32 v_public_key_y;
      var PublicVerificationKey v_public_verification_key;

      log (">>> f_generate_inner_ec_request");
      log("f_generate_inner_ec_request: PX_VE_ALG=", PX_VE_ALG);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Generate 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_mode) == false) {
        log ("f_generate_inner_ec_request: failed to generate keys");
        return false;
      }
      // Build the Proof of Possession InnerEcRequest
      if (PX_VE_ALG == e_nist_p256) {
        var EccP256CurvePoint v_eccP256_curve_point;
        if (p_compressed_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        var EccP256CurvePoint v_eccP256_curve_point;
        if (p_compressed_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        var EccP384CurvePoint v_eccP384_curve_point;
        if (p_compressed_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(p_public_key_compressed));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(p_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      }
      if (PICS_EC_SUBJECT_ATTRIBUT_ID) {
        p_inner_ec_request := valueof(
                                      m_innerEcRequest(
                                                       PICS_ITS_S_CANONICAL_ID,
                                                       m_publicKeys(
                                                                    v_public_verification_key
                                                                    ),
                                                       m_certificateSubjectAttributes_id_name(
                                                                                              oct2char(PICS_ITS_S_CANONICAL_ID) & int2str(f_getCurrentTime()), // ETSI TS  103 097 Clause 7.2.2 Enrolment credential 
                                                                                              { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
                                                                                                valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR }))
                                                                                                },
                                                                                              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_1),
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                                                                    }
                                                                                                                                  ),
                                                                                              PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                                                                              )
                                                       )
                                      );
      } else {
        p_inner_ec_request := valueof(
                                      m_innerEcRequest(
                                                       PICS_ITS_S_CANONICAL_ID,
                                                       m_publicKeys(
                                                                    v_public_verification_key
                                                                    ),
                                                       m_certificateSubjectAttributes_id_omit( // ETSI TS  103 097 Clause 7.2.2 Enrolment credential 
                                                                                              { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
                                                                                                valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_SCR }))
                                                                                                },
                                                                                              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_1),
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                                                                    }
                                                                                                                                  ),
                                                                                              PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                                                                              )
                                                       )
                                      );
      }
      // Remove geographical region (ETAS)
      if (not(PICS_EC_SUBJECT_ATTRIBUT_REGION)) {
        p_inner_ec_request.requestedSubjectAttributes.region := omit;
      }
      log("f_generate_inner_ec_request: PICS_SECPKI_REENROLMENT: ", PICS_SECPKI_REENROLMENT);
      log("f_generate_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter);
      if (PICS_SECPKI_REENROLMENT and (vc_ec_keys_counter > 0)) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential
        log("f_generate_inner_ec_request: This is a re-enrolment: vc_ec_keys_counter= ", vc_ec_keys_counter);
        log("f_generate_inner_ec_request: This is a re-enrolment: vc_ec_hashed_id8[vc_ec_keys_counter - 1]= ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]);
        p_inner_ec_request.itsId := vc_ec_hashed_id8[vc_ec_keys_counter - 1];
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_generate_inner_ec_request: ", p_inner_ec_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_ec_request
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_ec_request_with_wrong_parameters(
                                                               in SequenceOfPsidSsp p_appPermissions,
                                                               in octetstring p_canonical_id := PICS_ITS_S_CANONICAL_ID,
                                                               in Time32 p_start,
                                                               in Duration p_duration,
                                                               in boolean p_alter_private_key := false,
                                                               out octetstring p_private_key,
                                                               out octetstring p_public_key_compressed,
                                                               out integer p_compressed_mode,
                                                               out InnerEcRequest p_inner_ec_request
                                                               ) runs on ItsPkiHttp return boolean {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Local variables
      var Oct32 v_public_key_x;
      var Oct32 v_public_key_y;
      var octetstring v_private_key;
      var octetstring v_public_key_compressed;
      var integer v_compressed_mode;
      var PublicVerificationKey v_public_verification_key;

      log (">>> f_generate_inner_ec_request_with_wrong_parameters");
      // Generate 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_mode) == false) {
        log ("f_generate_inner_ec_request_with_wrong_parameters: failed to generate keys");
        return false;
      }
      if (p_alter_private_key == false) {
        v_private_key := p_private_key;
        v_public_key_compressed := p_public_key_compressed;
        v_compressed_mode := p_compressed_mode;
      } else {
        log ("f_generate_inner_ec_request_with_wrong_parameters: Alter verify private key");
        if (f_generate_key_pair(v_private_key, v_public_key_x, v_public_key_y, v_public_key_compressed, v_compressed_mode) == false) {
          log ("f_generate_inner_ec_request_with_wrong_parameters: failed to generate keys");
          return false;
        }
      }
      // Build the Proof of Possession InnerEcRequest
      log("f_generate_inner_ec_request_with_wrong_parameters: PX_VE_ALG=", PX_VE_ALG);
      if (PX_VE_ALG == e_nist_p256) {
        var EccP256CurvePoint v_eccP256_curve_point;
        if (v_compressed_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_compressed));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        var EccP256CurvePoint v_eccP256_curve_point;
        if (v_compressed_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_compressed));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        var EccP384CurvePoint v_eccP384_curve_point;
        if (v_compressed_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_compressed));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_compressed));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      }
      if (PICS_EC_SUBJECT_ATTRIBUT_ID) {
        p_inner_ec_request := valueof(
                                      m_innerEcRequest(
                                                      p_canonical_id,
                                                      m_publicKeys(
                                                                    v_public_verification_key
                                                                    ),
                                                      m_certificateSubjectAttributes_id_name(
                                                                                              oct2char(PICS_ITS_S_CANONICAL_ID),
                                                                                              p_appPermissions, // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
                                                                                              m_validityPeriod(
                                                                                                              p_start,
                                                                                                              p_duration
                                                                                                              ),
                                                                                              m_geographicRegion_identifiedRegion(
                                                                                                                                  {
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1),
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                                                                    }
                                                                                                                                  ),
                                                                                              PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                                                                              )
                                                      )
                                      );
      } else {
        p_inner_ec_request := valueof(
                                      m_innerEcRequest(
                                                      p_canonical_id,
                                                      m_publicKeys(
                                                                    v_public_verification_key
                                                                    ),
                                                      m_certificateSubjectAttributes_id_omit( // ETSI TS  103 097 Clause 7.2.2 Enrolment credential 
                                                                                              p_appPermissions, // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
                                                                                              m_validityPeriod(
                                                                                                              p_start,
                                                                                                              p_duration
                                                                                                              ),
                                                                                              m_geographicRegion_identifiedRegion(
                                                                                                                                  {
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_1),
                                                                                                                                    m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                                                                    }
                                                                                                                                  ),
                                                                                              PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                                                                              )
                                                      )
                                      );
      }// Remove geographical region (ETAS)
      if (not(PICS_EC_SUBJECT_ATTRIBUT_REGION)) {
        p_inner_ec_request.requestedSubjectAttributes.region := omit;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("f_generate_inner_ec_request_with_wrong_parameters: ", p_inner_ec_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_ec_request_with_wrong_parameters
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_ec_request_signed_for_pop(
                                                        in octetstring p_private_key,
                                                        in InnerEcRequest p_inner_ec_request,
                                                        out Ieee1609Dot2Data p_inner_ec_request_signed_for_pop
    ) runs on ItsPkiHttp return boolean {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Local variables
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var octetstring v_encoded_inner_ec_request;
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var Signature v_signature;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Encode it
      log("f_generate_inner_ec_request_signed_for_pop: encode ", p_inner_ec_request);
      v_encoded_inner_ec_request := bit2oct(encvalue(p_inner_ec_request));
      // Signed the encoded InnerEcRequestSignedForPop
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload(
                                                    m_etsiTs103097Data_unsecured(
                                                                                 v_encoded_inner_ec_request
                                                                                 )
                                                   ),
                                m_headerInfo_inner_pki_request(
                                                               -,
                                                               (f_getCurrentTime() * 1000) //us
                                                               )
                               );
      // Signed the encoded InnerEcRequestSignedForPop
      log("f_generate_inner_ec_request_signed_for_pop: tbs= ", v_tbs);
      log("f_generate_inner_ec_request_signed_for_pop: tbs= ", bit2oct(encvalue(v_tbs)));
      v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
      // Finalyse signed InnerEcRequestSignedForPop
      if (PX_VE_ALG == e_nist_p256) {
        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 if (PX_VE_ALG == e_brainpool_p256_r1) {
        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 (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        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 if (PX_VE_ALG == e_nist_p384) {
        v_signature := valueof(
                               m_signature_ecdsaNistP384(
                                                         m_ecdsaP384Signature(
                                                                              m_eccP384CurvePoint_x_only(
                                                                                                        substr(v_tbs_signed, 0, 48)
                                                                                                        ),
                                                                              substr(v_tbs_signed, 48, 48)
                                                                              )
                                                        )
                               );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_generate_inner_ec_request_signed_for_pop: v_signature= ", v_signature);
      p_inner_ec_request_signed_for_pop := valueof(
                                                   m_etsiTs103097Data_signed(
                                                                             m_signedData(
                                                                                          sha256,
                                                                                          v_tbs,
                                                                                          m_signerIdentifier_self,
                                                                                          v_signature
                                                                                          )
                                                                             )
                                                   );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_generate_inner_ec_request_signed_for_pop: p_inner_ec_request_signed_for_pop= ", p_inner_ec_request_signed_for_pop);
      return true;
    } // End of function f_generate_inner_ec_request_signed_for_pop

    function f_verify_inner_ec_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      out InnerEcRequest p_inner_ec_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 1. Decode content
      v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_inner_ec_request) != 0) {
        log("f_verify_inner_ec_request_signed_for_pop: Failed to decode InnerEcRequest");
        return false;
      } else {
        log("f_verify_inner_ec_request_signed_for_pop: v_inner_ec_request= ", p_inner_ec_request);

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_verify_inner_ec_request_signed_for_pop
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_generate_inner_ec_response(
                                          in octetstring p_inner_ec_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerEcResponse p_inner_ec_response
                                         ) return boolean {
      // Local variables
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Build the Proof of Possession InnerEcResponse
      p_inner_ec_response := valueof(
                                     m_innerEcResponse_ok(
                                                          substr(p_inner_ec_request_hash, 0, 16),
                                                          p_certificate
                                                          )
                                     );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_generate_inner_ec_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group inner_ec_xxx

  group inner_at_xxx {

    function f_generate_inner_at_request(
                                         in Certificate p_aa_certificate,
                                         in SignAlgorithm p_enc_algo := PX_EC_ALG_FOR_EC_SIGN,
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,
                                         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 HashAlgorithm v_hashId;
      var Signature v_signature;
      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: 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: Failed to generate verification key");
        return false;
      }
      log ("f_generate_inner_at_request: AT verification private key: ", p_private_key);
      log ("f_generate_inner_at_request: AT verification public compressed key: ", p_public_key_compressed);
      log ("f_generate_inner_at_request: 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: Failed to generate encryption key");
          return false;
        } else {
          log ("f_generate_inner_at_request: AT encryption private key: ", p_private_enc_key);
          log ("f_generate_inner_at_request: AT encryption public compressed key: ", p_public_compressed_enc_key);
          log ("f_generate_inner_at_request: 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
      // Generate 32 octets length secret key
      v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12));
      log("f_generate_inner_at_request: 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) {