ItsPkiItss_TestCases.ttcn 452 KB
Newer Older
/**
 *  @Author   ETSI / STF545 / TTF T025
 *  @version  $Url$
 *            $Id$
 *  @desc     Testcases  file for PKI/ITS-S Protocol
 *  @reference   ETSI TS ITS-00546v006
 *  @copyright   ETSI Copyright Notification
 *               No part may be reproduced except as authorized by written permission.
 *               The copyright and the foregoing restriction extend to reproduction in all media.
 *               All rights reserved.
 */
module ItsPkiItss_TestCases {

  // Libcommon
  import from LibCommon_Time all;
  import from LibCommon_VerdictControl all;
  import from LibCommon_Sync all;
  import from LibCommon_BasicTypesAndValues all;
  import from LibCommon_DataStrings all;

  // LibIts
  import from Ieee1609Dot2BaseTypes language "ASN.1:1997" all;
  import from Ieee1609Dot2 language "ASN.1:1997" all;
  import from EtsiTs102941BaseTypes language "ASN.1:1997" all;
  import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all;
  import from EtsiTs102941TypesAuthorization language "ASN.1:1997" all;
  import from EtsiTs102941TypesAuthorizationValidation language "ASN.1:1997" all;
  import from EtsiTs102941MessagesCa language "ASN.1:1997" all;
  import from EtsiTs102941TrustLists language "ASN.1:1997" all;
  import from EtsiTs103097Module language "ASN.1:1997" all;
  import from Ieee1609Dot2Dot1AcaRaInterface language "ASN.1:1997" all;
  import from Ieee1609Dot2Dot1EeRaInterface language "ASN.1:1997" all;
  import from ETSI_ITS_CDD language "ASN.1:1997" all;
  import from CAM_PDU_Descriptions language "ASN.1:1997" all;

  // LibItsCommon
  import from LibItsCommon_TypesAndValues all;
  import from LibItsCommon_Functions all;
  import from LibItsCommon_TypesAndValues all;
  import from LibItsCommon_ASN1_NamedNumbers all;

  // LibItsGeoNetworking
  import from LibItsGeoNetworking_TypesAndValues all;
  import from LibItsGeoNetworking_Functions all;
  import from LibItsGeoNetworking_Templates all;
  import from LibItsGeoNetworking_Pics all;
  import from LibItsGeoNetworking_Pixits all;
  import from LibItsGeoNetworking_TestSystem all;

  // LibItsCam
  import from LibItsCam_TypesAndValues all;
  import from LibItsCam_Templates all;

  // LibItsSecurity
  import from LibItsSecurity_TypesAndValues all;
  import from LibItsSecurity_TestSystem all;
  import from LibItsSecurity_Templates all;
  import from LibItsSecurity_Functions all;
  import from LibItsSecurity_Pixits all;
  import from LibItsSecurity_Pics all;

  // LibHttp
  import from LibHttp_TypesAndValues all;
  import from LibHttp_Templates all;
  import from LibHttp_Functions all;
  import from LibHttp_TestSystem all;
  import from LibHttp_Pics all;
  import from LibHttp_BinaryTemplates all;

  // LibHelpers
  import from LibHelpers_Functions all;

  // LibItsPki
  import from LibItsPki_TypesAndValues all;
  import from LibItsPki_Templates all;
  import from LibItsPki_Functions all;
  import from LibItsPki_TestSystem all;
  import from LibItsPki_Pics all;
  import from LibItsPki_Pixits all;
  import from LibItsPki_EncdecDeclarations all;

  // ItsPki
  import from ItsPki_Pixits all;

