Commit ffd5535b authored by YannGarcia's avatar YannGarcia
Browse files

Add basics for security (signature)

parent fc567794
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -277,6 +277,28 @@ $ cp ./ttcn/patch_lib_http/*.ttcn ./ttcn/LibIts/ttcn/Http/
- Switch to the next clause (Usage)


## Generate certificates for TLS and Cise security support 

This clause describes how generate certificates desrived from Let's encrypt certificate. These certificate will be used for TS mutual authentication and for Cise Security tests.
<b>NOTE:</b>
- Certficates shall be renewed every 3 months
- The port 80 shall be vailable for standalone validation

Pre-requisites:
- You need to install python and [certbot](https://manpages.ubuntu.com/manpages/impish/en/man1/certbot.1.html).

To generate certifcates, execute the following command:

```sh
$ export REQUESTS_CA_BUNDLE=$(dirname `python -c "import certifi; print(certifi.where())"`)
$ mkdir -p $HOME/var/ssl
$ sudo certbot certonly --debug --cise-tls-cert --config-dir $HOME/var/ssl --work-dir $HOME/var/ssl  --logs-dir $HOME/var/ssl --standalone --agree-tos --email <your email> -d <your domain> -w $HOME/var/ssl/
$ sudo certbot certonly --debug --cise-test-cert --config-dir $HOME/var/ssl --work-dir $HOME/var/ssl  --logs-dir $HOME/var/ssl --standalone --agree-tos --email <your email> -d <your domain> -w $HOME/var/ssl/
```

<b>NOTE:</b> For testing certificate generation and renewal, use the certbot's --dry-run option.


## Usage

This clause describes how to compile and execute an Abstract Test Suite.
+5 −5
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ namespace LibHttp__TestSystem {

  void HttpPort::set_parameter(const char * parameter_name, const char * parameter_value)
  {
    loggers::get_instance().log("HttpPort::set_parameter: %s=%s", parameter_name, parameter_value);
    loggers::get_instance().log("HttpPort::set_parameter: '%s'=%s", parameter_name, parameter_value);
    _cfg_params.insert(std::pair<std::string, std::string>(std::string(parameter_name), std::string(parameter_value)));
  }

@@ -48,17 +48,17 @@ namespace LibHttp__TestSystem {

  void HttpPort::user_map(const char * system_port)
  {
    loggers::get_instance().log(">>> HttpPort::user_map: %s", system_port);
    loggers::get_instance().log(">>> HttpPort::user_map: '%s'", system_port);
    // Build layer stack
    params::iterator it = _cfg_params.find(std::string("params"));
    if (it != _cfg_params.end()) {
      loggers::get_instance().log("HttpPort::user_map: %s", it->second.c_str());
      loggers::get_instance().log("HttpPort::user_map: '%s'", it->second.c_str());
      // Setup parameters
      params::convert(_layer_params, it->second); // TODO This _layer_params seems to be useless
      // Create layer
      _layer = layer_stack_builder::get_instance()->create_layer_stack(it->second.c_str());
      if (static_cast<http_layer*>(_layer) == nullptr) {
        loggers::get_instance().error("HttpPort::user_map: Invalid stack configuration: %s", it->second.c_str());
        loggers::get_instance().error("HttpPort::user_map: Invalid stack configuration: '%s'", it->second.c_str());
      }
      if (!static_cast<http_layer*>(_layer)->set_codec(new http_codec_cise())) {
        loggers::get_instance().error("HttpPort::user_map: Null codec");
@@ -71,7 +71,7 @@ namespace LibHttp__TestSystem {

  void HttpPort::user_unmap(const char * system_port)
  {
    loggers::get_instance().log(">>> HttpPort::user_unmap: %s", system_port);
    loggers::get_instance().log(">>> HttpPort::user_unmap: '%s'", system_port);

    // Reset layers
    if (_layer != nullptr) {
+4 −2
Original line number Diff line number Diff line
@@ -17,8 +17,6 @@ int xml_codec::encode(const LibHttp__XmlMessageBodyTypes::XmlBody& msg, OCTETSTR
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
  TTCN_Buffer encoding_buffer;

  CHARSTRING h("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
  encoding_buffer.put_s(h.lengthof(), (const unsigned char*)static_cast<const char*>(h));
  if (msg.ischosen(LibHttp__XmlMessageBodyTypes::XmlBody::ALT_pull__request)) {
    const http__www__cise__eu__servicemodel__v1__message::PullRequest& pull_request = msg.pull__request();
    loggers::get_instance().log_msg("xml_codec::encode: Process PullRequest: ", (const Base_Type&)pull_request);
@@ -54,6 +52,10 @@ int xml_codec::encode(const LibHttp__XmlMessageBodyTypes::XmlBody& msg, OCTETSTR
    data = OCTETSTRING(s.length(), (const unsigned char*)s.c_str());
  }

  // Add header
  CHARSTRING h("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
  data = char2oct(h) + data;

  loggers::get_instance().log_msg("xml_codec::encode: After encoding: ", data);

  loggers::get_instance().log("<<< xml_codec::encode");
+5 −1
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@ LibCise_Pics.PICS_IUT_NODE := true
LibCise_Pics.PICS_IUT_ADAPTOR := true

# LibCise
LibCise_Pics.PICS_CISE_SECURITY             := true
LibCise_Pics.PICS_CISE_CERTIFICATES_DB_PATH := "/home/yann/var/ssl/live/yanngarcia.ddns.net/";
LibCise_Pixits.PX_SECURITY_SIGN_CERT := "cert.pem";

# LibHttp
LibHttp_Pics.PICS_HEADER_HOST         := "192.168.1.39"
@@ -62,7 +65,8 @@ system.httpPort_notif.params := "HTTP(codecs=xml:xml_codec)/TCP(debug=1,server_m
#AtsCise_TestControl.control

# Check that the IUT sends a PullResponse when recieving a PullRequest with no Acknowledgement
AtsCise_TestCases.TC_CISE_xxx_BV_01
#AtsCise_TestCases.TC_CISE_xxx_BV_01
AtsCise_TestCases.TC_CISE_xxx_BV_02
# Check that the IUT is requested to send a PullRequest with no Acknowledgement, the IUT sends a PullRequest with entry Acknowledgement set to False
#AtsCise_TestCases.TC_CISE_yyy_BV_01

+135 −6
Original line number Diff line number Diff line
@@ -37,14 +37,14 @@ module AtsCise_TestCases {
      var charstring v_correlation_id := f_generate_uuid();

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

      // Test component configuration
      f_cf_01_http_up();
      f_cf_01_up();

      // Test adapter configuration

@@ -131,10 +131,139 @@ module AtsCise_TestCases {
      } // End of 'alt' statement

      // Postamble
      f_cf_01_http_down();
      f_cf_01_down();
    
    } // End of testcase TC_CISE_xxx_BV_01

    /**
     * @desc Check that the IUT sends a PullResponse when recieving a PullRequest with no Acknowledgement, with security
     * @see ETSI GS CDM 004 Clause 5.4.2 Pull
     */
    testcase TC_CISE_xxx_BV_02() runs on HttpComponent system HttpTestAdapter {
      // Local variables
      var Headers v_headers;
      var HttpMessage v_response;
      var charstring v_date_time := f_get_current_date_time();
      var charstring v_message_id := f_generate_uuid();
      var charstring v_correlation_id := f_generate_uuid();

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

      // Test component configuration
      f_cf_01_up();

      // Test adapter configuration

      // Preamble
      var PullRequest v_pull_request := valueof(
                                                m_pull_request(
                                                               v_date_time,
                                                               v_message_id,
                                                               high,
                                                               m_service( // Sender
                                                                         { string := PX_CISE_SERVICE_ID }, //m_service_id(PX_CISE_SERVICE_ID),
                                                                         pull,
                                                                         -,
                                                                         PX_CISE_SEA_BASSIN,
                                                                         consumer,
                                                                         online,
                                                                         vesselService
                                                                         ),
                                                               {}, 
                                                               -,
                                                               request,
                                                               {},
                                                               -, -, 
                                                               v_correlation_id, 
                                                               false, // RequiresAck
                                                               m_service( // Recipient
                                                                         { string := PX_CISE_SERVICE_ID }, //m_service_id(PX_CISE_SERVICE_ID),
                                                                         acknowledgement,
                                                                         -,
                                                                         PX_CISE_SEA_BASSIN,
                                                                         consumer,
                                                                         online,
                                                                         vesselService
                                                                         ),
                                                               m_core_entity_payload_derivations_payload(
                                                                                                         m_entity_payload( // Payload
                                                                                                                          nonClassified,
                                                                                                                          green,
                                                                                                                          nonSpecified,
                                                                                                                          {},
                                                                                                                          false,
                                                                                                                          -,
                                                                                                                          false
                                                                                                                          )
                                                                                                         ),
                                                               -,
                                                               1000 // ResponseTimeOut
                                                               ));
      var octetstring v_pull_request_signed;
      var charstring v_pull_request_signed_str;
      var integer v_result;

      v_result := f_sign_pull_request(v_pull_request, PX_SECURITY_SIGN_HASH_ALG, PX_SECURITY_SIGN_CERT, v_pull_request_signed);
      if (v_result != 0) {
        log("*** " & testcasename() & ": INCONC: Signature processing failed ***");
        f_selfOrClientSyncAndVerdict(c_prDone, e_timeout);
      }
      v_pull_request_signed_str := oct2char(v_pull_request_signed);
      f_init_default_headers_list(-, -, v_headers);
      httpPort.send(
                    m_http_request(
                                   m_http_request_get(
                                                      PICS_ROOT_API & PX_CISE_PULL_REQUEST_URI & "?messageId=" & v_message_id,
                                                      v_headers,
                                                      mw_http_message_body_xml(
                                                                               m_xml_body_raw(
                                                                                              v_pull_request_signed_str
                                                                                              )))));
      f_selfOrClientSyncAndVerdict(c_prDone, e_success);

      // Test Body
      tc_ac.start;
      alt {
        [] httpPort.receive(
                            mw_http_response(
                                             mw_http_response_ok(
                                                                 mw_http_message_body_xml(
                                                                                          mw_xml_body_pull_response(
                                                                                                                    mw_pull_response(
                                                                                                                                     v_date_time,
                                                                                                                                     v_message_id,
                                                                                                                                     high,
                                                                                                                                     -, -, -,
                                                                                                                                     success,
                                                                                                                                     -, -,
                                                                                                                                     v_correlation_id
                              )))))) -> value v_response {
            tc_ac.stop;

            if (not(f_verify_sign_pull_response(v_response.response.body.xml_body.pull_response))) {
              log("*** " & testcasename() & ": FAIL: Signature not verified ***");
              f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
            } else {
              log("*** " & testcasename() & ": PASS: IUT successfully received PullResponse ***");
              f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
            }
          }
          [] tc_ac.timeout {
            log("*** " & testcasename() & ": INCONC: Expected message not received ***");
            f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
          }
      } // End of 'alt' statement

      // Postamble
      f_cf_01_down();
    
    } // End of testcase TC_CISE_xxx_BV_02

  } // Enf of group test1

  group test2 {
@@ -155,7 +284,7 @@ module AtsCise_TestCases {
      }

      // Test component configuration
      f_cf_01_http_notif_up();
      f_cf_02_up();

      // Test adapter configuration

@@ -213,7 +342,7 @@ module AtsCise_TestCases {
      } // End of 'alt' statement

      // Postamble
      f_cf_01_http_notif_down();
      f_cf_02_down();
    
    } // End of testcase TC_CISE_yyy_BV_01

Loading