Commit 0d89f1d1 authored by Denis Filatov's avatar Denis Filatov
Browse files

Merge branch 'STF525' of https://forge.etsi.org/gitlab/ITS/ITS into STF525

parents f8693810 ade618da
Loading
Loading
Loading
Loading

LICENSE

0 → 100644
+23 −0
Original line number Diff line number Diff line
Copyright 2019 ETSI

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, 
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, 
   this list of conditions and the following disclaimer in the documentation 
   and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors 
   may be used to endorse or promote products derived from this software without 
   specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
OF THE POSSIBILITY OF SUCH DAMAGE.
+66 −51
Original line number Diff line number Diff line
@@ -37,7 +37,28 @@ The ETSI ITS protocols project builds and tests regularly on the following platf

  - Linux (Ubuntu)

Note: The [OpenSSL](https://www.openssl.org) version > 1.x is also required.
Note: The [OpenSSL](https://www.openssl.org) version > 1.1.x is also required.

### How to do it?

They are two different methods:
- Using [Vagrant](https://www.vagrantup.com/)
- Using [Docker](https://www.docker.com/)

How to choose one of these methods is depending of your host system.

NOTE: In all case, if you want to setup an continuous integration process (e.g. Jenkins), Docker is the best choice. 


#### The host system is Windows
The both methods require a virtual machine. You can use either VirtualBox or WMware.
In this case, the easiest way is to use Vagrant.


#### The host system is Linux
Vagrant requires a virtual machine. You can use either VirtualBox or WMware.
Docker does not need a virtual machine, so it is the more efficant way.


### Using Vagrant

@@ -45,14 +66,14 @@ Pre-requisites on your host machine:
- Install [Virtualbox](https://www.virtualbox.org/manual/ch01.html)
- Install [Vagrant](https://www.vagrantup.com/intro/getting-started/)
- Install Vagrant plugin vagrant-vbguest
- Credentials to access [ETSI forge](https://oldforge.etsi.org/!/#)
    - Set the environment variable USERNAME to your ETSI OEL account user name
    - Set the environment variable PASSWORD to your ETSI OEL account password
- Credentials to access [ETSI forge](https://forge.etsi.org/gitlab/users/sign_in)
    - Set the environment variable USERNAME to your ETSI EOL account user name
    - Set the environment variable PASSWORD to your ETSI EOL account password

Procedure:
- On your host machine, open a command line session (PuTTY, DOS window...)
- From the ETSI ITS protocols project, clone the Vagrant folder
- In the file Vagrantfilem, odify the tag config.vm.provision replacing <username> & <password> strings by your ETSI credentials
- In the file Vagrantfile, modify the tag config.vm.provision replacing <username> & <password> strings by your ETSI credentials
- In the Vagrant folder, execute the following commands:

```sh
@@ -85,13 +106,21 @@ NOTE The user password is vagrant.
### Using Docker

Pre-requisites on your host machine:
- Install Virtualbox
- Install Virtualbox (For Windows host only)
- Install Docker

Procedure for a Windows host machine:
- On your host machine, open a the Docker Quickstart Terminal
- On your host machine, clone the ETSI ITS protocols project. NOTE that only Docker folder and .jenkins.sh script file are required
- From the ETSI ITS protocols project root directory, execute the following commands:
- On your host machine, open a the Docker Quickstart Terminal and change to a working folder such as ./temp/docker_its

Procedure for a Linux host machine:
- On your host machine, open a terminal and change to a working folder such as $HOME/temp/docker_its

On your host machine, download the following items from ETSI ITS protocols project:
- The docker folder
- The .jenkins.sh script file (hidden file) and add the execution rights on it
- Check the rights of the script files and the folders

From the your current directory, execute the following commands:

```sh
$ ./.jenkins.sh
@@ -190,7 +219,7 @@ The procedures below illustrate how to run the CAM test suite. The same procedur


Pre-requisites:
- Your machine is installed followimg one of the installation method describes in the previous clause
- Your machine is installed following one of the installation method describes in the previous clause
- Refer to the ETSI TS 103 099 for the description of the Test System architecture and configuration
- Your are logged as 'etsi' or 'vagrant' user

@@ -198,7 +227,7 @@ Procedure using Eclipse TITAN:
- Start eclipse using a new workspace, (e.g. with the name workspace_titan)
- Download and follow the steps to install Eclipse plugins for TITAN, accessible [here]{https://www.eclipse.org/downloads/download.php?file=/titan/Eclipse_installationguide.pdf}
- Open the workspace_titan
- Create a new TITAN project (e.g. Its_autoInterop)
- Create a new TITAN project (e.g. STF525_Its)
<TODO>

Procedure in TITAN command line:
@@ -224,58 +253,44 @@ $ ../bin/run-all.bash

- The log files are located in ../logs folder. You can edit them using any editor or using the Eclipse TITAN log plugins

## How to generate ITS test certificates

## Rebuild Wireshark with support of ETSI ITS Protocols
The Test System includes a tool, asn1cert, to generate ITS test certificates used for Conformance Testing.
This tool is located in the folder '~/dev/STF525_Its/tools/itscertgen/'.

A specific version of Wireshark, based on official version 2.6.x, is available [here](https://github.com/YannGarcia/wireshark-for-ITS.git).
Note: These certificates can not be used in a true architectures, there are present only for testing and/or debug purposes.

The following Pre-requisites applies to build it:
- Your machine is installed followimg one of the installation method describes in the previous clause
- Your are logged as 'etsi' or 'vagrant' user

The following procedure applies to build it:
- Open a SSH session (PuTTY...)
- Change to the directory ~/frameworks
- Execute the following comands to clone the project and switch to the branck
### Build the tool 'asn1cert'

```sh
$ git clone https://github.com/YannGarcia/wireshark-for-ITS.git wireshark-for-ITS
$ git checkout ITS_Protocol_Support
...
```
To build the tool, run the 'make' command in each of the following folders:
- cshared
- cxml
- checker
- asn1certgen

- Create a folder ~/frameworks/wireshark-build
- Change to this folder
- Generate makefiles executing the following command

```sh
$ cmake ../wireshark-for-ITS
...
```
### Generate the certificates

- Add specific compiler options to the file epan/dissectors/CMakeFiles/dissectors.dir/flags.make:
    - Find the variable C_FLAGS
    - Remove the flag : "-Wunused-const-variable"
- Build Wireshark/tshark executing the following command
After that change to the folder '~/dev/STF525_Its/data/v3' and execute 'make command.
The certificates will be located in the folder '~/dev/STF525_Its/data/v3/certificates'.

```sh
$ make
```

- After the build, binaries are located in ~/frameworks/wireshark-build/run folder
- To distinguish this version of Wireshark from the others, a development tag 'ETSI ITS Protocols' is displayed on the GUI version
- You have to provide also the following link to indicate the location of the new built plugins
### Modify or create new certificates

```sh
$ sudo ln -sf /home/vagrant/frameworks/wireshark-build/run/plugins/2.9 /usr/local/lib/wireshark/plugins/2.9
```
The folder '~/dev/STF525_Its/data/v3/profiles' contains an XML file for each certificate to be generated.
This XML file describes the certificate content (e.g. CERT_IUT_A_RCA.xml describes the root certificate for all CERT_IUT_A certificates).

By modifying these files, you can change create new certificate with different geographical area, different validity periods or different SSPs.

To re-generates the certificates, refer to the previous clause.


## Wireshark with support of ETSI ITS Protocols

The official version of Wireshark, supporting ETSI ITS Protocols, is available [here](https://www.wireshark.org/download.html).
Some sample capture files are available [here](https://wiki.wireshark.org/SampleCaptures).

The following instructions enable the verify signature in real time. 
Note: The verify signature can be done only if the certificate in include in the message
- In the Wireshak menu Edit/Preferences, select Protocols in the list on the left 
- Search for 'ETSI ITS GeoNetworking' protocol
- Check the option 'Attempt to verify signatures
- Click on OK to validate your choice

## How to Report a Bug

+2 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ ASN_FILES = CAM/CAM.asn \
            DENM/DENM.asn \
            IS/ETSI_TS_103301/IVIM_PDU_Descriptions.asn \
            IS/ETSI_TS_103301/MAPEM_PDU_Descriptions.asn \
            IS/ETSI_TS_103301/RTCM_PDU_Descriptions.asn \
            IS/ETSI_TS_103301/SPATEM_PDU_Descriptions.asn \
            IS/ETSI_TS_103301/SREM_PDU_Descriptions.asn \
            IS/ETSI_TS_103301/SSEM_PDU_Descriptions.asn \
@@ -38,7 +39,7 @@ ASN_FILES = CAM/CAM.asn \


# PDUs
PDU = CAM DENM MAPEM SPATEM SREM SSEM IVIM EtsiTs103097Data EtsiTs103097Certificate EtsiTs102941Data
PDU = CAM DENM MAPEM SPATEM SREM SSEM IVIM RTCMEM EtsiTs103097Data EtsiTs103097Certificate EtsiTs102941Data

#patches
PATCHES = PsidGroupPermissions.c.diff
+29 −1
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "etsi_ts102941_types_authorization_inner_response.hh"
#include "etsi_ts102941_types_authorization_shared_at_request.hh"
#include "etsi_ts102941_types_authorization_validation_request.hh"
#include "etsi_ts102941_types_authorization_validation_response.hh"
#include "etsi_ts102941_base_types_public_keys.hh"
#include "ieee_1609dot2_base_types_public_encryption_key.hh"
#include "ieee_1609dot2_base_types_public_verification_key.hh"
@@ -230,6 +231,33 @@ namespace LibItsPki__EncdecDeclarations {
    return 0;
  }
  
    BITSTRING fx__enc__AuthorizationValidationResponse(EtsiTs102941TypesAuthorizationValidation::AuthorizationValidationResponse const& p_shared_at) {
    loggers::get_instance().log_msg(">>> fx__enc__AuthorizationValidationResponse: ", p_shared_at);

    etsi_ts102941_types_authorization_validation_response codec;
    OCTETSTRING os;
    if (codec.encode(p_shared_at, os) == -1) {
      loggers::get_instance().warning("fx__enc__AuthorizationValidationResponse: -1 result code was returned");
      return int2bit(0, 1);
    }

    return oct2bit(os);
  }
  
  INTEGER fx__dec__AuthorizationValidationResponse(BITSTRING& b, EtsiTs102941TypesAuthorizationValidation::AuthorizationValidationResponse& p_shared_at) {
    loggers::get_instance().log_msg(">>> fx__dec__AuthorizationValidationResponse: ", b);

    etsi_ts102941_types_authorization_validation_response codec;
    OCTETSTRING is = bit2oct(b);
    if (codec.decode(is, p_shared_at) == -1) {
      loggers::get_instance().warning("fx__dec__AuthorizationValidationResponse: -1 result code was returned");
      return -1;
    }

    loggers::get_instance().log_msg("<<< fx__dec__AuthorizationValidationResponse: ", p_shared_at);
    return 0;
  }
  
  BITSTRING fx__enc__PublicKeys(EtsiTs102941BaseTypes::PublicKeys const& p_public_keys) {
    loggers::get_instance().log_msg(">>> fx__enc__PublicKeys: ", p_public_keys);

+25 −5
Original line number Diff line number Diff line
@@ -587,7 +587,8 @@ namespace LibItsSecurity__Functions
   * \return The HMAC value resized to 16-byte
   */
  OCTETSTRING fx__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) {
    loggers::get_instance().log(">>> fx__hmac__sha256");
    loggers::get_instance().log_msg(">>> fx__hmac__sha256: p__k=", p__k);
    loggers::get_instance().log_msg(">>> fx__hmac__sha256: p__m=", p__m);

    hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm
    OCTETSTRING t;
@@ -595,8 +596,8 @@ namespace LibItsSecurity__Functions
      loggers::get_instance().warning("fx__hmac__sha256: Failed to generate HMAC");
      return OCTETSTRING(0, nullptr);
    }
    loggers::get_instance().log_msg("fx__hmac__sha256: HMAC: ", t);

    loggers::get_instance().log_msg("<<< fx__hmac__sha256: HMAC: ", t);
    return t;
  }

@@ -1183,7 +1184,7 @@ namespace LibItsSecurity__Functions
    return TRUE;
  }

  BOOLEAN fx__store__certificate(const CHARSTRING& p__cert__id, const OCTETSTRING& p__cert, const OCTETSTRING& p__private__key, const OCTETSTRING& p__public__key__x, const OCTETSTRING& p__public__key__y, const OCTETSTRING& p__public__key__compressed, const INTEGER& p__public__key__compressed__mode, const OCTETSTRING& p__hash, const OCTETSTRING& p__hashid8, const OCTETSTRING& p__issuer, const OCTETSTRING_template& p__private__enc__key, const OCTETSTRING_template& p__public__enc__key__x, const OCTETSTRING_template& p__public__enc__key__y, const OCTETSTRING_template& p__public__enc__compressed__key, const INTEGER_template& p__public__enc__key__compressed__mode) {
  BOOLEAN fx__store__certificate(const CHARSTRING& p__cert__id, const OCTETSTRING& p__cert, const OCTETSTRING& p__private__key, const OCTETSTRING& p__public__key__x, const OCTETSTRING& p__public__key__y, const OCTETSTRING& p__public__key__compressed, const INTEGER& p__public__key__compressed__mode, const OCTETSTRING& p__hash, const OCTETSTRING& p__hash__256, const OCTETSTRING& p__hashid8, const OCTETSTRING& p__issuer, const OCTETSTRING_template& p__private__enc__key, const OCTETSTRING_template& p__public__enc__key__x, const OCTETSTRING_template& p__public__enc__key__y, const OCTETSTRING_template& p__public__enc__compressed__key, const INTEGER_template& p__public__enc__key__compressed__mode) {
    loggers::get_instance().log(">>> fx__store__certificate: '%s'", static_cast<const char*>(p__cert__id));

    int result;
@@ -1191,9 +1192,9 @@ namespace LibItsSecurity__Functions
      const OCTETSTRING private_enc_key = p__private__enc__key.valueof();
      const OCTETSTRING public_enc_key_x = p__public__enc__key__x.valueof();
      const OCTETSTRING public_enc_key_y = p__public__enc__key__y.valueof();
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hashid8, p__issuer, p__private__enc__key.valueof(), p__public__enc__key__x.valueof(), p__public__enc__key__y.valueof(), p__public__enc__compressed__key.valueof(), p__public__enc__key__compressed__mode.valueof());
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hash__256, p__hashid8, p__issuer, p__private__enc__key.valueof(), p__public__enc__key__x.valueof(), p__public__enc__key__y.valueof(), p__public__enc__compressed__key.valueof(), p__public__enc__key__compressed__mode.valueof());
    } else {
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hashid8, p__issuer, OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), INTEGER(-1));
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hash__256, p__hashid8, p__issuer, OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), INTEGER(-1));
    }
    
    return (result == 0);
@@ -1293,6 +1294,25 @@ namespace LibItsSecurity__Functions
    return TRUE;
  }

  /**
   * \brief   Read the whole-hash of the certificate using SHA 256
   * \param   p_certificate_id the certificate identifier
   * \param   p_hash   the expected certificate
   * \return  true on success, false otherwise
   */
  BOOLEAN fx__readCertificateHash256(
                                     const CHARSTRING& p__certificateId,
                                     OCTETSTRING& p__hash
                                     ) {
    loggers::get_instance().log(">>> fx__readCertificateHash256: '%s'", static_cast<const char*>(p__certificateId));

    if (security_services::get_instance().read_certificate_hash_sha_256(p__certificateId, p__hash) == -1) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * \brief    Read the private keys for the specified certificate
   * \param   p_certificate_id     the keys identifier
Loading