LibItsPki_Functions.ttcn 426 KB
Newer Older
        } else {
          v_verification_tag.ecsigSm2.compressed_y_1 := p_public_key_compressed;
        }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        log("f_generate_key_tag: Failed to generate HMAC tag");
        return false;
      }
      log("f_generate_key_tag: v_verification_tag= ", v_verification_tag);
      p_encoded_tag := bit2oct(encvalue(v_verification_tag));
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        v_encryption_tag.supportedSymmAlg := aes128Ccm;
        if (PX_EC_ALG_FOR_EC_SIGN == e_nist_p256) {
          if (p_compressed_enc_key_mode == 0) {
            v_encryption_tag.publicKey.eciesNistP256.compressed_y_0 := p_public_compressed_enc_key;
          } else {
            v_encryption_tag.publicKey.eciesNistP256.compressed_y_1 := p_public_compressed_enc_key;
          }
        } else if (PX_EC_ALG_FOR_EC_SIGN == e_brainpool_p256_r1) {
          if (p_compressed_enc_key_mode == 0) {
            v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_0 := p_public_compressed_enc_key;
          } else {
            v_encryption_tag.publicKey.eciesBrainpoolP256r1.compressed_y_1 := p_public_compressed_enc_key;
          }
        } else if (PX_EC_ALG_FOR_EC_SIGN == e_sm2_p256) { // FIXME FSCOM
          if (p_compressed_enc_key_mode == 0) {
            v_encryption_tag.publicKey.ecencSm2.compressed_y_0 := p_public_compressed_enc_key;
          } else {
            v_encryption_tag.publicKey.ecencSm2.compressed_y_1 := p_public_compressed_enc_key;
          }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        } else {
          log("f_generate_key_tag: Failed to generate HMAC tag (enc)");
          return false;
        }
        log("f_generate_key_tag: v_encryption_tag= ", v_encryption_tag);
        p_encoded_tag := p_encoded_tag & bit2oct(encvalue(v_encryption_tag));
      }

      return true;
    } // End of function f_generate_key_tag
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group helpers

  group http { // TODO Split into EnnerEc, Authorization, AuthorizationValidation and bfk
ASN.1 Documenter's avatar
ASN.1 Documenter committed

    function f_http_build_inner_ec_request( // TODO Cleanup parameters
                                           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 {
      var InnerEcRequest v_inner_ec_request;
      var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_result;

      log(">>> f_http_build_inner_ec_request");
      log ("f_http_build_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter);
      log ("f_http_build_inner_ec_request: vc_ec_private_keys: ", vc_ec_private_keys);
      log ("f_http_build_inner_ec_request: vc_ec_counter: ", vc_ec_counter);

ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
        log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_inner_ec_request: ==> EC verification private key: ", p_private_key);
      log ("f_http_build_inner_ec_request: ==> EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_inner_ec_request: ==> EC verification public compressed mode: ", p_compressed_mode);
      // Store enrolment keys for re-enrolment
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      vc_ec_private_keys[vc_ec_keys_counter] := p_private_key;
      vc_ec_public_compressed_key[vc_ec_keys_counter] := p_public_key_compressed;
      vc_ec_compressed_modes[vc_ec_keys_counter] := p_compressed_mode;
      vc_ec_keys_counter := vc_ec_keys_counter + 1;
      // Generate InnerEcRequestSignedForPoP
      if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
        log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerEcRequestSignedForPoP message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_inner_ec_request: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_inner_ec_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.
      log("f_http_build_inner_ec_request: vc_ec_keys_counter: ", vc_ec_keys_counter);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if ((PICS_SECPKI_REENROLMENT == false) or (vc_ec_keys_counter == 1)) { // This is the first enrolment, we used Factory keys
        var octetstring v_private_key;
        if (PX_VE_ALG == e_nist_p256) {
          v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
        } else if (PX_VE_ALG == e_brainpool_p256_r1) {
          v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
        } else if (PX_VE_ALG == e_sm2_p256) {
          v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
        } else if (PX_VE_ALG == e_nist_p384) {
          v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        } else {
          v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
        }
        v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), 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);
      } else { // We use last valid EC certificate
        // TODO Retrieve EC certificate from the first enrolment instead of PX
        log("f_http_build_inner_ec_request: v_ec_private_key: ", vc_ec_private_keys[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_public_compressed_key: ", vc_ec_public_compressed_key[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_compressed_modes: ", vc_ec_compressed_modes[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]);
        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_ec_hashed_id8[vc_ec_keys_counter - 1]/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), 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);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      if (v_result == false) {
        log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_inner_ec_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_inner_ec_request: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_inner_ec_request

    function f_http_build_inner_ec_request_with_wrong_parameters( // TODO Cleanup 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 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 {
      var InnerEcRequest v_inner_ec_request;
      var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_result;

      log(">>> f_http_build_inner_ec_request_with_wrong_parameters");
      if (f_generate_inner_ec_request_with_wrong_parameters(p_appPermissions, p_canonical_id, p_start, p_duration, p_alter_private_key, p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification private key: ", p_private_key);
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed mode: ", p_compressed_mode);
      // Generate InnerEcRequestSignedForPoP
      if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request_with_wrong_parameters: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerEcRequestSignedForPoP message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key);
      log("f_http_build_inner_ec_request_with_wrong_parameters: 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.
      var octetstring v_private_key;
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), 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);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (v_result == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_inner_ec_request_with_wrong_parameters: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_inner_ec_request_with_wrong_parameters: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_inner_ec_request_with_wrong_parameters

    function f_http_build_invalid_enrolment_request(
                                                    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 {
      var InnerEcRequest v_inner_ec_request;
      var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_ret_code;
      var octetstring v_private_key;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_invalid_enrolment_request: EC verification private key: ", p_private_key);
      log ("f_http_build_invalid_enrolment_request: EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_invalid_enrolment_request: EC verification public compressed mode: ", p_compressed_mode);
      // Generate InnerEcRequestSignedForPoP
      if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_invalid_enrolment_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
      // Modify signature to get an error
      if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature)) {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1]));
      } else if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1]));
      } else {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1]));
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerEcRequestSignedForPoP message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_invalid_enrolment_request: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_invalid_enrolment_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.
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      v_ret_code := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), 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);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (v_ret_code == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_invalid_enrolment_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data);
    } // End of function f_http_build_invalid_enrolment_request

    function f_http_build_inner_ec_response(
                                            in template (omit) InnerEcRequest p_inner_ec_request := omit,
                                            in EnrolmentResponseCode p_responseCode := ok,
                                            in Oct16 p_request_hash,
                                            in octetstring p_private_key := ''O,
                                            in octetstring p_digest := ''O,
                                            in Oct16 p_aes_sym_key,
                                            out EtsiTs103097Certificate p_ec_certificate,
                                            out HashedId8 p_ec_certificate_hashed_id8,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                            out InnerEcResponse p_inner_ec_response,
                                            out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                            ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var boolean p_result := false;

      log(">>> f_http_build_inner_ec_response: p_inner_ec_request= ", p_inner_ec_request);
      log(">>> f_http_build_inner_ec_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_inner_ec_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_inner_ec_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_inner_ec_response: p_digest= ", p_digest);
      log(">>> f_http_build_inner_ec_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_inner_ec_response := valueof(
                                       m_innerEcResponse_ko(
                                                            p_request_hash,
                                                            p_responseCode
                                                            )
                                       );
        p_result := true;
      } else {
        // Generate the certificate
        if (f_generate_ec_certificate_for_inner_ec_response(valueof(p_inner_ec_request), p_private_key, p_digest, p_ec_certificate, p_ec_certificate_hashed_id8) == false) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          log("f_http_build_inner_ec_response: Failed to generate the certificate");
          p_inner_ec_response := valueof(
                                         m_innerEcResponse_ko(
                                                              p_request_hash,
                                                              incompleterequest
                                                              )
                                         );
        } else {
          p_inner_ec_response := valueof(
                                         m_innerEcResponse_ok(
                                                              p_request_hash,
                                                              p_ec_certificate
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                              )
                                         );
        }
      }

      // Secure the response
      log("f_http_build_inner_ec_response: p_inner_ec_response= ", p_inner_ec_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_ec_response(p_inner_ec_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_inner_ec_response: Failed to generate the certificate");
        p_inner_ec_response := valueof(
                                       m_innerEcResponse_ko(
                                                            p_request_hash,
                                                            deniedrequest
                                                            )
                                       );
      } else {
        p_result := true;
      }

      return p_result;
    } // End of function f_http_build_inner_ec_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_authorization_request(
                                                in Certificate p_ec_certificate, // Enrolment credentials 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 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 {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 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 octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;

      // Generate the InnerAtRequest
      if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
        log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationRequest ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_authorization_request: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request: ERROR: Non canonical AA certificate ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("*** f_http_build_authorization_request: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // 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_authorization_request: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      }
      log("<<< f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("<<< f_http_build_authorization_request: DEBUG: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_request

    function f_http_build_authorization_request_with_wrong_private_key(
                                                                       in Certificate p_ec_certificate, // Enrolment credentials 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 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 {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 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 octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;

      // Generate the InnerAtRequest
      if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
        log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate AuthorizationRequest ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_authorization_request_with_wrong_private_key: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      /***
          Use the wrong private key
      ***/
      if (f_extract_enc_key(vc_eaCertificate/*Insted of vc_aaCertificate/*/, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Non canonical EA certificate ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // 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_authorization_request_with_wrong_private_key: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request_with_wrong_private_key: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      }
      log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_request_with_wrong_private_key

    function f_http_build_authorization_request_with_wrong_parameters(
                                                                      in Certificate p_ec_certificate, // Enrolment credentials certificate
                                                                      in octetstring p_ec_private_key,
                                                                      in boolean p_alter_pop_signature := false,
                                                                      in boolean p_alter_hmac := false,
                                                                      in boolean p_alter_signer_digest := false,
                                                                      in boolean p_alter_pks_recipient := false,
                                                                      in boolean p_alter_enc_key := false,
                                                                      in boolean p_alter_ea_id := 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 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 {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 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 octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;
      var boolean v_ret_code;

      // Generate the InnerAtRequest
      if (p_alter_ea_id == true) {
        var HashedId8 v_ea_hashed_id8 := vc_eaHashedId8;
        v_ea_hashed_id8[0] := 'bb'O;
        v_ea_hashed_id8[1] := 'cc'O;
        log("f_http_build_authorization_request_with_wrong_parameters: Altered eaId= ", v_ea_hashed_id8);
        v_ret_code := f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, v_ea_hashed_id8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request);
      } else {
        v_ret_code := f_generate_inner_at_request_with_wrong_parameters(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_alter_hmac, p_alter_signer_digest, p_start, p_duration, p_generation_time, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request);
      }
      if (v_ret_code == false) {
        log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate AuthorizationRequest ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_authorization_request_with_wrong_parameters: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Non canonical AA certificate ***");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // 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_authorization_request_with_wrong_parameters: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_alter_pop_signature, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request_with_wrong_parameters: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***");
          return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        }
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      if (p_alter_enc_key == true) {
        /***
            Alter encryption key to prevent decryption
         ***/
        if (ischosen(p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256)) {
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[1] := 'aa'O;
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[2] := 'bb'O;
        } else {
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[1] := 'aa'O;
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[2] := 'bb'O;
        }
        log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered enc key= ", p_ieee1609dot2_signed_and_encrypted_data);
      }
      if (p_alter_pks_recipient == true) {
        p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].pskRecipInfo := int2oct(314259265, 8); // NOT equal to the HashedId8 of the certificate CERT_AA
        log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered pskRecipInfo= ", p_ieee1609dot2_signed_and_encrypted_data);
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_request_with_wrong_parameters

    function f_http_build_authorization_response(
                                                 in template (omit) InnerAtRequest p_inner_at_request := omit,
                                                 in AuthorizationResponseCode p_responseCode := ok,
                                                 in Oct16 p_request_hash,
                                                 in octetstring p_private_key := ''O,
                                                 in octetstring p_digest := ''O,
                                                 in Oct16 p_aes_sym_key,
                                                 out InnerAtResponse p_inner_at_response,
                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                 ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var EtsiTs103097Certificate v_at_certificate;
      var boolean v_result := false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      log(">>> f_http_build_authorization_response: p_inner_at_request= ", p_inner_at_request);
      log(">>> f_http_build_authorization_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_authorization_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_authorization_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_authorization_response: p_digest= ", p_digest);
      log(">>> f_http_build_authorization_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_inner_at_response := valueof(
                                       m_innerAtResponse_ko(
                                                            p_request_hash,
                                                            p_responseCode
                                                            )
                                       );
        v_result := true;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        // Generate the certificate
        if (f_generate_at_certificate_for_inner_at_response(valueof(p_inner_at_request), p_private_key, p_digest, v_at_certificate) == false) {
          log("f_http_build_authorization_response: Failed to generate the certificate");
          p_inner_at_response := valueof(
                                         m_innerAtResponse_ko(
                                                              p_request_hash,
                                                              its_aa_incompleterequest
                                                              )
                                         );
        } else {
          p_inner_at_response := valueof(
                                         m_innerAtResponse_ok(
                                                              p_request_hash,
                                                              v_at_certificate
                                                              )
                                         );
        }
      }

      // Secure the response
      log("f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_at_response(p_inner_at_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_authorization_response: Failed to generate the certificate");
        p_inner_at_response := valueof(
                                       m_innerAtResponse_ko(
                                                            p_request_hash,
                                                            its_aa_deniedpermissions
                                                            )
                                       );
      } else {
        v_result := true;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }

      log("<<< f_http_build_authorization_response: v_result= ", v_result);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response);
      return v_result;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_authorization_validation_request(
                                                           in InnerAtRequest p_inner_at_request,
                                                           in octetstring p_public_key_compressed,
                                                           in integer p_compressed_key_mode,
                                                           in octetstring p_private_enc_key,
                                                           in octetstring p_public_compressed_enc_key,
                                                           in integer p_compressed_enc_key_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 return boolean {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Local variables
      var AuthorizationValidationRequest v_authorization_validation_request;
      var bitstring v_authorization_validation_request_msg;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;

      log(">>> f_http_build_authorization_validation_request");

      // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage
      v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest;
      // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop
      v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature;
      // Secure the InnerAtRequest message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("f_http_build_authorization_validation_request: Non canonical EA certificate");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_authorization_validation_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_authorization_validation_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.
      log("f_http_build_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8);
      log("f_http_build_authorization_validation_request: p_salt: ", p_salt);
      if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
        log("f_http_build_authorization_validation_request: Failed to generate Authorization Request");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("f_http_build_authorization_validation_request: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_validation_request

    function f_http_build_invalid_authorization_validation_request(
                                                                   in InnerAtRequest p_inner_at_request,
                                                                   in octetstring p_public_key_compressed,
                                                                   in integer p_compressed_key_mode,
                                                                   in octetstring p_private_enc_key,
                                                                   in octetstring p_public_compressed_enc_key,
                                                                   in integer p_compressed_enc_key_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 return boolean {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Local variables
      var AuthorizationValidationRequest v_authorization_validation_request;
      var bitstring v_authorization_validation_request_msg;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;

      log(">>> f_http_build_invalid_authorization_validation_request");

      // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage
      v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest;
      // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop
      v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature;
      // Secure the InnerAtRequest message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("f_http_build_invalid_authorization_validation_request: Non canonical EA certificate");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_invalid_authorization_validation_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_invalid_authorization_validation_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.
      log("f_http_build_invalid_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8);
      log("f_http_build_invalid_authorization_validation_request: p_salt: ", p_salt);
      if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)),
                                                             vc_eaHashedId8/*recipientId*/, v_public_enc_key,
                                                             v_compressed_enc_key_mode, p_salt,
                                                             bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))),
                                                             PX_EC_ALG_FOR_ATV, true, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("f_http_build_invalid_authorization_validation_request: Failed to generate Authorization Request");
        return false;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("f_http_build_invalid_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("f_http_build_invalid_authorization_validation_request: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_invalid_authorization_validation_request

    function f_http_build_authorization_validation_response(
                                                            in SharedAtRequest p_shared_at_request,
                                                            in AuthorizationValidationResponseCode p_responseCode := ok,
                                                            in Oct16 p_request_hash,
                                                            in octetstring p_private_key := ''O,
                                                            in octetstring p_digest := ''O,
                                                            in Oct16 p_aes_sym_key,
                                                            out AuthorizationValidationResponse p_authorization_validation_response,
                                                            out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                            ) return boolean {
      // 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;
ASN.1 Documenter's avatar
ASN.1 Documenter committed

      log(">>> f_http_build_authorization_validation_response: p_shared_at_request= ", p_shared_at_request);
      log(">>> f_http_build_authorization_validation_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_authorization_validation_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_authorization_validation_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_authorization_validation_response: p_digest= ", p_digest);
      log(">>> f_http_build_authorization_validation_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_authorization_validation_response := valueof(
                                                       m_authorizationValidationResponse_ko(
                                                                                            p_request_hash,
                                                                                            p_responseCode
                                                                                            )
                                                       );
        v_result := true;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        p_authorization_validation_response := valueof(m_authorizationValidationResponse_ok(
                                                                                            p_request_hash,
                                                                                            p_shared_at_request.requestedSubjectAttributes
                                                                                            )
                                                        );
      }
      log("f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response);
      // Encapsulte authorization validation response into EtsiTs102941Data
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_response(p_authorization_validation_response)));
      // Secure the response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      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_authorization_validation_response: Failed to generate the certificate");
        p_authorization_validation_response := valueof(
                                                       m_authorizationValidationResponse_ko(
                                                                                            p_request_hash,
                                                                                            deniedpermissions
                                                                                            )
                                                       );
      } else {
        v_result := true;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      log("<<< f_http_build_authorization_validation_response: v_result= ", v_result);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response);
      return v_result;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_validation_response

    function f_http_build_butterfly_authorization_request_message( // TODO Cleanup parameters
                                                                  in Oct32 p_private_key_ec,
                                                                  in HashedId8 p_ec_cert_hashed_id8,
                                                                  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 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,
                                                                  out EeRaCertRequest p_ee_ra_cert_request
                                                                  ) runs on ItsPkiHttp return boolean {

      var Ieee1609Dot2Data v_ee_ra_cert_request_signed;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_result;

      log(">>> f_http_build_butterfly_authorization_request_message: p_private_key_ec: ", p_private_key_ec);
      log(">>> f_http_build_butterfly_authorization_request_message: p_ec_cert_hashed_id8: ", p_ec_cert_hashed_id8);

      // Generate EeRaCertRequest
      if (f_generate_ee_ra_cert_request(p_caterpillar_private_key, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode, p_caterpillar_enc_private_key, p_caterpillar_enc_public_key_compressed, p_caterpillar_enc_compressed_mode, p_ee_ra_cert_request) == false) {
        log("*** f_http_build_butterfly_authorization_request_message: ERROR: Failed to generate InnerEcRequest ***");
        return false;
      }
      log ("f_http_build_butterfly_authorization_request_message: p_ee_ra_cert_request: ", p_ee_ra_cert_request);

      // Secure EeRaCertRequest
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_butterfly_authorization_request_message: ERROR: Non canonical EA certificate ***");
        return false;
      }
      log("f_http_build_butterfly_authorization_request_message: Public encryption key: ", v_public_enc_key);
      log("f_http_build_butterfly_authorization_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.
      v_result := f_build_pki_secured_request_message_signed_with_pop(p_private_key_ec, valueof(m_signerIdentifier_digest(p_ec_cert_hashed_id8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_cert_request(p_ee_ra_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_authorization_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        return false;
      } else {
        log("f_http_build_butterfly_authorization_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_butterfly_authorization_request_message: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_butterfly_authorization_request_message

    function f_http_build_butterfly_authorization_response_message(
                                                                   in EeRaCertRequest p_ee_ra_cert_request,
                                                                   in HashedId8 p_request_hash,
                                                                   in octetstring p_private_key := ''O,
                                                                   in octetstring p_digest := ''O,
                                                                   in Oct16 p_aes_sym_key,
                                                                   out RaEeCertInfo p_ra_ee_cert_info,
                                                                   out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                                   ) runs on ItsPkiHttp return boolean {
      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_authorization_response_message: p_ee_ra_cert_request= ", p_ee_ra_cert_request);
      log(">>> f_http_build_butterfly_authorization_response_message: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_butterfly_authorization_response_message: p_private_key= ", p_private_key);
      log(">>> f_http_build_butterfly_authorization_response_message: p_digest= ", p_digest);
      log(">>> f_http_build_butterfly_authorization_response_message: p_aes_sym_key= ", p_aes_sym_key);


      // Generate EeRaCertRequest
      if (f_generate_ra_ee_cert_info(p_ee_ra_cert_request, p_request_hash, p_ra_ee_cert_info) == false) {
        log("*** f_http_build_butterfly_authorization_response_message: ERROR: Failed to generate InnerEcRequest ***");
        return v_result;
      }
      log ("f_http_build_butterfly_authorization_response_message: p_ra_ee_cert_info: ", p_ra_ee_cert_info);

      // Secure the response
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_ra_ee_cert_info(p_ra_ee_cert_info)));
      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_authorization_response_message: Failed to generate the certificate");
        return v_result;
      } else {
        v_result := true;
      }

      log("<<< f_http_build_butterfly_authorization_response_message: v_result= ", v_result);
      return v_result;
    } // End of function f_http_build_butterfly_authorization_response_message

    function f_http_build_butterfly_cert_request(
                                                 in EeRaCertRequest p_ee_ra_cert_request,
                                                 in octetstring p_private_key := ''O,
                                                 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 RaAcaCertRequest p_ra_aca_cert_request,
                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                 out Oct32 p_request_hash
                                                 ) runs on ItsPkiHttp return boolean {
      // Local variables
      var Ieee1609Dot2Data v_ra_aca_cert_request_signed;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_result;

      log(">>> f_http_build_butterfly_cert_request: p_ee_ra_cert_request= ", p_ee_ra_cert_request);
      log(">>> f_http_build_butterfly_cert_request: p_private_key= ", p_private_key);

      p_ra_aca_cert_request := valueof(
                                        m_ra_aca_cert_request(
                                                              p_ee_ra_cert_request.generationTime,
                                                              p_ee_ra_cert_request.type_,
                                                              '00000000'B, // FIXME What does it mean? ETSI TS 102 941 V2.1.1 (2021-10) Figure 27 Bullet 1 dash #3
                                                              p_ee_ra_cert_request.tbsCert,
                                                              -,
                                                              omit // FIXME Shall be the cocoon key that shall be derived by the EA ETSI TS 102 941 V2.1.1 (2021-10) Figure 27 Bullet 1 dash #4
                                        ));
      log("f_http_build_butterfly_cert_request: p_ra_aca_cert_request= ", p_ra_aca_cert_request);

      // 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