ItsPki_TestCases.ttcn 1.03 MB
Newer Older
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_05_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_05_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_05_BV

      /**
       * @desc CaCertificateRequest.requestedSubjectAttributes shall contain the requested certificates attributes as specified in ETSI TS 103 097, clause 7.2.4
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to send a CACertificateRequestMessage
       *         }
       *         then {
       *             the IUT sends a CACertificateRequestMessage
       *                 containing CaCertificateRequest
       *                     containing requestedSubjectAttributes
       *                         as specified in ETSI TS 103 097, clause 7.2.4
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_06_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       *            ETSI TS 103 097, clause 7.2.4
       */
      testcase TC_SECPKI_EA_CERTGEN_06_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_06_BV

      /**
       * @desc EtsiTs103097Data-Signed.tbsData contains the EtsiTs102941Data as payload and the headerInfo containing psid and generationTime
       *       The psid shall be set to "secured certificate request" as assigned in ETSI TS 102 965 and the generationTime shall be present
       *       All other components of the component tbsdata.headerInfo are not used and absent
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to send a CACertificateRequestMessage
       *         }
       *         then {
       *             the IUT sends a CACertificateRequestMessage
       *                 containing headerInfo
       *                     containing psid
       *                         indicating SEC_CERT_REQ
       *                     and containing generationTime
       *                     and not containing any other component of tbsdata.headerInfo
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_07_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_07_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_07_BV

      /**
       * @desc If the current private key has reached its end of validity period or is revoked, the SubCA shall restart the initial certificate application process
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to perform a CA certificate rekeying procedure
       *             and SubCA certificate is no longer valid (due to end of validity or revocation)
       *         }
       *         then {
       *             the IUT switches to the ''initial' state
       *             and sends a CACertificateRequestMessage
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_08_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_08_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_08_BV

      /**
       * @desc For the re-keying application to the RCA (CaCertificateRekeyingMessage), an EtsiTs103097Data-Signed structure is built, containing: hashId, tbsData, signer and signature
       *       The hashId shall indicate the hash algorithm to be used as specified in ETSI TS 103 097
       *       The signer declared as a digest, containing the hashedId8 of the EA certificate and the signature over tbsData is computed using the currently valid private key corresponding to the EA certificate (outer signature)
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to send a CACertificateRequestMessage
       *         }
       *         then {
       *             the IUT sends a CACertificateRequestMessage
       *                 containing EtsiTs103097Data-Signed structure
       *                     containing hashId
       *                         indicating the hash algorithm to be used
       *                     and containing tbsData
       *                     and containing signer
       *                         containing digest
       *                             indicating HashedId8 of the SubCA certificate (CERT)
       *                     and containing signature
       *                         computed over tbsData
       *                             using the private key corresponding to CERT
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_09_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       *            ETSI TS 103 097, clause 7
       */
      testcase TC_SECPKI_EA_CERTGEN_09_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_09_BV

      /**
       * @desc The (outer) tbsData of the CACertificateRekeyingMessage shall contain the CaCertificateRequestMessage as payload
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to perform a CA certificate rekeying procedure
       *         }
       *         then {
       *             the IUT sends a CACertificateRekeyingMessage
       *                 containing EtsiTs103097Data-Signed structure
       *                     containing tbsData
       *                         containing CaCertificateRequestMessage
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_10_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_10_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_10_BV

      /**
       * @desc The (outer) tbsData of the CACertificateRekeyingMessage shall contain a headerInfo containing psid and generationTime. 
       *       The psid shall be set to "secured certificate request" as assigned in ETSI TS 102 965 and the generationTime shall be present
       *       All other components of the component tbsdata.headerInfo are not used and absent
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to perform a CA certificate rekeying procedure
       *         }
       *         then {
       *             the IUT sends a CACertificateRekeyingMessage
       *                 containing tbsData
       *                     containing psid
       *                         indicating SEC_CERT_REQ
       *                     and containing generationTime
       *                     and not containing any other component of tbsdata.headerInfo
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_11_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_11_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_11_BV

      /**
       * @desc Check that the CaCertificateRekeyingMessage is permitted by CA certificate
       * <pre>
       * Pics Selection: 
       * Initial conditions: 
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is requested to perform a CA certificate rekeying procedure
       *         }
       *         then {
       *             the IUT sends a CACertificateRekeyingMessage
       *                 containing EtsiTs103097Data-Signed structure
       *                     containing tbsData
       *                     and containing signer
       *                         containing digest
       *                             indicating HashedId8 of the CA certificate
       *                         containing appPermissions
       *                             containing an item of type PsidSsp
       *                                 containing psid
       *                                     indicating AID_CERT_REQ
       *                                 and containing ssp
       *                                     containing opaque[0] (version)
       *                                         indicating 1
       *                                     containing opaque[1] (value)
       *                                         indicating 'CA Certificate Response' (bit 6) set to 1
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_CERTGEN_12_BV
       * @reference ETSI TS 102 941, clause 6.2.1
       */
      testcase TC_SECPKI_EA_CERTGEN_12_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
        setverdict(inconc);
      } // End of testcase TC_SECPKI_EA_CERTGEN_12_BV

    } // End of group ca_certificate_request

    // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.4.6  Authorization using butterfly key expansion mechanism
    group ea_authorization_with_bfk {
      // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.4.6.1  Butterfly authorization response
      group ea_bfk_auth_response {

        /**
        * @desc Check that the EA sends the butterfly authorization respond message after receiving of the butterfly authorization request
        *       Check that this message is signed with EA certificate
        * <pre>
        * Pics Selection: PICS_IUT_EA_ROLE
        * Initial conditions:
        *     the EA in 'operational' state
        *         authorized with CERT_EA certificate
        *     and the ITS-S in 'enrolled' state
        * Expected behaviour:
        *     ensure that {
        *         when {
        *             the IUT receives a ButterflyAuthorizationRequestMessage message
        *         }
        *         then {
        *             the IUT send an EtsiTs103097Data to the ITS-S
        *                 containing content.signedData
        *                     containing tbsData
        *                         containing headerInfo
        *                             containing psid
        *                                 indicating AID_PKI_CERT_REQUEST
        *                              and containing generationTime
        *                              and not containing any other field
        *                         and containing payload.data
        *                              indicating EtsiTs102941Data
        *                                   containing version
        *                                      indicating ‘1’
        *                                  and containing content
        *                                      containing butterflyCertificateResponse
        *                         and containing signer
        *                             containing digest
        *                                  indicating HashedId8 of the CERT_EA
        *                     and containing signature
        *                         validated using CERT_EA verification public key
        *         }
        *     }
        * </pre>
        * 
        * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_BFK_AUTH_01_BV
        * @reference ETSI TS 102 941 [1], clause 6.2.3.5.3
        */
        testcase TC_SECPKI_EA_BFK_AUTH_01_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
          // Local variables
          var octetstring v_private_key_ec;
          var octetstring v_public_compressed_key_ec;
          var integer v_compressed_key_mode_ec;
          var HashedId8 v_ec_cert_hashed_id8;
          var InnerEcResponse v_inner_ec_response;
          var octetstring v_caterpillar_private_key;
          var octetstring v_caterpillar_public_key_compressed;
          var integer v_caterpillar_compressed_mode;
          var octetstring v_caterpillar_enc_private_key;
          var octetstring v_caterpillar_enc_public_key_compressed;
          var integer v_caterpillar_enc_compressed_mode;
          var EeRaCertRequest v_ee_ra_cert_request;
          var Oct32 v_request_hash;
          var Oct16 v_encrypted_sym_key;
          var Oct16 v_aes_sym_key;
          var HashedId8 v_aes_sym_key_hashed_id8;
          var Oct16 v_authentication_vector;
          var Oct12 v_nonce;
          var octetstring v_salt;
          var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
          var Headers v_headers;
          var HttpMessage v_response;
          // Test control
          if (not PICS_IUT_EA_ROLE) {
            log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***");
            setverdict(inconc);
            stop;
          }

          // Test component configuration
          f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID);

          // Test adapter configuration

          // Preamble
          // Trigger an enrolment request
          if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_ec_cert_hashed_id8, v_inner_ec_response, -, true) == false) {
            log("*** " & testcasename() & ": INCONC: Enrolment failed ***");
            f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
          } else {
            log("*** " & testcasename() & ": INFO: Enrolment succeed ***");
          }
          log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response);
          log("*** " & testcasename() & ": DEBUG: = ", v_private_key_ec);

          // Generate an ButterflyAutorizationRequest
          f_http_build_butterfly_authorization_request_message(v_private_key_ec, v_ec_cert_hashed_id8, v_caterpillar_private_key, v_caterpillar_public_key_compressed, v_caterpillar_compressed_mode, v_caterpillar_enc_private_key, v_caterpillar_enc_public_key_compressed, v_caterpillar_enc_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash, v_ee_ra_cert_request);
          log("*** " & testcasename() & ": DEBUG: v_ee_ra_cert_request= ", v_ee_ra_cert_request);
          log("*** " & testcasename() & ": DEBUG: v_caterpillar_private_key= ", v_caterpillar_private_key);
          v_aes_sym_key_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256('80'O & v_aes_sym_key)); // Used to match the response
          f_init_default_headers_list(-, "bfk_auth_request", v_headers);
          f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);

          // Test Body
          f_http_send(
                      v_headers,
                      m_http_request(
                                    m_http_request_post(
                                                        PICS_HTTP_POST_URI_BFK_AUTH,
                                                        v_headers,
                                                        m_http_message_body_binary(
                                                                                   m_binary_body_ieee1609dot2_data(
                                                                                                                   v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                   )))));
          tc_ac.start;
          alt {
            [] a_await_ec_http_response_from_iut(
                                                 mw_http_response(
                                                                  mw_http_response_ok(
                                                                                      mw_http_message_body_binary(
                                                                                                                  mw_binary_body_ieee1609dot2_data(
                                                                                                                                                   mw_butterflyAuthorizationResponseMessage(
                                                                                                                                                                                            mw_signedData(
                                                                                                                                                                                                          sha256,
                                                                                                                                                                                                          mw_toBeSignedData,
                                                                                                                                                                                                          m_signerIdentifier_digest(vc_eaHashedId8)
                                                                  )))))),
              log("*** " & testcasename() & ": PASS: Signed message received ***");
              f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement

          // Postamble
          f_cfHttpDown();

        } // End of testcase TC_SECPKI_EA_BFK_AUTH_01_BV

        /**
        * @desc Check that the butterfly authorization respond message, sent by EA, contains all necessary fields
        * <pre>
        * Pics Selection: PICS_IUT_EA_ROLE
        * Initial conditions:
        *     the EA in 'operational' state
        *         authorized with CERT_EA certificate
        *     and the ITS-S in 'enrolled' state
        * Expected behaviour:
        *     ensure that {
        *         when {
        *             the IUT receives a ButterflyAuthorizationRequestMessage message (REQ)
        *         }
        *         then {
        *             the IUT send to the ITS-S a ButterflyAuthorizationResponseMessage
        *                 containing butterflyCertificateResponse
        *                     containing RaEeCertInfo
        *                         containing version
        *                             indicating 2
        *                         and containing generationTime
        *                             indicating value between REQ_TIME and the current time
        *                         and containing currentI
        *                         and containing requestHash
        *                              indicating the left-most 16 octets of the SHA256 digest of the REQ
        *                         and containing nextDlTime
        *                         and not containing acpcTreeId
        *         }
        *     }
        * </pre>
        * 
        * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_BFK_AUTH_02_BV
        * @reference ETSI TS 102 941 [1], clause 6.2.3.5.3
        */
        testcase TC_SECPKI_EA_BFK_AUTH_02_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
          // Local variables
          var octetstring v_private_key_ec;
          var octetstring v_public_compressed_key_ec;
          var integer v_compressed_key_mode_ec;
          var HashedId8 v_ec_cert_hashed_id8;
          var InnerEcResponse v_inner_ec_response;
          var octetstring v_caterpillar_private_key;
          var octetstring v_caterpillar_public_key_compressed;
          var integer v_caterpillar_compressed_mode;
          var octetstring v_caterpillar_enc_private_key;
          var octetstring v_caterpillar_enc_public_key_compressed;
          var integer v_caterpillar_enc_compressed_mode;
          var EeRaCertRequest v_ee_ra_cert_request;
          var Oct32 v_request_hash;
          var Oct16 v_encrypted_sym_key;
          var Oct16 v_aes_sym_key;
          var HashedId8 v_aes_sym_key_hashed_id8;
          var Oct16 v_authentication_vector;
          var Oct12 v_nonce;
          var octetstring v_salt;
          var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
          var Headers v_headers;
          var HttpMessage v_response;

          // Test control
          if (not PICS_IUT_EA_ROLE) {
            log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***");
            setverdict(inconc);
            stop;
          }

          // Test component configuration
          f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID);

          // Test adapter configuration

          // Preamble
          // Trigger an enrolment request
          if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_ec_cert_hashed_id8, v_inner_ec_response, -, true) == false) {
            log("*** " & testcasename() & ": INCONC: Enrolment failed ***");
            f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
          } else {
            log("*** " & testcasename() & ": INFO: Enrolment succeed ***");
          }
          log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response);
          log("*** " & testcasename() & ": DEBUG: = ", v_private_key_ec);

          // Generate an ButterflyAutorizationRequest
          f_http_build_butterfly_authorization_request_message(v_private_key_ec, v_ec_cert_hashed_id8, v_caterpillar_private_key, v_caterpillar_public_key_compressed, v_caterpillar_compressed_mode, v_caterpillar_enc_private_key, v_caterpillar_enc_public_key_compressed, v_caterpillar_enc_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash, v_ee_ra_cert_request);
          log("*** " & testcasename() & ": DEBUG: v_ee_ra_cert_request= ", v_ee_ra_cert_request);
          log("*** " & testcasename() & ": DEBUG: v_caterpillar_private_key= ", v_caterpillar_private_key);
          v_aes_sym_key_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256('80'O & v_aes_sym_key)); // Used to match the response
          f_init_default_headers_list(-, "bfk_auth_request", v_headers);
          f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);

          // Test Body
          f_http_send(
                      v_headers,
                      m_http_request(
                                    m_http_request_post(
                                                        PICS_HTTP_POST_URI_BFK_AUTH,
                                                        v_headers,
                                                        m_http_message_body_binary(
                                                                                   m_binary_body_ieee1609dot2_data(
                                                                                                                   v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                   )))));
          tc_ac.start;
          alt {
            [] a_await_ec_http_response_from_iut(
                                                 mw_http_response(
                                                                  mw_http_response_ok(
                                                                                      mw_http_message_body_binary(
                                                                                                                  mw_binary_body_ieee1609dot2_data(
                                                                                                                                                   mw_butterflyAuthorizationResponseMessage(
                                                                                                                                                                                            mw_signedData(
                                                                                                                                                                                                          sha256,
                                                                                                                                                                                                          mw_toBeSignedData,
                                                                                                                                                                                                          m_signerIdentifier_digest(vc_eaHashedId8)
                                                                  )))))),
              var octetstring v_tbs := bit2oct(encvalue(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData));
              if (f_verifyEcdsa(v_tbs, vc_eaWholeHash256, v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.signature_, vc_eaCertificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
                log("*** " & testcasename() & ": FAIL: Failed to verify signature message ***");
                f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
              } else {
                var bitstring v_etsi_ts_102941_data_content_msg := oct2bit(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
                var EtsiTs102941MessagesCa.EtsiTs102941Data v_etsi_ts_102941_data;
                if (decvalue(v_etsi_ts_102941_data_content_msg, v_etsi_ts_102941_data) != 0) {
                  log("*** " & testcasename() & ": FAIL: Failed to decode message ***");
                  f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
                } else {
                  log("*** " & testcasename() & ": DBG: v_etsi_ts_102941_data: ", v_etsi_ts_102941_data);
                  log("*** " & testcasename() & ": INFO: match ", match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationResponse(mw_ra_ee_cert_info)), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
                  if (not(match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationResponse(mw_ra_ee_cert_info)))) {
                    log("*** " & testcasename() & ": FAIL: Unexpected message ***");
                    f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
                  } else {
                    log("*** " & testcasename() & ": PASS: ButterflyAuthorizationResponseMessage received ***");
                    f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
                  }
                }
              }
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement

          // Postamble
          f_cfHttpDown();

        } // End of testcase TC_SECPKI_EA_BFK_AUTH_02_BV

      } // End of group ea_bfk_auth_response
      // ETSI TS 103 525-2 V2.0.2 (2023-07) Clause 5.4.6  Authorization using butterfly key expansion mechanism
      group ea_bfk_cert_request {

          function f_trigger_butterfly_authorization_request(
                                                             out HashedId8 p_aes_sym_key_hashed_id8,
                                                             out EeRaCertRequest p_ee_ra_cert_request,
                                                             out RaEeCertInfo p_ra_ee_cert_info
                                                             ) runs on ItsPkiHttp return boolean {
            // Local variables
            var octetstring v_private_key_ec;
            var octetstring v_public_compressed_key_ec;
            var integer v_compressed_key_mode_ec;
            var HashedId8 v_ec_cert_hashed_id8;
            var InnerEcResponse v_inner_ec_response;
            var octetstring v_caterpillar_private_key;
            var octetstring v_caterpillar_public_key_compressed;
            var integer v_caterpillar_compressed_mode;
            var octetstring v_caterpillar_enc_private_key;
            var octetstring v_caterpillar_enc_public_key_compressed;
            var integer v_caterpillar_enc_compressed_mode;
            var EeRaCertRequest v_ee_ra_cert_request;
            var Oct32 v_request_hash;
            var Oct16 v_encrypted_sym_key;
            var Oct16 v_aes_sym_key;
            var HashedId8 v_aes_sym_key_hashed_id8;
            var Oct16 v_authentication_vector;
            var Oct12 v_nonce;
            var octetstring v_salt;
            var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
            var Headers v_headers;
            var HttpMessage v_response;

            // Trigger an enrolment request
            if (f_await_http_inner_ec_request_response(v_private_key_ec, v_public_compressed_key_ec, v_compressed_key_mode_ec, v_ec_cert_hashed_id8, v_inner_ec_response, -, true) == false) {
              log("*** " & testcasename() & ": INCONC: Enrolment failed ***");
              return false;
            } else {
              log("*** " & testcasename() & ": INFO: Enrolment succeed ***");
            }
            log("*** " & testcasename() & ": DEBUG: v_inner_ec_response= ", v_inner_ec_response);
            log("*** " & testcasename() & ": DEBUG: = ", v_private_key_ec);

            // Generate an ButterflyAutorizationRequest
            f_http_build_butterfly_authorization_request_message(v_private_key_ec, v_ec_cert_hashed_id8, v_caterpillar_private_key, v_caterpillar_public_key_compressed, v_caterpillar_compressed_mode, v_caterpillar_enc_private_key, v_caterpillar_enc_public_key_compressed, v_caterpillar_enc_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash, v_ee_ra_cert_request);
            log("*** " & testcasename() & ": DEBUG: v_ee_ra_cert_request= ", v_ee_ra_cert_request);
            log("*** " & testcasename() & ": DEBUG: v_caterpillar_private_key= ", v_caterpillar_private_key);
            v_aes_sym_key_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256('80'O & v_aes_sym_key)); // Used to match the response
            f_init_default_headers_list(-, "bfk_auth_request", v_headers);
            f_http_send(
                        v_headers,
                        m_http_request(
                                       m_http_request_post(
                                                           PICS_HTTP_POST_URI_BFK_AUTH,
                                                           v_headers,
                                                           m_http_message_body_binary(
                                                                                      m_binary_body_ieee1609dot2_data(
                                                                                                                      v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                      )))));
            tc_ac.start;
            alt {
              [] a_await_ec_http_response_from_iut(
                                                   mw_http_response(
                                                                    mw_http_response_ok(
                                                                                        mw_http_message_body_binary(
                                                                                                                    mw_binary_body_ieee1609dot2_data(
                                                                                                                                                     mw_butterflyAuthorizationResponseMessage(
                                                                                                                                                                                              mw_signedData(
                                                                                                                                                                                                            sha256,
                                                                                                                                                                                                            mw_toBeSignedData,
                                                                                                                                                                                                            m_signerIdentifier_digest(vc_eaHashedId8)
                                                                    )))))),
                                                  v_response
                                                  ) {
                tc_ac.stop;

                var octetstring v_tbs := bit2oct(encvalue(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData));
                if (f_verifyEcdsa(v_tbs, vc_eaWholeHash256, v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.signature_, vc_eaCertificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
                  log("*** " & testcasename() & ": INCONC: Failed to verify signature message ***");
                  return false;
                } else {
                  var bitstring v_etsi_ts_102941_data_content_msg := oct2bit(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
                  /** 
                  TITIAN BUG
                  https://www.eclipse.org/forums/index.php/t/1113606/

                  var EtsiTs102941MessagesCa.EtsiTs102941Data v_etsi_ts_102941_data;
                  if (decvalue(v_etsi_ts_102941_data_content_msg, v_etsi_ts_102941_data) != 0) {
                    log("*** " & testcasename() & ": INCONC: Failed to decode message ***");
                    return false;
                  } else {
                    log("*** " & testcasename() & ": DBG: v_etsi_ts_102941_data: ", v_etsi_ts_102941_data);
                    log("*** " & testcasename() & ": INFO: match ", match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationResponse(mw_ra_ee_cert_info)), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
                    if (not(match(v_etsi_ts_102941_data.content, mw_butterflyAuthorizationResponse(mw_ra_ee_cert_info)))) {
                      log("*** " & testcasename() & ": FAIL: Unexpected message ***");
                      return false;
                    } else {
                      log("*** " & testcasename() & ": INFO: ButterflyAuthorizationResponseMessage received ***");
                      p_ra_ee_cert_info := v_etsi_ts_102941_data.content.butterflyAuthorizationResponse;
                    }
                  }
                  **/
                  // Extract currentI, request hash && nextDlTime
                  var integer v_len := lengthof(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData);
                  var IValue v_currentI := oct2int(substr(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData, v_len - 4 - 8 - 2, 2));
                  var HashedId8 v_requestHash := substr(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData, v_len - 4 - 8, 8);
                  var Time32 v_nextDlTime := oct2int(substr(v_response.response.body.binary_body.ieee1609dot2_data.content.signedData.tbsData.payload.data.content.unsecuredData, v_len - 4, 4));
                  log("*** " & testcasename() & ": DBG: nextDlTime: ", v_nextDlTime);
                  log("*** " & testcasename() & ": DBG: request hash: ", v_requestHash);
                  log("*** " & testcasename() & ": DBG: currentI: ", v_currentI);
                  log("*** " & testcasename() & ": DBG: v_nextDlTime - f_getCurrentTime/100: ", f_getCurrentTime() / 1000);
                  log("*** " & testcasename() & ": DBG: v_nextDlTime - CurrentTime: ", v_nextDlTime - f_getCurrentTime() / 1000);
                  log("*** " & testcasename() & ": INFO: ButterflyAuthorizationResponseMessage received ***");
                  p_ra_ee_cert_info := valueof(
                                               m_ra_ee_cert_info(
                                                                 f_getCurrentTime() / 1000,
                                                                 v_currentI,
                                                                 v_requestHash,
                                                                 v_nextDlTime
                                               ));
                }
                log("*** " & testcasename() & ": INFO: p_ra_ee_cert_info: ", p_ra_ee_cert_info, " ***");
              }
              [] tc_ac.timeout {
                log("*** " & testcasename() & ": INCONC: Expected message not received ***");
                return false;
              }
            } // End of 'alt' statement

            return true;
          } // End of function f_trigger_butterfly_authorization_request

          function f_verify_http_butterfly_cert_request_message_from_aa(
                                                                        in Request p_request,
                                                                        in Headers p_headers,
                                                                        in boolean p_checked_cocoon_keys_derivation := false,
                                                                        in template (omit) octetstring p_caterpilar_compressed_key := omit,
                                                                        out integer p_result,
                                                                        out RaAcaCertRequest p_butterflyCertificateRequest,
                                                                        out HttpMessage p_response
                                                                        ) runs on ItsPkiHttp {

            // Local variables
            var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
            var EtsiTs102941Data v_etsi_ts_102941_data;
            var template (value) HttpMessage v_response;
            var Oct16 v_request_hash;
            var HashedId8 v_bfk_hashed_id8;
            var Oct16 v_aes_enc_key;

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

            p_result := 0;

            if (f_verify_pki_request_message(vc_aaPrivateEncKey, vc_aaWholeHash/*salt*/, ''O, 
                                             omit,
                                             p_request.body.binary_body.ieee1609dot2_data, true, v_request_hash, v_bfk_hashed_id8, 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 {
              var UInt64 v_current_time := f_getCurrentTimeUtc();
              var UInt64 v_delta_time := 30;
              log("f_verify_http_butterfly_cert_request_message_from_aa: match ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_ra_aca_cert_request(mw_ra_aca_cert_request))); // TODO In TITAN, this is the only way to get the unmatching in log
              if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_ra_aca_cert_request(mw_ra_aca_cert_request((v_current_time - v_delta_time .. v_current_time + v_delta_time), explicit, '00000000'B/*butterflyExplicit*/, mw_bfk_to_be_signed_certificate))) == false) {
                // 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 := -2;
              } else {
                if (p_checked_cocoon_keys_derivation == true) {
                  // FIXME FSCOM if (f_check_cocoon_keys_derivation(v_etsi_ts_102941_data.content.butterflyCertificateRequest.tbsCert.verifyKeyIndicator, ))
                } else {
                  var AcaRaCertResponse v_aca_ra_cert_response;
                  var HashedId8 v_hashedId8;
                  var octetstring v_msg := bit2oct(encvalue(p_request.body.binary_body.ieee1609dot2_data));

                  v_hashedId8 := f_hashedId8FromSha256(f_hashWithSha256(v_msg));
                  f_http_build_butterfly_cert_response(v_hashedId8, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, v_aca_ra_cert_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_butterflyCertificateRequest := v_etsi_ts_102941_data.content.butterflyCertificateRequest;
                }
              }
            }

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


        /**
        * @desc Check that the EA sends butterfly certificate request message after receiving of the butterfly authorization request
        *       Check that this message is encrypted for the AA
        *       Check that this message is signed with the EA certificate
        * <pre>
        * Pics Selection: PICS_IUT_EA_ROLE
        * Initial conditions:
        *     the EA in 'operational' state
        *         authorized with CERT_EA certificate
        *     and the AA is emulated by TS and
        *         authorized with CERT_AA certificate
        *     and EA is configured to use emulated AA to generate certificates
        * Expected behaviour:
        *     ensure that {
        *         when {
        *             the IUT received the ButterflyAuthorizationRequestMessage
        *                 containing EtsiTs102941Data
        *                     containing content.butterflyAuthorizationRequest
        *         }
        *         then {
        *             the IUT sends a EtsiTs103097Data to the AA
        *                 containing content.encryptedData
        *                     containing recipients
        *                         indicating size 1
        *                         and containing the instance of RecipientInfo
        *                             containing certRecipInfo
        *                                 containing recipientId
        *                                     indicating HashedId8 of the CERT_AA
        *                     and containing encrypted representation of EtsiTs103097Data
        *                         containing signedData
        *                             containing tbsData
        *                                 containing headerInfo
        *                                     containing psid
        *                                         indicating AID_PKI_CERT_REQUEST
        *                                     and containing payload.data
        *                                         containing EtsiTs102941Data
        *                                             containing version
        *                                                 indicating ‘1’
        *                                         and containing content
        *                                             containing butterflyCertificateRequest
        *                                     and containing signer
        *                                         containing digest
        *                                           indicating HashedId8 of the CERT_EA
        *         }
        *     }
        * </pre>
        * 
        * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_BFK_AUTH_03_BV
        * @reference ETSI TS 102 941 [1], clause 6.2.3.5.4
        */
        testcase TC_SECPKI_EA_BFK_AUTH_03_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
          // Local variables
          var boolean v_received_butterfly_authorization_response := false;
          var boolean v_tb_done := false;
          var HashedId8 v_aes_sym_key_hashed_id8;
          var Headers v_headers;
          var HttpMessage v_request;
          var HttpMessage v_response;
          var integer v_result;
          var EeRaCertRequest v_ee_ra_cert_request;
          var RaEeCertInfo p_ra_ee_cert_info;
          var RaAcaCertRequest v_butterflyCertificateRequest;

          // Test control
          if (not PICS_IUT_EA_ROLE) {
            log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***");
            setverdict(inconc);
            stop;
          }

          // Test component configuration
          f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID);

          // Test adapter configuration

          // Preamble
          f_trigger_butterfly_authorization_request(v_aes_sym_key_hashed_id8, v_ee_ra_cert_request, p_ra_ee_cert_info);
          log("*** " & testcasename() & ": INFO: p_ra_ee_cert_info:", p_ra_ee_cert_info, " ***");
          f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);

          // Test Body
          tc_ac.start;
          alt {
            [] httpAtVPort.receive(
                                   mw_http_request(
                                                   mw_http_request_post(
                                                                        -, // URI
                                                                        v_headers, // Headers
                                                                        mw_http_message_body_binary(
                                                                                                    mw_binary_body_ieee1609dot2_data(
                                                                                                                                     mw_butterflyCertRequestMessage(
                                                                                                                                                                    mw_encryptedData
                                  )))))) -> value v_request {
              tc_ac.stop;

              log("+++++++++++++++++++++++++++++++++++++++++++++++", v_request);
              f_verify_http_butterfly_cert_request_message_from_aa(v_request.request, v_headers, -, -, v_result, v_butterflyCertificateRequest, v_response);
              // Send response forcing error code
              if (isvalue(v_response)) {
                httpPort.send(v_response);
              }
              // Set verdict
              if (v_result == 0) {
                log("*** " & testcasename() & ": PASS: ButterflyCertRequestMessage received ***");
                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
              } else {
                log("*** " & testcasename() & ": FAIL: Failed to verify ButterflyCertRequestMessage ***");
                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
              }
              v_tb_done := true;
              if (v_received_butterfly_authorization_response == false) {
                log("*** " & testcasename() & ": INFO: ButterflyAuthorizationResponse not received yet ***");
                tc_ac.start;
                repeat;
              }
            }
            [] a_await_ec_http_response_from_iut(
                                                 mw_http_response(
                                                                  mw_http_response_ok(
                                                                                      mw_http_message_body_binary(
                                                                                                                  mw_binary_body_ieee1609dot2_data(
                                                                                                                                                  mw_enrolmentResponseMessage(
                                                                                                                                                                              mw_encryptedData(
                                                                                                                                                                                                { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * },
                                                                                                                                                                                                mw_symmetricCiphertext_aes128ccm
                                                                                                                                                                                                )))))),
                                                v_response
                                                ) {
              tc_ac.stop;

              if (v_tb_done == false) {
                v_received_butterfly_authorization_response := true;
                tc_ac.start;
                repeat;
              } // else, end on the test case
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement

          // Postamble
          f_cfHttpDown();

        } // End of testcase TC_SECPKI_EA_BFK_AUTH_03_BV

        /**
        * @desc Check that the butterfly certificate request message sent by EA to AA contains all required elements
        * <pre>
        * Pics Selection: PICS_IUT_EA_ROLE
        * Initial conditions:
        *     the EA in 'operational' state
        *         authorized with CERT_EA certificate
        *     and the EA already received the ButterflyAuthorizationRequestMessage
        *         indicating the sha256 message hash MSG_HASH
        *     and the EA already responded with ButterflyAuthorizationResponseMessage
        *         containing EtsiTs102941Data
        *             containing butterflyAuthorizationResponse
        *                 containing nextDlTime
        *                     indicating DNL_TIME
        * Expected behaviour:
        *     ensure that {
        *         when {
        *             the IUT received the ButterflyAtDownloadRequestMessage
        *                 containing EtsiTs102941Data
        *                     containing butterflyAtDownloadRequest
        *                         containing EeRaCertRequest
        *                             containing generationTime
        *                                 indicating REQ_TIME
        *         }
        *         then {
        *             the IUT sends to the AA the ButterflyCertRequestMessage
        *                 containing EtsiTs102941Data
        *                     containing content
        *                         containing butterflyCertificateRequest
        *                             containing RaAcaCertRequest
        *                                 containing version
        *                                     indicating 2
        *                             and containing generationTime
        *                                 indicating value between REQ_TIME and the current time
        *                             and containing flags
        *                                 indicating empty bit string
        *                             and containing certEncKey
        *                             and containing tbsCert
        *                             and not containing linkageInfo
        *         }
        *     }
        * </pre>
        * 
        * @see       ETSI TS 103 525-2 v2.0.1 TP SECPKI_EA_BFK_AUTH_04_BV
        * @reference ETSI TS 102 941 [1], clause 6.2.3.5.4
        */
        testcase TC_SECPKI_EA_BFK_AUTH_04_BV() runs on ItsPkiHttp system ItsPkiHttpSystem {
          // Local variables
          var boolean v_received_butterfly_authorization_response := false;
          var boolean v_tb_done := false;
          var HashedId8 v_aes_sym_key_hashed_id8;
          var Headers v_headers;
          var HttpMessage v_request;
          var HttpMessage v_response;
          var integer v_result;
          var EeRaCertRequest v_ee_ra_cert_request;
          var RaEeCertInfo p_ra_ee_cert_info;
          var RaAcaCertRequest v_butterflyCertificateRequest;

          // Test control
          if (not PICS_IUT_EA_ROLE) {
            log("*** " & testcasename() & ": PICS_IUT_EA_ROLE required for executing the TC ***");
            setverdict(inconc);
            stop;
          }

          // Test component configuration
          f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID);

          // Test adapter configuration

          // Preamble
          f_trigger_butterfly_authorization_request(v_aes_sym_key_hashed_id8, v_ee_ra_cert_request, p_ra_ee_cert_info);
          f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);

          // Test Body
          tc_ac.start;
          alt {
            [] httpAtVPort.receive(
                                   mw_http_request(
                                                   mw_http_request_post(
                                                                        -, // URI
                                                                        v_headers, // Headers
                                                                        mw_http_message_body_binary(
                                                                                                    mw_binary_body_ieee1609dot2_data(
                                                                                                                                     mw_butterflyCertRequestMessage(
                                                                                                                                                                    mw_encryptedData
                                  )))))) -> value v_request {
              tc_ac.stop;

              f_verify_http_butterfly_cert_request_message_from_aa(v_request.request, v_headers, -, -, v_result, v_butterflyCertificateRequest, v_response);
              // TODO Check v_butterflyCertificateRequest
              // FIXME Some check can be moved to  f_verify_http_butterfly_cert_request_message_from_aa




              // Send response forcing error code
              if (isvalue(v_response)) {
                httpPort.send(v_response);
              }
              // Set verdict
              if (v_result == 0) {
                log("*** " & testcasename() & ": PASS: ButterflyCertRequestMessage received ***");
                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
              } else {
                log("*** " & testcasename() & ": FAIL: Failed to verify ButterflyCertRequestMessage ***");
                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
              }
              v_tb_done := true;
              if (v_received_butterfly_authorization_response == false) {
                log("*** " & testcasename() & ": INFO: ButterflyAuthorizationResponse not received yet ***");
                tc_ac.start;
                repeat;
              }
            }
            [] a_await_ec_http_response_from_iut(
                                                 mw_http_response(
                                                                  mw_http_response_ok(
                                                                                      mw_http_message_body_binary(
                                                                                                                  mw_binary_body_ieee1609dot2_data(
                                                                                                                                                  mw_enrolmentResponseMessage(
                                                                                                                                                                              mw_encryptedData(
                                                                                                                                                                                                { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * },
                                                                                                                                                                                                mw_symmetricCiphertext_aes128ccm
                                                                                                                                                                                                )))))),
                                                v_response
                                                ) {
              tc_ac.stop;

              if (v_tb_done == false) {
                v_received_butterfly_authorization_response := true;
                tc_ac.start;
                repeat;
              } // else, end on the test case