ItsPki_TestCases.ttcn 849 KB
Newer Older
        v_itss.start(f_TC_SECPKI_ITSS_CTL_05_BV_itss());
        v_dc.start(f_TC_SECPKI_ITSS_CTL_05_BV_pki());
        // Synchronization
        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
      } // End of testcase TC_SECPKI_ITSS_CTL_05_BV
        function f_TC_SECPKI_ITSS_CTL_05_BV_itss() runs on ItsPkiItss system ItsPkiItssSystem {
          // Local variables
          var GeoNetworkingPdu v_securedGnPdu;
          var integer i;
          // Preamble
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) {
              tc_ac.stop;
              f_sendUtTriggerRequestForRcaCtl(""); // FIXME Create PIXIT for RCA DC
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          log("*** " & testcasename() & ": PASS: Trigger was sent ***");
          f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
          // Postamble
          f_cfDown_itss();
        } // End of function f_TC_SECPKI_ITSS_CTL_05_BV_itss
        function f_TC_SECPKI_ITSS_CTL_05_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
          // Local variable
          var HttpMessage v_response;
          var Headers v_headers;
          var float v_t1 := 30.0; // nextUpdate expiry in second
                                  // := (f_getCurrentTime()/* - 1072915200000*/) / 1000; // nextUpdate expiry in second

          // Test component configuration
          f_cfHttpUp_ca();
          // Preamble
          tc_ac.start;
          alt {
            [] a_await_dc_http_request_from_iut(
                                                mw_http_request(
                                                                mw_http_request_get(
                                                                                    PICS_HTTP_GET_URI_DC
                                                                                    )),
                                                v_response
                                                ) {
              var HashedId8 v_aa_hashed_id8; // Used for signature
              var Oct32 v_aa_private_key;
              var EtsiTs103097Certificate v_aa_new; // The CERT_AA_NEW
              var bitstring v_enc_msg;
              var ToBeSignedData v_tbs;
              var bitstring v_tbs_enc;
              var Oct32 v_tbs_signed;
              var Signature v_signature;
              var Ieee1609Dot2Data v_ieee1609dot2_signed_data;

              tc_ac.stop;

              // Read certificates
              f_getCertificateHash("CERT_IUT_AA", v_aa_hashed_id8);
              f_readSigningKey("CERT_IUT_AA", v_aa_private_key);
              f_readCertificate(cc_ectl_aa_new, v_aa_new);
              // Build the ToBeSignedRcaCtl data structure
              v_enc_msg := encvalue(
                                    valueof(
                                            m_to_be_signed_rca_full_ctl(
                                                                        f_getCurrentTime() / 1000 + 30,
                                                                        10,
                                                                        {
                                                                          m_ctrl_command_add(
                                                                                             m_ctl_entry_aa(
                                                                                                            m_aa_entry(
                                                                                                                       v_aa_new,
                                                                                                                       "" // FIXME PICS_AA_ENTRY_URL
                                                                                                                       )))
                                                                          }
                                                                        )));
              v_tbs := valueof(
                               m_toBeSignedData(
                                                m_signedDataPayload(
                                                                    m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg))
                                                                    ),
                                                m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/)
                                                ));
              v_tbs_enc := encvalue(v_tbs);
              // Sign the certificate
              v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_aa_hashed_id8, v_aa_private_key);
              v_signature := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 32)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 32, 32)
                                                                                    )));
              log(testcasename() & ": v_signature= ", v_signature);
              v_ieee1609dot2_signed_data := valueof(
                                                    m_etsiTs103097Data_signed(
                                                                              m_signedData(
                                                                                           sha256,
                                                                                           v_tbs,
                                                                                           m_signerIdentifier_digest(v_aa_hashed_id8),
                                                                                           v_signature
                                                                                           )));
              // Send response with CERT_AA_NEW
              f_init_default_headers_list(-, "ca_request", v_headers);
              f_http_send(
                          v_headers,
                          m_http_response(
                                          m_http_response_ok(
                                                             m_http_message_body_binary(
                                                                                        m_binary_body_ieee1609dot2_data(
                                                                                                                        v_ieee1609dot2_signed_data
                                                                                                                        )),
                                                             v_headers
                                                             )));
              log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          tc_wait.start(v_t1);
          alt {
            [] a_await_cpoc_http_request_from_iut(
                                                  mw_http_request(
                                                                  mw_http_request_get(
                                                                                      PICS_HTTP_GET_URI_TLM
              // TODO Send an error response (400 Bad request?)
              log("*** " & testcasename() & ": FAIL: ITSS RCA DC request received before the tiemer expiry ***");
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_error);
            }
            [] tc_wait.timeout {
              log("*** " & testcasename() & ": PASS: No RCA DC done before the timer expiry ***");
              f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement

          // TODO Wait for the request after timer expiry
        } // End of testcase TC_SECPKI_ITSS_CTL_05_BV
YannGarcia's avatar
YannGarcia committed
      group f_TC_SECPKI_ITSS_CTL_xx {
        function f_sendSecuredCam(in charstring p_certificate_id) runs on ItsPkiItss return GeoNetworkingPdu {
          // Local variables
          var GeoNetworkingPdu v_securedGnPdu;
          v_securedGnPdu := f_prepareSecuredCam(p_certificate_id, valueof(m_headerInfo_cam(-, (f_getCurrentTime() * 1000)/*us*/)), valueof(m_signerIdentifier_digest), f_getTsStationId());
          log("f_sendSecuredCam: v_securedGnPdu= ", v_securedGnPdu);
          geoNetworkingPort.send(valueof(m_geoNwReq_linkLayerBroadcast(v_securedGnPdu)));
          return v_securedGnPdu;
        }
        function f_prepareSecuredCam(
                                     in charstring p_configId,
                                     in HeaderInfo p_headerInfo,
                                     in SignerIdentifier p_signerIdentifier,
YannGarcia's avatar
YannGarcia committed
                                     in template (value) StationId p_station_id := f_getTsStationId()
        ) runs on ItsPkiItss return GeoNetworkingPdu {
            // Local variables
            var GnNonSecuredPacket v_gnNonSecuredPacket;
            var octetstring v_gnPayload;
            var EtsiTs103097Data v_securedMessage;
            var LongPosVector v_longPosVector := valueof(m_dummyLongPosVector);
            // Build signed Ieee1609Dot2Data
            v_longPosVector.latitude := f_getTsLatitude();
            v_longPosVector.longitude := f_getTsLongitude();
            v_longPosVector.gnAddr := f_getTsGnLocalAddress(c_compNodeB);
            v_gnNonSecuredPacket := valueof(m_geoNwShbPacket(
                                                             v_longPosVector
                                                             ));
            // Encode CAM payload
            v_gnPayload := valueof(
                                   bit2oct(
                                           encvalue(
                                                    m_camMsg_vehicle_HF_BV(
                                                                           valueof(p_station_id),
                                                                           f_getCurrentTime() mod 65536, // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime
                                                                           m_tsPosition
                                                                           ))));
            // Add BTP/CAM payload
            v_gnNonSecuredPacket.payload := int2oct(2001, 2) & int2oct(0, 2) & v_gnPayload;
            // Encode it
            log("f_prepareSecuredCam: v_gnNonSecuredPacket= ", v_gnNonSecuredPacket);
            v_gnPayload := bit2oct(
                                   encvalue(
                                            v_gnNonSecuredPacket
                                            )
                                   );
            log("f_prepareSecuredCam: v_gnPayload= ", v_gnPayload);
            f_buildGnSecuredCam(
                                v_securedMessage,
                                valueof(m_toBeSignedData(
                                                         m_signedDataPayload(
                                                                             m_etsiTs103097Data_unsecured(
                                                                                                          v_gnPayload
                                                                                                          )), 
                                                         p_headerInfo
                                                         )),
                                p_signerIdentifier,
                                p_configId
                                );

            // Return secured Gn packet
            return valueof(m_geoNwSecPdu(v_gnNonSecuredPacket, v_securedMessage));
        } // End of function f_prepareSecuredCam
    group itss_ctl_distribution {

      /**
       * @desc Check that the IUT retransmits the newly received Delta CTL
       * <pre>
       * Pics Selection: PICS_UC_SEC_05_2
       * Initial conditions: {
       *     the IUT is configured to redistribute the Delta CTL
       *     and the IUT doesn’t contain an CTL information
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT has received the Delta CTL
       *         }
       *         then {
       *             the IUT is started to broadcast the received Delta CTL
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_01_BV
       * @reference ETSI TS 103 601, clause 4.2.1.4
       */
      testcase TC_SECPKI_ITSS_CTLDIST_01_BV() runs on ItsMtc system ItsPkiItssSystem {
        // Local variables
        var ItsPkiItss v_itss;
        var ItsPkiHttp v_cpoc;
        // Test control
        if (not PICS_IUT_ITS_S_ROLE or not PICS_UC_SEC_05_2) {
          log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 required for executing the TC ***");
          setverdict(inconc);
          stop;
        }
        // Test component configuration
        f_cfMtcUp03(v_itss, v_cpoc);

        // Start components
        v_itss.start(f_TC_SECPKI_ITSS_CTLDIST_01_BV_itss());
        v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_01_BV_pki());
        // Synchronization
        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
      } // End of testcase TC_SECPKI_ITSS_CTLDIST_01_BV
        function f_TC_SECPKI_ITSS_CTLDIST_01_BV_itss()  runs on ItsPkiItss system ItsPkiItssSystem {
          // Local variables
          var GeoNetworkingInd v_geonetworking_message;
          // Preamble
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) {
              tc_ac.stop;
              f_sendUtTriggerUpdateEctl(""); // FIXME Create PIXIT for ETCL URI
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) -> value v_geonetworking_message {
              tc_ac.stop;
              if (f_verify_broadcasted_delta_ctl(v_geonetworking_message.msgIn) == false) {
                log("*** " & testcasename() & ": FAIL: Delta CTL was not successfully broadcasted ***");
                f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error);
              } else {
                log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted ***");
                f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
              }
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement
        } // End of function TC_SECPKI_ITSS_CTLDIST_01_BV_itss
        function f_TC_SECPKI_ITSS_CTLDIST_01_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
          // Local variable
          var HttpMessage v_response;
          var Headers v_headers;

          // Test component configuration
          f_cfHttpUp_tlm();
          // Preamble
          tc_ac.start;
          alt {
            [] a_await_cpoc_http_request_from_iut(
                                                  mw_http_request(
                                                                  mw_http_request_get(
                                                                                      PICS_HTTP_GET_URI_TLM
                                                                                      )),
                                                  v_response
                                                  ) {
              var HashedId8 v_rca_hashed_id8; // Used for signature
              var Oct32 v_rca_private_key;
              var EtsiTs103097Certificate v_rca_new; // The CERT_RCA_NEW
              var bitstring v_enc_msg;
              var ToBeSignedData v_tbs;
              var bitstring v_tbs_enc;
              var Oct32 v_tbs_signed;
              var Signature v_signature;
              var Ieee1609Dot2Data v_ieee1609dot2_signed_data;

              tc_ac.stop;

              // Read certificates
              f_getCertificateHash(PICS_IUT_CA_CERTIFICATE_ID, v_rca_hashed_id8);
              f_readSigningKey(PICS_IUT_CA_CERTIFICATE_ID, v_rca_private_key);
              f_readCertificate(cc_ectl_rca_new, v_rca_new);
              // Build the ToBeSignedTlmCtl data structure
              v_enc_msg := encvalue(
                                    valueof(
                                            m_to_be_signed_tlm_full_ctl(
                                                                        f_getCurrentTime() / 1000 + 3600,
                                                                        10,
                                                                        {
                                                                          m_ctrl_command_add(
                                                                                             m_ctl_entry_rca(
                                                                                                             m_root_ca_entry(
                                                                                                                             v_rca_new
                                                                                                                             )))
                                                                          }
                                                                        )));
              v_tbs := valueof(
                               m_toBeSignedData(
                                                m_signedDataPayload(
                                                                    m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg))
                                                                    ),
                                                m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/)
                                                ));
              v_tbs_enc := encvalue(v_tbs);
              // Sign the certificate
              v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_rca_hashed_id8, v_rca_private_key);
              v_signature := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 32)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 32, 32)
                                                                                    )));
              log(testcasename() & ": v_signature= ", v_signature);
              v_ieee1609dot2_signed_data := valueof(
                                                    m_etsiTs103097Data_signed(
                                                                              m_signedData(
                                                                                           sha256,
                                                                                           v_tbs,
                                                                                           m_signerIdentifier_digest(v_rca_hashed_id8),
                                                                                           v_signature
                                                                                           )));
              // Send response with CERT_RCA_NEW
              f_init_default_headers_list(-, "tlm_ectl", v_headers);
              f_http_send(
                          v_headers,
                          m_http_response(
                                          m_http_response_ok(
                                                             m_http_message_body_binary(
                                                                                        m_binary_body_ieee1609dot2_data(
                                                                                                                        v_ieee1609dot2_signed_data
                                                                                                                        )),
                                                             v_headers
                                                             )));
              log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
          // Postamble
          f_cfHttpDown_tlm();
        } // End of function f_TC_SECPKI_ITSS_CTLDIST_01_BV_pki

      } // End of group f_TC_SECPKI_ITSS_CTLDIST_01_BV
      /**
       * @desc Check that the IUT retransmits the updated Delta CTL
       * <pre>
       * Pics Selection: PICS_UC_SEC_05_2
       * Initial conditions: {
       *     the IUT is configured to redistribute the Delta CTL
       *     and the IUT contains an CTL information
       *         containing ctlSequence (SN)
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT has received the Delta CTL
       *                 containing ctlSequence
       *                    indicating value greater than SN
       *         }
       *         then {
       *             the IUT is started to broadcast the received Delta CTL
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_02_BV
       * @reference ETSI TS 103 601, clause 4.2.1.4
       */
      testcase TC_SECPKI_ITSS_CTLDIST_02_BV() runs on ItsMtc system ItsPkiItssSystem {
        // Local variables
        var ItsPkiItss v_itss;
        var ItsPkiHttp v_cpoc;
        // Test control
        if (not PICS_IUT_ITS_S_ROLE or not PICS_UC_SEC_05_2) {
          log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 required for executing the TC ***");
          setverdict(inconc);
          stop;
        }
        // Test component configuration
        f_cfMtcUp03(v_itss, v_cpoc);

        // Start components
        v_itss.start(f_TC_SECPKI_ITSS_CTLDIST_02_BV_itss());
        v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_02_BV_pki());
        // Synchronization
        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
      } // End of testcase TC_SECPKI_ITSS_CTLDIST_02_BV
        function f_TC_SECPKI_ITSS_CTLDIST_02_BV_itss()  runs on ItsPkiItss system ItsPkiItssSystem {
          // Local variables
          var GeoNetworkingInd v_geonetworking_message;
          // Preamble
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) {
              tc_ac.stop;
              f_sendUtTriggerUpdateEctl(""); // FIXME Create PIXIT for ETCL URI
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) -> value v_geonetworking_message {
              tc_ac.stop;
              if (f_verify_broadcasted_delta_ctl(v_geonetworking_message.msgIn) == false) {
                log("*** " & testcasename() & ": FAIL: Delta CTL was not successfully broadcasted ***");
                f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error);
              } else {
                log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted ***");
                f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
              }
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement
        } // End of function TC_SECPKI_ITSS_CTLDIST_02_BV_itss
        function f_TC_SECPKI_ITSS_CTLDIST_02_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
          // Local variable
          var HttpMessage v_response;
          var Headers v_headers;

          // Test component configuration
          f_cfHttpUp_tlm();
          // Preamble
          tc_ac.start;
          alt {
            [] a_await_cpoc_http_request_from_iut(
                                                  mw_http_request(
                                                                  mw_http_request_get(
                                                                                      PICS_HTTP_GET_URI_TLM
                                                                                      )),
                                                  v_response
                                                  ) {
              var HashedId8 v_rca_hashed_id8; // Used for signature
              var Oct32 v_rca_private_key;
              var EtsiTs103097Certificate v_rca_new; // The CERT_RCA_NEW
              var bitstring v_enc_msg;
              var ToBeSignedData v_tbs;
              var bitstring v_tbs_enc;
              var Oct32 v_tbs_signed;
              var Signature v_signature;
              var Ieee1609Dot2Data v_ieee1609dot2_signed_data;

              tc_ac.stop;

              // Read certificates
              f_getCertificateHash(PICS_IUT_CA_CERTIFICATE_ID, v_rca_hashed_id8);
              f_readSigningKey(PICS_IUT_CA_CERTIFICATE_ID, v_rca_private_key);
              f_readCertificate(cc_ectl_rca_new, v_rca_new);
              // Build the ToBeSignedTlmCtl data structure
              v_enc_msg := encvalue(
                                    valueof(
                                            m_to_be_signed_tlm_full_ctl(
                                                                        f_getCurrentTime() / 1000 + 3600,
                                                                        10,
                                                                        {
                                                                          m_ctrl_command_add(
                                                                                             m_ctl_entry_rca(
                                                                                                             m_root_ca_entry(
                                                                                                                             v_rca_new
                                                                                                                             )))
                                                                          }
                                                                        )));
              v_tbs := valueof(
                               m_toBeSignedData(
                                                m_signedDataPayload(
                                                                    m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg))
                                                                    ),
                                                m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/)
                                                ));
              v_tbs_enc := encvalue(v_tbs);
              // Sign the certificate
              v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_rca_hashed_id8, v_rca_private_key);
              v_signature := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 32)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 32, 32)
                                                                                    )));
              log(testcasename() & ": v_signature= ", v_signature);
              v_ieee1609dot2_signed_data := valueof(
                                                    m_etsiTs103097Data_signed(
                                                                              m_signedData(
                                                                                           sha256,
                                                                                           v_tbs,
                                                                                           m_signerIdentifier_digest(v_rca_hashed_id8),
                                                                                           v_signature
                                                                                           )));
              // Send response with CERT_RCA_NEW
              f_init_default_headers_list(-, "tlm_ectl", v_headers);
              f_http_send(
                          v_headers,
                          m_http_response(
                                          m_http_response_ok(
                                                             m_http_message_body_binary(
                                                                                        m_binary_body_ieee1609dot2_data(
                                                                                                                        v_ieee1609dot2_signed_data
                                                                                                                        )),
                                                             v_headers
                                                             )));
              log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
          // Postamble
          f_cfHttpDown_tlm();
        } // End of function f_TC_SECPKI_ITSS_CTLDIST_02_BV_pki

      } // End of group f_TC_SECPKI_ITSS_CTLDIST_02_BV
      /**
       * @desc Check that the IUT is using the proper BTP port to broadcast the Delta CTL
       * <pre>
       * Pics Selection: PICS_UC_SEC_05_2
       * Initial conditions: {
       *     the IUT is configured to support P2P X_DISTRIBUTION distribution
       *     and the IUT has received the Delta X_DISTRIBUTION message
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT is triggered to broadcast the Delta X_DISTRIBUTION message
       *         }
       *         then {
       *             the IUT sends the X_MESSAGE
       *                 using the BTP port 2014
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_03_BV
       * @reference ETSI TS 103 601, clause 5.4.4
       */
      testcase TC_SECPKI_ITSS_CTLDIST_03_BV() runs on ItsMtc system ItsPkiItssSystem {
        // Local variables
        var ItsPkiItss v_itss;
        var ItsPkiHttp v_cpoc;
        // Test control
        if (not PICS_IUT_ITS_S_ROLE or not PICS_UC_SEC_05_2) {
          log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 required for executing the TC ***");
          setverdict(inconc);
          stop;
        }
        // Test component configuration
        f_cfMtcUp03(v_itss, v_cpoc);

        // Start components
        v_itss.start(f_TC_SECPKI_ITSS_CTLDIST_03_BV_itss());
        v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_03_BV_pki());
        // Synchronization
        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
      } // End of testcase TC_SECPKI_ITSS_CTLDIST_03_BV
        function f_TC_SECPKI_ITSS_CTLDIST_03_BV_itss()  runs on ItsPkiItss system ItsPkiItssSystem {
          // Local variables
          var GeoNetworkingInd v_geonetworking_message;
          var octetstring v_payload;
          // Preamble
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) {
              tc_ac.stop;
              f_sendUtTriggerUpdateEctl(""); // FIXME Create PIXIT for ETCL URI
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          geoNetworkingPort.clear;
          tc_ac.start;
          alt {
            [] geoNetworkingPort.receive(
                                         mw_geoNwInd(
                                                     mw_geoNwSecPdu(
                                                                    mw_etsiTs103097Data_signed(
                                                                                               mw_signedData
                                                                                               )))) -> value v_geonetworking_message {
              tc_ac.stop;
              if (f_verify_and_extract_payload(v_geonetworking_message.msgIn, -, v_payload) == false) {
                log("*** " & testcasename() & ": INCONC: Failed to verifiy payload ***");
                f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout);
              } else {
                // TODO Check payload
                if (substr(v_payload, 0, 2) == int2oct(2014, 2)) { // TODO Reorganize CAM/DENM/BTP test suites
                  log("*** " & testcasename() & ": PASS: Delta CTL was successfully broadcasted on the correct BTP port ***");
                  f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                } else {
                  log("*** " & testcasename() & ": FAIL: Delta CTL was not broadcasted on BTP port 114 ***");
                  f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_error);
                }
              }
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_timeout);
            }
          } // End of 'alt' statement
        } // End of function TC_SECPKI_ITSS_CTLDIST_03_BV_itss
        function f_TC_SECPKI_ITSS_CTLDIST_03_BV_pki() runs on ItsPkiHttp system ItsPkiItssSystem {
          // Local variable
          var HttpMessage v_response;
          var Headers v_headers;

          // Test component configuration
          f_cfHttpUp_tlm();
          // Preamble
          tc_ac.start;
          alt {
            [] a_await_cpoc_http_request_from_iut(
                                                  mw_http_request(
                                                                  mw_http_request_get(
                                                                                      PICS_HTTP_GET_URI_TLM
                                                                                      )),
                                                  v_response
                                                  ) {
              var HashedId8 v_rca_hashed_id8; // Used for signature
              var Oct32 v_rca_private_key;
              var EtsiTs103097Certificate v_rca_new; // The CERT_RCA_NEW
              var bitstring v_enc_msg;
              var ToBeSignedData v_tbs;
              var bitstring v_tbs_enc;
              var Oct32 v_tbs_signed;
              var Signature v_signature;
              var Ieee1609Dot2Data v_ieee1609dot2_signed_data;

              tc_ac.stop;

              // Read certificates
              f_getCertificateHash(PICS_IUT_CA_CERTIFICATE_ID, v_rca_hashed_id8);
              f_readSigningKey(PICS_IUT_CA_CERTIFICATE_ID, v_rca_private_key);
              f_readCertificate(cc_ectl_rca_new, v_rca_new);
              // Build the ToBeSignedTlmCtl data structure
              v_enc_msg := encvalue(
                                    valueof(
                                            m_to_be_signed_tlm_full_ctl(
                                                                        f_getCurrentTime() / 1000 + 3600,
                                                                        10,
                                                                        {
                                                                          m_ctrl_command_add(
                                                                                             m_ctl_entry_rca(
                                                                                                             m_root_ca_entry(
                                                                                                                             v_rca_new
                                                                                                                             )))
                                                                          }
                                                                        )));
              v_tbs := valueof(
                               m_toBeSignedData(
                                                m_signedDataPayload(
                                                                    m_etsiTs103097Data_unsecured(bit2oct(v_enc_msg))
                                                                    ),
                                                m_headerInfo_inner_pki_request(-, (f_getCurrentTime() * 1000)/*us*/)
                                                ));
              v_tbs_enc := encvalue(v_tbs);
              // Sign the certificate
              v_tbs_signed := f_signWithEcdsa(bit2oct(v_tbs_enc), v_rca_hashed_id8, v_rca_private_key);
              v_signature := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 32)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 32, 32)
                                                                                    )));
              log(testcasename() & ": v_signature= ", v_signature);
              v_ieee1609dot2_signed_data := valueof(
                                                    m_etsiTs103097Data_signed(
                                                                              m_signedData(
                                                                                           sha256,
                                                                                           v_tbs,
                                                                                           m_signerIdentifier_digest(v_rca_hashed_id8),
                                                                                           v_signature
                                                                                           )));
              // Send response with CERT_RCA_NEW
              f_init_default_headers_list(-, "tlm_ectl", v_headers);
              f_http_send(
                          v_headers,
                          m_http_response(
                                          m_http_response_ok(
                                                             m_http_message_body_binary(
                                                                                        m_binary_body_ieee1609dot2_data(
                                                                                                                        v_ieee1609dot2_signed_data
                                                                                                                        )),
                                                             v_headers
                                                             )));
              log("*** " & testcasename() & ": INFO: CERT_RCA_NEW was sent to the IUT ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            }
            [] tc_ac.timeout {
              log("*** " & testcasename() & ": INCONC: Expected message not received ***");
              f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
            }
          } // End of 'alt' statement
          // Test Body
          f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
          // Postamble
          f_cfHttpDown_tlm();
        } // End of function f_TC_SECPKI_ITSS_CTLDIST_03_BV_pki

      } // End of group f_TC_SECPKI_ITSS_CTLDIST_03_BV

      /**
       * @desc Check that the IUT stops to redistribute the Delta CTL if anorther node is also sending it
       * <pre>
       * Pics Selection: PICS_UC_SEC_05_2
       * Initial conditions: {
       *     the IUT is configured to support P2P Delta X_DISTRIBUTION distribution
       *     and the IUT has started broadcasting the Delta X_DISTRIBUTION message
       *         signed with X_CERTIFICATE
       *         and containing ctlSequence (SN)
       *     }
       * Expected behaviour:
       *     ensure that {
       *         when {
       *             the IUT has received the Delta X_DISTRIBUTION
       *                 signed with X_CERTIFICATE
       *                 and containing ctlSequence
       *                     indicating value equal or higher than SN
       *         }
       *         then {
       *             the IUT stops broadfcasting the Delta X_DISTRIBUTION
       *                 signed with X_CERTIFICATE
       *                 and containing ctlSequence (SN)
       *         }
       *     }
       * </pre>
       * 
       * @see       ETSI TS 103 525-2 TP SECPKI_ITSS_CTLDIST_04_BV
       * @reference ETSI TS 103 601, clause 5.4.4
       */
      testcase TC_SECPKI_ITSS_CTLDIST_04_BV() runs on ItsMtc system ItsPkiItssSystem {
        // Local variables
        var ItsPkiItss v_itss;
        var ItsPkiHttp v_cpoc;
        // Test control
        if (not PICS_IUT_ITS_S_ROLE or not PICS_UC_SEC_05_2) {
          log("*** " & testcasename() & ": PICS_IUT_ITS_S_ROLE and PICS_UC_SEC_05_2 required for executing the TC ***");
          setverdict(inconc);
          stop;
        }
        // Test component configuration
        f_cfMtcUp03(v_itss, v_cpoc);

        // Start components
        v_itss.start(f_TC_SECPKI_ITSS_CTLDIST_04_BV_itss());
        v_cpoc.start(f_TC_SECPKI_ITSS_CTLDIST_04_BV_pki());
        // Synchronization
        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
      } // End of testcase TC_SECPKI_ITSS_CTLDIST_04_BV
      group f_TC_SECPKI_ITSS_CTLDIST_04_BV {

        function f_broadcast_delta_ctl(
                                       in charstring p_certificate_id,
                                       out Ieee1609Dot2Data p_delta_ctl
                                       ) runs on ItsPkiItss return GeoNetworkingPdu {
          // Local variables
          var GeoNetworkingPdu v_securedGnPdu;
          v_securedGnPdu := f_prepareSecuredCam(p_certificate_id, valueof(m_headerInfo_cam(-, (f_getCurrentTime() * 1000)/*us*/)), valueof(m_signerIdentifier_digest), f_getTsStationId());
          log("f_sendSecuredCam: v_securedGnPdu= ", v_securedGnPdu);