ItsPkiItss_TestCases.ttcn 474 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
/**
 *  @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
                                                                                                                                                                                                                       )
                                                                                                                                                                                           )