  /**
   * @desc 5.2  ITS-S behaviour
   */
  group itss_behavior {
    group itss_states {
      const charstring c_stInitial := "initial";
      const charstring c_stEnrolled := "enrolled";
      const charstring c_stAuthorized := "authorized";
    }


    group itss_helpers {

      /**
       * @desc Send an HTTP error message 500 Internal error.
       *       Note: To be refined
       */
      function f_send_500_Internal_Error(
                                         in Headers p_headers, 
                                         in template (omit) charstring p_error_message := omit
                                         ) runs on ItsPkiHttp {
        f_http_send(
                    p_headers,
                    m_http_response(
                                    m_http_response_500_internal_error(
                                                                       p_headers
                    )));
      } // End function f_send_500_Internal_Error

      /**
       * @desc The purpose of this function is verify the EC request and extract InnerEcRequest and build the InnerEcResponse for the HTTP response
       *       Note: This function accepts additional parameters to alter the reponse
       */
      function f_verify_http_ec_request_from_iut_itss(
                                                      in Request p_request,
                                                      in Headers p_headers,
                                                      out InnerEcRequest p_inner_ec_request,
                                                      out InnerEcResponse p_inner_ec_response,
                                                      out HttpMessage p_response,
                                                      out integer p_result,
                                                      in template (present) octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
                                                      in template (present) SignerIdentifier p_signer := m_signerIdentifier_self,
                                                      in EnrolmentResponseCode p_force_response_code := ok
                                                      ) runs on ItsPkiHttp {
        // Local variables
        var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
        var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
        var EtsiTs102941Data v_etsi_ts_102941_data;
        var Oct16 v_request_hash;
        var HashedId8 v_bfk_hashed_id8;
        var Oct16 v_aes_enc_key;
        var template (value) HttpMessage v_response;
        var EtsiTs103097Certificate v_ec_certificate;
        var HashedId8 v_ec_certificate_hashed_id8;
        var PublicVerificationKey v_canonical_key;

        log(">>> f_verify_http_ec_request_from_iut_itss: ", p_request);

        p_result := 0;

        if(false == f_get_canonical_itss_key(v_canonical_key)){
          log(">>> f_verify_http_ec_request_from_iut_itss: error getting canonical key");
          v_response := m_http_response(m_http_response_500_internal_error(p_headers));
          p_result := -1;
          return;
        }

        if(not(f_read_pki_request_message(
                                          p_request.body.binary_body.ieee1609dot2_data,
                                          vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/,
                                          v_request_hash, v_aes_enc_key,
                                          v_ieee1609dot2_signed_data,
                                          v_etsi_ts_102941_data
                                          ))) {
          f_http_build_inner_ec_response(-, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
          p_result := -1;
          goto L_Done;
        }

        log("f_verify_http_ec_request_from_iut_itss: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))); // TODO In TITAN, this is the only way to get the unmatching in log
        if (false == match(v_etsi_ts_102941_data.content, mw_enrolmentRequest(mw_innerEcRequestSignedForPop(mw_signedData(sha256, mw_toBeSignedData(-, mw_headerInfo_inner_pki_request), p_signer))))) {
          // Send error message
          f_http_build_inner_ec_response(-, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
          // Set verdict
          p_result := -2;
          goto L_Done;
        }
        // Verify signature of mw_innerEcRequestSignedForPop
        if (false == f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request)) {
          // Send error message
          f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
          v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
          // Set verdict
          p_result := -3;
          goto L_Done;
        }

        log("f_verify_http_ec_request_from_iut_itss: matching: ", match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes({mw_appPermissions(c_its_aid_SCR, ?)})))); // TODO In TITAN, this is the only way to get the unmatching in log
        if (false == match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)})))) {
          // Send error message: Not enrolmentrequest
          f_http_build_inner_ec_response(p_inner_ec_request, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
          v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
          // Set verdict
          p_result := -4;
          goto L_Done;
        }

        // TODO Check ValidityPeriod

        // Send OK message
        log("f_verify_http_ec_request_from_iut_itss: Receive ", p_inner_ec_request);
        if (p_force_response_code == ok) { 
          // Send EC certificate with code ok
          log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter);
          f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
          if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256)) {
            if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0)) {
              vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0;
              vc_ec_compressed_modes[vc_ec_keys_counter] := 0;
            } else {
              vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_1;
              vc_ec_compressed_modes[vc_ec_keys_counter] := 1;
            }
          } else if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1)) {                
            if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) {
              vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0;
              vc_ec_compressed_modes[vc_ec_keys_counter] := 0;
            } else {
              vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1;
              vc_ec_compressed_modes[vc_ec_keys_counter] := 1;
            }
          } else {
            log("*** " & testcasename() & ": FAIL: Not implemented yet ***");
            f_selfOrClientSyncAndVerdict(c_prDone, e_error);
          }
          vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8;
          vc_ec_keys_counter := vc_ec_keys_counter + 1;
          vc_ec_certificates[vc_ec_counter] := v_ec_certificate;
          vc_ec_counter := vc_ec_counter + 1;
          log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter);
        } else {
              log("f_verify_http_ec_request_from_iut_itss: Succeed but force error code ", p_force_response_code);
          f_http_build_inner_ec_response(p_inner_ec_request, p_force_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
        }
        
        label L_Done;
        v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));

        // Set verdict
        p_result := 0;
        p_response := valueof(v_response);
        log("<<< f_verify_http_ec_request_from_iut_itss: p_response: ", p_response);
        log("<<< f_verify_http_ec_request_from_iut_itss: p_result: ", p_result);
      } // End of function f_verify_http_ec_request_from_iut_itss

      /**
       * @desc The purpose of this function is verify the AT request and extract InnerAtRequest and build the InnerAtResponse for the HTTP response
       *       Note: This function accepts additional parameters to alter the reponse
       */
      function f_verify_http_at_request_from_iut_itss(
                                                      in Request p_request,
                                                      in Headers p_headers,
                                                      in template (omit) EtsiTs103097Certificate p_ec_certificate,
                                                      out InnerAtRequest p_inner_at_request,
                                                      out InnerAtResponse p_inner_at_response,
                                                      out HttpMessage p_response,
                                                      out integer p_result,
                                                      in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
                                                      in AuthorizationResponseCode p_force_response_code := ok
                                                      ) runs on ItsPkiHttp {
        // Local variables
        var Ieee1609Dot2Data v_ieee1609dot2_data;
        var EtsiTs102941Data v_etsi_ts_102941_data;
        var Oct16 v_request_hash;
        var Oct16 v_aes_enc_key;
        var template (value) HttpMessage v_response;
        var octetstring v_msg;

        log(">>> f_verify_http_at_request_from_iut_itss:", p_request);

        p_result := 0;

        // 1. Calculate the request Hash
        v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data));
        log(">>> f_verify_http_at_request_from_iut_itss: Encoded request: ", v_msg);
        v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16);
        log(">>> f_verify_http_at_request_from_iut_itss: p_request_hash= ", v_request_hash);
 
        // 2. Decrypt the InnerAtRequest
        if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key
                               p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted
                               vc_aaWholeHash, // salt
                               v_ieee1609dot2_data, // decrypted message
                               v_aes_enc_key)) {
          log("f_verify_http_at_request_from_iut_itss: Failed to decrypt message");
          // Send error message, unable to decypt it
          p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); // Initialize v_reponse with an error message
          // Set verdict
          p_result := -1;
          return;
        }

        // check if signed
        var bitstring v_msg_bit;
        if(ispresent(v_ieee1609dot2_data.content.signedData)) {
          if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data)
            or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData)) {
            log("f_verify_http_at_request_from_iut_itss: Invalid message payload");
            p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
            p_result := -1;
            return;
          }
          log("f_verify_http_at_request_from_iut_itss: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
          v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
        } else {
          if(not ispresent(v_ieee1609dot2_data.content.unsecuredData)) {
            log("f_verify_http_at_request_from_iut_itss: Invalid message payload");
            p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
            p_result := -1;
            return;
          }
          v_msg_bit := oct2bit(v_ieee1609dot2_data.content.unsecuredData);
        }
        if (decvalue(v_msg_bit, v_etsi_ts_102941_data) != 0) {
          log("f_verify_http_at_request_from_iut_itss: Can not decode v_etsi_ts_102941_data");
          p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
          p_result := -1;
          return;
        }

        if (match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest)) == false) {
          // Send error message
          f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
          // Set verdict
          p_result := -2;
          return;
        }

            if (f_verify_inner_at_request_signed_for_pop(v_etsi_ts_102941_data, p_ec_certificate, p_inner_at_request) == false) {
              // Send error message
          f_http_build_authorization_response(p_inner_at_request, its_aa_cantparse, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
          p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)));
              // Set verdict
              p_result := -3;
          return;
        }

        log("f_verify_http_at_request_from_iut_itss: match ", match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)));
              if (match(p_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined
          // Send error message: No authorization request
          f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
          p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)));
                // Set verdict
                p_result := -4;
          return;
        }

        // Verify PoP signature of outer message
        if(ispresent(v_ieee1609dot2_data.content.signedData)){
          log("f_verify_http_at_request_from_iut_itss: v_ieee1609dot2_data.content.signedData.tbsData= ", v_ieee1609dot2_data.content.signedData.tbsData);
          v_msg := bit2oct(encvalue(v_ieee1609dot2_data.content.signedData.tbsData));
          log("f_verify_http_at_request_from_iut_itss: v_msg= ", v_msg);
          if (false == f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_data.content.signedData.signature_, p_inner_at_request.publicKeys.verificationKey)) {
            f_http_build_authorization_response(p_inner_at_request, invalidsignature, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
            p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)));
            // Set verdict
            p_result := -6;
            return;
          }
        }
        
        var PublicVerificationKey v_verification_tag;
        var octetstring v_encoded_tag;
        var octetstring v_key_tag;

        // Build the tag
        v_encoded_tag := bit2oct(encvalue(p_inner_at_request.publicKeys.verificationKey));
        if (ispresent(p_inner_at_request.publicKeys.encryptionKey)) {
          v_encoded_tag := v_encoded_tag & bit2oct(encvalue(p_inner_at_request.publicKeys.encryptionKey));
        }
        // Verify HMAC-SHA256
        log("f_verify_http_at_request_from_iut_itss: v_encoded_tag= ", v_encoded_tag);
        v_key_tag := substr(
                            fx_hmac_sha256( // TODO Rename and use a wrapper function
                                            p_inner_at_request.hmacKey,
                                            v_encoded_tag
                                            ),
                            0,
                            16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
        log("f_verify_http_at_request_from_iut_itss: v_key_tag: ", v_key_tag);
        log("f_verify_http_at_request_from_iut_itss: keyTag= ", p_inner_at_request.sharedAtRequest.keyTag);
        log("f_verify_http_at_request_from_iut_itss: matching: ", match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag));
        if (match(p_inner_at_request.sharedAtRequest.keyTag, v_key_tag) == false) {
          // Send error message: No enrolment request
          f_http_build_authorization_response(p_inner_at_request, its_aa_keysdontmatch, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
          p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)));
          // Set verdict
          p_result := -5;
          return;
        }

        // Send OK message
        log("f_verify_http_at_request_from_iut_itss: Receive ", p_inner_at_request);
        if (p_force_response_code == ok) {
          f_http_build_authorization_response(p_inner_at_request, ok, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
        } else {
          log("f_verify_http_at_request_from_iut_itss: Succeed built force error code ", p_force_response_code);
          f_http_build_authorization_response(p_inner_at_request, p_force_response_code, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
        }
        p_response := valueof(m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers)));
        log("<<< f_verify_http_at_request_from_iut_itss: p_result: ", p_result);
        log("<<< f_verify_http_at_request_from_iut_itss: p_response: ", p_response);
      } // End of function f_verify_http_at_request_from_iut_itss

      /**
       * @desc The purpose of this function is verify the AT request and extract InnerAtRequest , verify ecSignature and build the InnerAtResponse for the HTTP response
       *       Note: This function accepts additional parameters to alter the response
       */
      function f_verify_http_at_request_from_iut_itss_for_ecSignature(
                                                      in Request p_request,
                                                      in Headers p_headers,
                                                      in EtsiTs103097Certificate p_ec_certificate,
                                                      out InnerAtRequest p_inner_at_request,
                                                      out InnerAtResponse p_inner_at_response,
                                                      out HttpMessage p_response,
                                                      out integer p_result,
                                                      out boolean p_contains_ecsignature,
                                                      in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
                                                      in AuthorizationResponseCode p_force_response_code := ok
                                                      ) runs on ItsPkiHttp {
        // Local variables
        var Ieee1609Dot2Data v_ieee1609dot2_data;
        var EtsiTs102941Data v_etsi_ts_102941_data;
        var Ieee1609Dot2Data v_ieee1609dot2_signed_data; //new variable
        var HashedId8 v_ec_certificate_hashed_id8 //new variable
        // var EcHashedId8 vc_ec_hashed_id8; Already defined in LibItsPki_TestSystem
        var Oct16 v_request_hash;
        var HashedId8 v_bfk_hashed_id8;
        var Oct16 v_aes_enc_key;
        var template (value) HttpMessage v_response;
        var octetstring v_msg;


        log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature:", p_request);

        p_result := 0;

        // 1. Calculate the request Hash
        v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data));
        log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature: ", v_msg);
        v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16);
        log(">>> f_verify_http_at_request_from_iut_itss_for_ecSignature: p_request_hash= ", v_request_hash);
 
        // 2. Decrypt the InnerAtRequest
        if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key
                               p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted
                               vc_aaWholeHash, // salt
                               v_ieee1609dot2_data, // decrypted message
                               v_aes_enc_key)) {
          log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Failed to decrypt message");
          // Send error message, unable to decypt it
          p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); // Initialize v_reponse with an error message
          // Set verdict
          p_result := -1;
          return;
        }

        // check if signed
        var bitstring v_msg_bit;
        if(ispresent(v_ieee1609dot2_data.content.signedData)){
          if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data)
            or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData))
          {
            log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Invalid message payload");
            p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
            p_result := -1;
            return;
          }
          log("f_verify_http_at_request_from_iut_itss_for_ecSignature: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
          v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
        } else {
            log("f_verify_http_at_request_from_iut_itss_for_ecSignature: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // to get the unmatching in log
          if (match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest)) == false) {
            // Send error message
          f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, vc_aaPrivateKey, vc_aaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
            // Set verdict
            p_result := -2;
          } else {
            // Extract InnerAtRequest and Verify signature of mw_innerATRequestSigned
            var InnerAtRequest v_inner_at_request := v_etsi_ts_102941_data.content.authorizationRequest;
            log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // to get the unmatching in log
                if (match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined
                  // Send error message: No authorization request
                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                  // Set verdict
                  p_result := -3;
                  } else {

                    // Check ecSignature
                    if (ispresent(v_inner_at_request.ecSignature.ecSignature) == false) {
                        // Send error message: No signed external payload present
                        f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                        v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                        // Set verdict
                        p_result := -4;
                        // Verify ecSignature of mw_ec_signature (encrypted)
                    } else {
                        p_contains_ecsignature  := true;
                        v_ieee1609dot2_signed_data := v_inner_at_request.ecSignature.ecSignature;  
                        
                        log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(v_inner_at_request.ecSignature,mw_ec_signature_ext_payload))                  
                        if (match(v_inner_at_request.ecSignature, mw_ec_signature_ext_payload) == false) {
                            // Send error message: Present signed external payload doesnot match mw_ec_signature_ext_payload template
                            f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                            v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                            // Set verdict
                            p_result := -5;
                        } else {
                            // Check signer in ecSignature
                            if (isvalue(v_ieee1609dot2_signed_data.content.signedData)) {
                                // Verify digest of signerIdentifier_digest
                                if (match(v_ieee1609dot2_signed_data.content.signedData.signer,mw_signerIdentifier_digest) == false) {
                                    var HashedId8 v_digest := v_ieee1609dot2_signed_data.content.signedData.signer.digest; // check if it is hashId8
                                    //log("f_verify_http_at_request_from_iut_itss_for_ecSignature: match ", match(p_ec_certificate.issuer, v_digest));
                                    var bitstring v_enc_value;
                                    var octetstring v_ec_hash;
                                    var Oct8 v_ec_hashed_id8;
                                    v_enc_value := encvalue(p_ec_certificate);
                                    if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) {
                                      v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
                                      v_ec_hashed_id8 := f_hashedId8FromSha256(v_ec_hash);
                                    } else {
                                      v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
                                      v_ec_hashed_id8 := f_hashedId8FromSha384(v_ec_hash);
                                    }

                                    if (match(v_ec_hashed_id8, v_digest) == false) {
                                        // Send error message: Signer not contains HashedId8 of the CERT_EC certificate
                                        f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                        v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                        // Set verdict
                                        p_result := -6;
                                    } else {
                                        // Check _signature in ecSignature
                                        if (isvalue(v_ieee1609dot2_signed_data.content.signedData.signature_)) {
                                            //
                                            var EtsiTs103097Certificate v_certificate;
                                            var EtsiTs102941Data v_etsi_ts_102941_ext_payload_data;
                                            var octetstring v_encoded_tbsData
                                            var Oct32            v_issuer;
                                            v_certificate := v_ieee1609dot2_signed_data.content.signedData.signer.certificate[0];
                                            v_encoded_tbsData := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData));
                                            var octetstring v_enc := bit2oct(encvalue(v_certificate));
                                            v_issuer := f_hashWithSha256(v_enc);
                                            if (f_verifyEcdsa(v_encoded_tbsData,v_issuer,v_ieee1609dot2_signed_data.content.signedData.signature_,v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
                                                // Send error message: Unable to verfy signature using EC's verification public key
                                                f_http_build_authorization_response(p_inner_at_request, invalidsignature, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                                v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                                // Set verdict
                                                p_result := -7;
                                            } else {
                                                // Send OK message
                                                log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Receive ", p_inner_at_request);
                                                if (p_force_response_code == ok) {
                                                    f_http_build_authorization_response(p_inner_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                                } else {
                                                log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Succeed built force error code ", p_force_response_code);
                                                    f_http_build_authorization_response(p_inner_at_request, p_force_response_code, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                                }
                                                v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                            }
                                        } 
                                    }
                                }
                            }
                        }
                    }
                    // Check 
                  }
          }
        }
      }

      /**
       * @desc The purpose of this function is verify the AT request and extract InnerAtRequest , verify encrypted ecSignature and build the InnerAtResponse for the HTTP response
       *       Note: This function accepts additional parameters to alter the response
       */
      function f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature(
                                                      in Request p_request,
                                                      in Headers p_headers,
                                                      in EtsiTs103097Certificate p_ec_certificate,
                                                      out InnerAtRequest p_inner_at_request,
                                                      out InnerAtResponse p_inner_at_response,
                                                      out HttpMessage p_response,
                                                      out integer p_result,
                                                      in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
                                                      in AuthorizationResponseCode p_force_response_code := ok
                                                      ) runs on ItsPkiHttp {
        // Local variables
        var Ieee1609Dot2Data v_ieee1609dot2_data;
        var EtsiTs102941Data v_etsi_ts_102941_data;
        var EtsiTs103097Data  p_decryptedSecuredMessage;
        var EncryptedData   v_encrypted_data;
        var EtsiTs103097Data v_etsi_ts_103097_data;
        var Oct16 v_request_hash;
        var HashedId8 v_bfk_hashed_id8;
        var Oct16 v_aes_enc_key;
        var template (value) HttpMessage v_response;
        var octetstring v_msg;

        log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature:", p_request);

        p_result := 0;

        // 1. Calculate the request Hash
        v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data));
        log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Encoded request: ", v_msg);
        v_request_hash := substr(f_hashWithSha256(v_msg), 0, 16);
        log(">>> f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: p_request_hash= ", v_request_hash);
 
        // 2. Decrypt the InnerAtRequest
        if (false == f_decrypt(vc_aaPrivateEncKey, // AA private encryption key
                               p_request.body.binary_body.ieee1609dot2_data , // data to be decrypted
                               vc_aaWholeHash, // salt
                               v_ieee1609dot2_data, // decrypted message
                               v_aes_enc_key)) {
          log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Failed to decrypt message");
          // Send error message, unable to decypt it
          p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request"))); // Initialize v_reponse with an error message
          // Set verdict
          p_result := -1;
          return;
        }

        // check if signed
        var bitstring v_msg_bit;
        if(ispresent(v_ieee1609dot2_data.content.signedData)){
          if(not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data)
            or not ispresent(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData))
          {
            log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Invalid message payload");
            p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
            p_result := -2;
            return;
          }
          log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
          v_msg_bit := oct2bit(v_ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);

          if (decvalue(v_msg_bit, v_etsi_ts_102941_data) != 0) {
            log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: Can not decode v_etsi_ts_102941_data");
            p_response := valueof(m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")));
            p_result := -3;
            return;
          }
        } else {
          log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: matching: ", match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest))); // to get the unmatching in log
          if (match(v_etsi_ts_102941_data.content, mw_authorizationRequest(mw_innerAtRequest)) == false) {
            // Send error message
            f_http_build_authorization_response(-, its_aa_cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
            // Set verdict
            p_result := -4;
            return;
          } else {
            // Extract InnerAtRequest and Verify signature of mw_innerATRequest
            var InnerAtRequest v_inner_at_request := v_etsi_ts_102941_data.content.authorizationRequest;
            log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature))); // to get the unmatching in log
                if (match(v_inner_at_request, mw_innerAtRequest(mw_publicKeys, -, mw_shared_at_request, mw_ec_signature)) == false) { // TODO To be refined
                  // Send error message: No authorization request
                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                  // Set verdict
                  p_result := -5;
                  return;
                } else {
                    // Check ecSignature
                    var EcSignature v_ecsignature := v_inner_at_request.ecSignature;
                    if (ischosen(v_ecsignature.encryptedEcSignature) == false) {
                        // Send error message: No encrypted ecSignature present
                        f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                        v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                        // Set verdict
                        p_result := -6;
                        return;
                        // Verify ecSignature of mw_ec_signature (encrypted)
                    } else {
                        //v_encrypted_data := v_inner_at_request.ecSignature.encryptedEcSignature; 
                        v_encrypted_data := v_ecsignature.encryptedEcSignature.content.encryptedData; 
                        //var RecipientInfo v_recipientInfo := v_encrypted_data.content.encryptedData.recipients[0];
                        var RecipientInfo v_recipientInfo := v_encrypted_data.recipients[0];
                        var PKRecipientInfo v_pKRecipientInfo := v_recipientInfo.certRecipInfo;
                        log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(v_ecsignature,mw_ec_signature))               
                        if (match(v_ecsignature, mw_ec_signature) == false) {
                            // Send error message: Present encrypted ecSignature doesnot matches with mw_ec_signature template
                            f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                            v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                            // Set verdict
                            p_result := -7;
                            return;
                        } else {
                            // Check in encrypted ecSignature
                            if (isvalue(v_ecsignature.encryptedEcSignature.content.encryptedData)) {
                                var octetstring v_decryptedSecuredMessage;
                                // Verify recipient 
                                if (not isvalue(v_encrypted_data.recipients[0]) and sizeof(v_encrypted_data.recipients) > 1) { // RecipientInfo should not contains certRecipInfo > 1
                                  // Send error message: recipients containing more than one element of type RecipientInfo
                                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                  // Set verdict
                                  p_result := -8;
                                  return;
                                } else {
                                  // RecipientInfo should contains certRecipInfo
                                  if (isvalue(v_recipientInfo.certRecipInfo)) {
                                    // verify that recipientId should be hashedId8 of EA_CERT
                                    log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(vc_eaHashedId8, v_pKRecipientInfo.recipientId));
                                    if (match(vc_eaHashedId8, v_pKRecipientInfo.recipientId) == false) {
                                      // Send error message: recipientId not contains the HashedId8 of the CERT_EA
                                      f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                      v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                      // Set verdict
                                      p_result := -8;
                                      return;
                                    } else {
                                        // Further verify the encKey of supported type  
                                        if (isvalue(v_pKRecipientInfo.encKey)) {
                                          if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) {
                                              var SymmetricCiphertext v_ciphertext := v_encrypted_data.ciphertext;
                                              var Oct16 p_aes_sym_enc_key;
                                              //var octetstring v_decryptedSecuredMessage;
                                              log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: v_ciphertext=", v_ciphertext);
                                                if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0)) {
                                                    v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
                                                                                                                      v_ciphertext.aes128ccm.ccmCiphertext,
                                                                                                                      vc_eaPrivateEncKey,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0,
                                                                                                                      0,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.c,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.t,
                                                                                                                      v_ciphertext.aes128ccm.nonce,
                                                                                                                      vc_eaWholeHash,
                                                                                                                      p_aes_sym_enc_key
                                                                                                                      );
                                                } else if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1)) {
                                                    v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
                                                                                                                      v_ciphertext.aes128ccm.ccmCiphertext,
                                                                                                                      vc_eaPrivateEncKey,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1,
                                                                                                                      1,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.c,
                                                                                                                      v_pKRecipientInfo.encKey.eciesNistP256.t,
                                                                                                                      v_ciphertext.aes128ccm.nonce,
                                                                                                                      vc_eaWholeHash,
                                                                                                                      p_aes_sym_enc_key
                                                                                                                      );
                                                } else {
                                                  // send error msg : Non canonical ephemeral encryption keys
                                                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                                  // Set verdict
                                                  p_result := -7;
                                                  return;
                                                }

                                          } else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1)) {
                                                var SymmetricCiphertext v_ciphertext := v_encrypted_data.ciphertext;
                                                //var octetstring  v_decryptedSecuredMessage;
                                                var Oct16 p_aes_sym_enc_key;
                                                if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0)) {
                                                  v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256(
                                                                                                                        v_ciphertext.aes128ccm.ccmCiphertext,
                                                                                                                        vc_eaPrivateEncKey,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0,
                                                                                                                        0,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
                                                                                                                        v_ciphertext.aes128ccm.nonce,
                                                                                                                        vc_eaWholeHash,                                                                                                                                         p_aes_sym_enc_key
                                                                                                                    );
                                                } else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1)) {
                                                  v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256(
                                                                                                                        v_ciphertext.aes128ccm.ccmCiphertext,
                                                                                                                        vc_eaPrivateEncKey,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1,
                                                                                                                        1,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
                                                                                                                        v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
                                                                                                                        v_ciphertext.aes128ccm.nonce,
                                                                                                                        vc_eaWholeHash,
                                                                                                                        p_aes_sym_enc_key
                                                                                                                    );
                                                } else {
                                                  // send error msg : Non canonical ephemeral encryption keys
                                                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                                  // Set verdict
                                                  p_result := -7;
                                                  return;
                                                }
                                          } else {
                                            // send error message : encKey does not support any type 
                                            f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                            v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                            // Set verdict
                                            p_result := -7;
                                            return;
                                          }
                                        }
                                    }
                                  }
                                }

                                // verify containing cyphertext
                                if (ispresent(v_encrypted_data.ciphertext) == false){
                                  // Send error message: ciphertext doesn't exist
                                  f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                  v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                  // Set verdict
                                  p_result := -8;
                                  return;
                                } else {
                                    //v_ieee1609dot2_signed_data :=  v_encrypted_data.ciphertext;
                                    if (isbound(v_decryptedSecuredMessage)) {
                                      var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
                                      if (decvalue(v_decode, p_decryptedSecuredMessage) != 0) {
                                        log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***");
                                        f_http_build_authorization_response(p_inner_at_request, its_aa_badcontenttype, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                        v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                        // Set verdict
                                        p_result := -7;
                                        return;
                                      } else {
                                        log("f_verify_http_at_request_from_iut_itss_for_encrypted_ecSignature: match ", match(p_decryptedSecuredMessage,mw_etsiTs103097Data_signed));
                                        //check if encrypted data is of type  
                                        if(match(p_decryptedSecuredMessage,mw_etsiTs103097Data_signed)){
                                          // Send OK message
                                          log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Receive ", p_inner_at_request);
                                          if (p_force_response_code == ok) {
                                              f_http_build_authorization_response(p_inner_at_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                          } else {
                                          log("f_verify_http_at_request_from_iut_itss_for_ecSignature: Succeed built force error code ", p_force_response_code);
                                              f_http_build_authorization_response(p_inner_at_request, p_force_response_code, v_request_hash, -, -, v_aes_enc_key, p_inner_at_response, v_ieee1609dot2_data);
                                          }
                                          v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_data)), p_headers));
                                        }
                                      }
                                    }
                                }
                            }
                        }
                    }
                  }
          }
        }
      }

      function f_verify_http_bfk_authorization_request(
                                                       in Request p_request,
                                                       in Headers p_headers,
                                                       in EtsiTs103097Certificate p_ec_certificate,
                                                       out EeRaCertRequest p_bfk_authorization_request,
                                                       out RaEeCertInfo p_ra_ee_cert_info,
                                                       out HttpMessage p_response,
                                                       out integer p_result,
                                                       in template octetstring p_its_id := PICS_ITS_S_CANONICAL_ID,
                                                       in template SignerIdentifier p_signer := m_signerIdentifier_self,
                                                       in EnrolmentResponseCode p_force_response_code := ok
                                                       ) runs on ItsPkiHttp {
        // Local variables
        var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
        var EtsiTs102941Data v_etsi_ts_102941_data;
        var Oct16 v_request_hash;
        var HashedId8 v_bfk_request_hash;
        var Oct16 v_aes_enc_key;
        var template (value) HttpMessage v_response;

        log(">>> f_verify_http_bfk_authorization_request: ", p_request);

        p_result := 0;

        if (f_verify_pki_request_message_with_certificate(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, p_ec_certificate, p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message
          // Send error message
          v_response := m_http_response(m_http_response_ko_no_body(p_headers, 400, "Bad request")); // Initialize v_reponse with an error message
          // Set verdict
          p_result := -1;
        } else { // TODO Add checks on date, 
          log("f_verify_http_bfk_authorization_request: match ", match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationRequest(mw_ee_ra_cert_request))); // TODO In TITAN, this is the only way to get the unmatching in log
          if (match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationRequest(mw_ee_ra_cert_request)) == false) {
            // Send error message
            f_http_build_butterfly_authorization_response_message(p_bfk_authorization_request/*Not required*/, v_bfk_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_ra_ee_cert_info, v_ieee1609dot2_signed_and_encrypted_data);
            // Set verdict
            p_result := -2;
          } else {
            // TODO Add checks
            p_bfk_authorization_request := v_etsi_ts_102941_data.content.butterflyAuthorizationRequest;
            f_http_build_butterfly_authorization_response_message(p_bfk_authorization_request, v_bfk_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_ra_ee_cert_info, v_ieee1609dot2_signed_and_encrypted_data);
            //       vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8;
            //       vc_ec_keys_counter := vc_ec_keys_counter + 1;
            //       vc_ec_certificates[vc_ec_counter] := v_ec_certificate;
            //       vc_ec_counter := vc_ec_counter + 1;
            //       log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter);

            //       
            // Verify signature of mw_innerEcRequestSignedForPop
            // if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, p_inner_ec_request) == false) {
            //   // Send error message
            //   f_http_build_inner_ec_response(p_inner_ec_request/*Not required*/, cantparse, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
            //   v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
            //   // Set verdict
            //   p_result := -3;
            // } else {
            //   log("f_verify_http_bfk_authorization_request: matching: ", match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes({mw_appPermissions(c_its_aid_SCR, ?)})))); // TODO In TITAN, this is the only way to get the unmatching in log
            //   if (match(p_inner_ec_request, mw_innerEcRequest(p_its_id, -, mw_certificate_subject_attributes_optional_assuranceLevel({mw_appPermissions(c_its_aid_SCR, ?)}))) == false) {
            //     // Send error message: Not enrolmentrequest
            //     f_http_build_inner_ec_response(p_inner_ec_request, badcontenttype, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
            //     v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
            //     // Set verdict
            //     p_result := -4;
            //   } else {
            //     // TODO Check ValidityPeriod
            //     // Send OK message
            //     log("f_verify_http_bfk_authorization_request: Receive ", p_inner_ec_request);
            //     if (p_force_response_code == ok) { 
            //       // Send EC certificate with code ok
            //       log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter);
            //       f_http_build_inner_ec_response(p_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
            //       if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256)) {
            //         if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0)) {
            //           vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_0;
            //           vc_ec_compressed_modes[vc_ec_keys_counter] := 0;
            //         } else {
            //           vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256.compressed_y_1;
            //           vc_ec_compressed_modes[vc_ec_keys_counter] := 1;
            //         }
            //       } else if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1)) {                
            //         if (ispresent(p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) {
            //           vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0;
            //           vc_ec_compressed_modes[vc_ec_keys_counter] := 0;
            //         } else {
            //           vc_ec_public_compressed_key[vc_ec_keys_counter] := p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1;
            //           vc_ec_compressed_modes[vc_ec_keys_counter] := 1;
            //         }
            //       } else {
            //         log("*** " & testcasename() & ": FAIL: Not implemented yet ***");
            //         f_selfOrClientSyncAndVerdict(c_prDone, e_error);
            //       }
            //       vc_ec_hashed_id8[vc_ec_keys_counter] := v_ec_certificate_hashed_id8;
            //       vc_ec_keys_counter := vc_ec_keys_counter + 1;
            //       vc_ec_certificates[vc_ec_counter] := v_ec_certificate;
            //       vc_ec_counter := vc_ec_counter + 1;
            //       log("====================================== vc_ec_keys_counter= ", vc_ec_keys_counter);
            //     } else {
            //       log("f_verify_http_bfk_authorization_request: Succeed but force error code ", p_force_response_code);
            //       f_http_build_inner_ec_response(p_inner_ec_request, p_force_response_code, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_ec_certificate, v_ec_certificate_hashed_id8, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
            //     }
                v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), p_headers));
          }
        }

        p_response := valueof(v_response);
        log("<<< f_verify_http_bfk_authorization_request: p_response: ", p_response);
        log("<<< f_verify_http_bfk_authorization_request: p_result: ", p_result);
      } // End of function f_verify_http_bfk_authorization_request

      /**
       * @desc Await ITS CA message using the default AT certificate
       */
      altstep a_await_cam_with_current_cert(
                                            in EtsiTs103097Certificate p_certificate
                                            ) runs on ItsPkiItss {
        [PICS_SEC_SHA256 == true] geoNetworkingPort.receive(
                                                            mw_geoNwInd(
                                                                        mw_geoNwSecPdu(
                                                                                       mw_etsiTs103097Data_signed(
                                                                                                                  mw_signedData(
                                                                                                                                sha256,
                                                                                                                                mw_toBeSignedData(
                                                                                                                                                  mw_signedDataPayload,
                                                                                                                                                  mw_headerInfo_cam
                                                                                                                                                  ),
                                                                                                                                mw_signerIdentifier_certificate(
                                                                                                                                                                mw_etsiTs103097Certificate(
                                                                                                                                                                                           mw_issuerIdentifier_sha256AndDigest(
                                                                                                                                                                                                                               p_certificate.issuer.sha256AndDigest
                                                                                                                                                                                                                               ),
                                                                                                                                                                                           mw_toBeSignedCertificate_at(
                                                                                                                                                                                                                       -,
                                                                                                                                                                                                                       p_certificate.toBeSigned.verifyKeyIndicator
                                                                                                                                                                                                                       )
                                                                                                                                                                                           )
                                                                                                                                                                )
                                                                                                                                )
                                                                                                                  ), 
                                                                                       mw_geoNwShbPacket
                                                                                       ))) {
        }
        [PICS_SEC_SHA384 == true] geoNetworkingPort.receive(
                                                            mw_geoNwInd(
                                                                        mw_geoNwSecPdu(
                                                                                       mw_etsiTs103097Data_signed(
                                                                                                                  mw_signedData(
                                                                                                                                sha384, 
                                                                                                                                mw_toBeSignedData(
                                                                                                                                                  mw_signedDataPayload,
                                                                                                                                                  mw_headerInfo_cam
                                                                                                                                                  ),
                                                                                                                                mw_signerIdentifier_certificate(
                                                                                                                                                                mw_etsiTs103097Certificate(
                                                                                                                                                                                           mw_issuerIdentifier_sha384AndDigest(
                                                                                                                                                                                                                               p_certificate.issuer.sha384AndDigest
                                                                                                                                                                                                                               ),
                                                                                                                                                                                           mw_toBeSignedCertificate_at(
                                                                                                                                                                                                                       -,
                                                                                                                                                                                                                       p_certificate.toBeSigned.verifyKeyIndicator