The FitSec library provides the security engine, implementing messages and certificates processing for Intelligent Transport Systems communication.
The library implements following specifications:
- IEEE 1609.2-2022 - The main specification for ITS security message headers and certificate format
- ETSI TS 103 097 v2.1.1 - The ETSI profile for IEEE 1609.2
- ETSI TS 102 941 v2.2.1 - The PKI and trust mechanisms.
- ETSI TS 103 601 v2.2.1 - The ETSI ITS security extensions.
- ETSI TS 103 759 v2.1.1 - The misbehaviour reporting protocol (the support is ongoing).
Basic library features:
- Designed for minimum memory and CPU consumption.
- Plugin interface for software cryptographic libraries and HSMs.
- Synchronous and asynchronous message processing.
Secured message handling features:
- Encoding and decoding of ITS secured messages, including all extensions, as described in ETSI TS 103 097 v2.1.1.
- Signature generation and verification.
- Message validation, according to signing certificate restrictions.
- Peer-2-peer certificate distribution.
PKI features:
- Multiple root, enrolment and authorization certificate authorities.
- Independent EC and AT certificate pools for each ITS application.
- Creation and handling of certificate (EC or AT) requests.
- Automatic EE certificate selection for outgoing messages.
- Certificate revocation lists (CRL).
- Certificates trust lists (CTL and ECTL).
- Explicit and implicit certificates support.
- Peer-2-peer CRL/CTL requests.
- Certificate requests repetition.
The library can be used with any kind of communication protocol, particularly with the GeoNetworking as described in ETSI EN 302 636-4-1.
The library is written in plain C in cross-platform manner and has been compiled and tested in Linux(gcc) and Windows(mingw32,cygwin and Visual C 14) environments for x86 and ARM platforms. The x86 Linux and Windows binaries provided for testing purposes (contains some feature restrictions). Please contact author for a full verisons.
Try the library using the ITS message simulator: https://github.com/fillabs/fsmsggen
Library dependencies are collected using git submodules:
- cshared - The open-source library providing various utility functions
- fscrypt - The open-source library providing wrappers for various cryptographic engines. For the moment only the following engines are implemented:
- OpenSSL.
- AutoTalk Craton2 HSM engine (not fully tested yet).
- Other cryptographic engines can be implemented using the plugin API as described in fscrypt library README.
The main library API is defined in the fitsec.h header file.
- First of all, the instance of the engine must be created using the
FitSec_New
.
This function takes a configuration structure of type FitSecConfig as a parameter.
The FitSecConfig contains the following configuration fields:
version
- default protocol version. Set it to3
according to IEEE 1609.2 and ETSI TS 103 097flags
- configuration flags bitmap. See theFitSecEngineFlags
data type for possible bit fields.appProfiles
- application profiles list, contains a structures array ofFitSecAppProfile
. Each record contains description of the ITS application in the following fields:aid
- the ITS application ID for the profile.payloadType
- the message payload type to be used for outgoing messages.fields
- bitmap of mandatory fields to be included into an outgoing message. SeeFitSecAppProfileFlags
for details.certPeriod
- delay in milliseconds between inclusion of certificates in application messages. Special values are:-1
- do not send any certificates and sign all messages using digest0
- send certificates within each outgoing message (default for DENM, SPAT, MAP, etc.)- some positive value defines a maximum delay between two messages containing certificates. For example set to 1000 to send certificate each second (default for RSU CAM)
certChangePeriod
- the maximum usage time in seconds for the AT certificate. After this period new AT certificate will be loaded from the pool.
encKeyStorageDuration
period in seconds when system keeps previously used symmetric key for decrypting incomming messages (PKI messages only for now). -storeTrustInformation
call user call-back to store received CA certificates, CRLs and CTLs.
Crypto engines:
The library provides a flexible way for using different crypto engines for different purposes. Crypto engines are referenced by names. Two crypto engines are supported now: openssl
and atlk
(AutoTalk Craton 2 HSM library). Please have a look on cryptographic plugin definition in fitsec_crypt_plugin.h and fitsec_hash_plugin.h.
hashEngine
the crypto engine used for hash functions. Currently "openssl" and "atlk" are supported, set to NULL for autoselectsignEngine
the crypto engine for signing: "openssl", "atlk", NULL by defaultverifyEngine
the crypto engine for sugnature verification: "openssl", "atlk", NULL by defaultencryptEngine
the crypto engine for EC encrypting engine: "openssl", "atlk", NULL by defaultdecryptEngine
the crypto engine for EC decryption: "openssl", "atlk", NULL by defaultsymmEncryptEngine
the crypto engine for symmetric encryption: "openssl", "atlk", NULL by defaultsymmDecryptEngine
the crypto engine for symmetric decryption: "openssl", "atlk", NULL by defaultmacEngine
the crypto engine for MAC calculatoin: "openssl", "atlk", NULL by defaultrandomEngine
the crypto engine for random function: "openssl", "atlk", NULL by default
Callbacks:
The library has two work modes: synchronous and asynchronous. In asynchronous mode the library interacts with the upper level using the set of callback functions. These callbacks are defined in the configuration structure:
cbOnSigned
user callback function to be called when the outgoing message is signed and ready to be sent to the networkcbOnValidated
user callback function to be called when the incoming message is validatedcbOnEncrypted
user callback function to be called when the outgoing message is encryptedcbOnDecrypted
user callback function to be called when the incoming message is decryptedcbOnEvent
user callback function to be called when some event is occurred (@see FSEventId)cbOnEventUser
user pointer to be passed to all callback functions
Certificate pool parameters:
maxReceivedPoolSize
maximum size of the pool for AT certificates, installed in the system.maxReceivedLifeTime
maximum life time of AT certificates of received messages.purgePeriod
period in seconds when certificate pools must be purged. Set to 0 to do not purge at all. In this case two previous parameters doesn't make any sense.ctlCheckPeriod
period in seconds when the engine shall check for new CTLs. Shall be at least 24h for real usage.crlCheckPeriod
period in seconds when the engine shall check for new CRLs. Shall be at least 24h for real usage.
This configuration structure can be initialized using the FitSecConfig_InitDefault
and modified according to user's needs. Please have a look at the fitsec.h for the description of configuration fields.
- Install all necessary certificates using function
FitSec_InstallCertificate
.
Any types of certificates can be installed: Root, TLM, EA, EC, AA, AT or any other custom certificate types in any order. Pay attention, that all root certificates installed by this function will be verified against itself and considered as trusted. Authorization tickets shall be followed by the correspondent private keys or HSM key identifiers.
CTL/ECTL/CRL can also be installed. See CTL/CRL support chapter for information.
- Now the engine is ready to work. Encode and decode messages can be started.
Processing of outgoing signed messages is split into two stages:
- preparation of the message header
- signing the message
To optimize the memory manipulation efforts, all message operations performed directly within the message buffer, provided by the facility layer.
This buffer, containing encoded message, can be passed later to the transport layer. The buffer shall contain anough space for all security headers, certificates and the payload of the message.
According to the GeoNetworking specification, the Security Header takes place between Basic GN Header and Common GN Header elements in GeoNetworking message structure.
Geonetworking layer shall execute the following steps to encode a secured message:
- allocate (or prepare) a memory buffer.
- prepare Basic GN Header strucutre.
- call
FitSec_PrepareSignedMessage
to prepare Security header - fill the payload buffer with the payload data, starting from the Common GN Header, following by BTP and facility payload.
- update the payload size field in message information structure.
(Note: Please don't spend too much time in this stage because it can violate the CAM signing rules.)
- call
FitSec_FinalizeMessage
orFitSec_FinalizeSignedMessageAsync
to sign the message.
Please see the fitsec.h for function descriptions.
To start the security envelop encoding, the upper layer shall call FitSec_PrepareSignedMessage
to create the Security Header element and to put it into the outgoing buffer.
This function must be called with the message information structure, containing following information:
message
andmessageSize
containing the outgoing buffer address and sizepayloadType
containing the type of the security envelop: signed, encrypted, etc. (optional, set toFS_PAYLOAD_AUTO
by default).position
containing current geographic position if necessary. (optional, not needed for CAM)generationTime
containing the timestamp when the last GPS fix has been occured.sign
containing information about signing procedure. Following fields should be set:signerType
containing the type of signer. Set toFS_SI_AUTO
to set the signer type automatically, according to the ITS application ID. Other values to be used:-
FS_SI_CERTIFICATE
orFS_SI_DIGEST
- use certificate or certificate digest to sign the message.Certificate can be provided in
sign.cert
field or can be selected automatically according to provided time, position and ITS application ID. -
FS_SI_SELF
- sign message using the private key provided insign.priv
field.This field can be NULL during this stage but should be filled in with real value on the finalizing stage. The signing algorithm shell be specified in
sign.alg
field.
-
ssp
containing application ID and SSP bits, describing the content of the message. The ITS AID list can be found on ISO TS17419 V2016-02-09: "ITS-AID_AssignedNumbers". SSP bits values described in ITS service standards.
The function creates the ITS Security Header in the provided buffer and fill the message information structure with:
payload
containing the pointer to the memory buffer where the payload data shall be copied.payloadSize
containing the maximum size of the payload buffersign
containing some information about signing procedure:signerType
is set to the actual type of signer:FS_SI_CERTIFICATE
,FS_SI_DIGEST
orFS_SI_SELF
cert
is set to the certificate to be used to sign message ifsignerType
is set to theFS_SI_CERTIFICATE
orFS_SI_DIGEST
. This value can be changed before or during the final stage.
The data in the message information structure will be used on the next stage, so please keep it unchanged, excepts the payload size.
The function returns the offset in the buffer to copy the payload or 0 in case of some error. The error ID is provided in the message information structure.
Please see the fitsec.h for function descriptions.
The GeoNetworking layer needs to create the Common Header and, optionally the Extended Header elements, and put the facility layer payload into the outgoing buffer.
The total length of these elements shall be set in the payloadSize
field in the message information structure.
When the payload buffer is filled in, the message shall be signed or encrypted, according to the payload type.
The user code must call FitSec_FinalizeMessage
to perform these tasks. For asynchronous procedure the FitSec_FinalizeSignedMessageAsync
can be used.
This function takes the same parameters as the FitSec_PrepareMessage
.
The function returns the full size of secured packet or 0 in case of error. The error ID is provided in the message information structure.
The library supports encryption based on IEEE 1609.2 specifications using algorithms defined in ETSI TS 103 097. The encryption of the outgoing messages shall follow the same procedure as signing:
- preparation of the buffer using
FitSec_PrepareEncryptedMessage
- adding one or more recipients.
- applying the payload
- encrypting using
FitSec_FinalizeEncryptedMessage
To start the encryption process, the FitSec_PrepareEncryptedMessage
function shoall be called to initialize the outgoing buffer with the message header.
The function should be called with the message information structure, containing:
message
andmessageSize
containing the outgoing buffer address and sizepayloadType
containing the type of the security envelop: signed, encrypted, etc. (optional, set toFS_PAYLOAD_AUTO
by default).generationTime
containing the timestamp, when the last GPS fix has been occured. This field is needed to select proper certificates and to process cached values.
The encrypted message can be addressed for up to 8 recipients. For the moment the library supports two types of encryption recipients: certificate or pre-shared keys (PSK). Not more than 1 PSK recipient is allowed.
To add a certificate as a recipient, the function FitSec_AddEncryptedMessageCertificateRecipient
shall be called with message information structure and the certificate id.
To add a PSK recipient, the FitSec_AddEncryptedMessagePSKRecipient
shall be called. The actual symmetric key can be set using the symkey
parameter or it can be referenced using digest
if the key was used recently and is expected in the keys cache. The encKeyStorageDuration
parameter defines an encryption cache lifetime.
The payload data shall be copied into the payload
buffer.
The total length of the payload shall be set in the payloadSize
field in the message information structure.
The actual encryption is the final step of the whole procedure. The function FitSec_FinalizeEncryptedMessage
shall be called to proceed with message encryption.
Be aware, if PSK recipient was added in the message, the field encryption.pub
shall point to the encryption public key.
The function returns the total size message in bytes or 0 if some error was occurred.
Incoming message processing is also split into 2 stages: message parsing and message validating. Validating phase can be skipped if message is discarded by the upper layer.
The function FitSec_ParseMessage
shall be used to read the incoming message.
The function shall be called with message information structure, containing following parameters:
message
- pointer to the message buffermessageSize
- size of the message to parsegenerationTime
- the current time to be used for cache processing.payloadType
- can contain a type of the payload. If actual payload doesn't fit the requested one, the parsing is failed. Set toFS_PAYLOAD_AUTO
to accept any type of payload.
The function will fill the content of the message information structure:
payload
,payloadSize
andpayloadType
with actual information about the message payloadposition
andgenerationTime
with the sender position and time when message was sent if this information exists in the incomming message.sign
contains additional information for signed message:signerType
- type of the signer (certificate, digest, or pre-shared key)ssp
- contains information about the application ID and service specific permissionscert
- certificate been used for signing (if any)
- 'encryption' contains information about encrypted message:
symm
- symmetric algorithm and encryption keycert
- certificate to be used to decrypt messagepriv
- private key to decrypt message if it was found in the keys cache.
When incomming message has been parsed, and the message type is set to FS_PAYLOAD_SIGNED or FS_PAYLOAD_SIGNED_EXTERNAL, the upper layer can decide to to verify message signature and validate conformance to the signing certificate restrictions, using functions FitSec_ValidateSignedMessage
or FitSec_ValidateSignedMessageAsync
.
Be aware, message verification procedure doesn't match the SSP bits with the content of facility payload. It is up to user to check the conformance of the incoming message with correspondent SSP bit fields and to take this message into account or skip it.
Validating function shall be called with message information structure, filled in by the message parsing function. Following fields should be set in the structure, depending of the sign.signerType
value:
sign.cert
shall contain pointer to theFSCertificate
if signer type is FS_SI_DIGEST or FS_SI_CERTIFICATE.sign.pub
shall contain pointer to theFSPublicKey
if signer type is FS_SI_SELF.sign.alg
shall be set to the actual signing algorithm if signer type is FS_SI_SELF.
Function returns true or false and set the error ID in the message information structure.
The function FitSec_DecryptMessage
needs to be called to decrypt encrypted message if message type is set to FS_PAYLOAD_ENCRYPTED.
The function shall be called with the following message information fields:
encryption
:cert
shall contain pointer to FSCertificate field containing description private key if recipient type is certificate. Parsing function sets this field if certificate is installed in the system.priv
shall contain the decryption private key if recipient key is PSK. The key is set to the proper value by the parsing function if the key is installed on the system.
generationTime
shall be set to the current time to manage key and certificate cache.
The function decrypts the payload, sets the payload size to the correct value and update the encryption.symm
information field with symmetric key information.
The function returns size of the payload or 0 in case of error.
The library supports the CRL and CTL (ECTL) processing as defined in ETSI TS 102 941.
The CRL and CTL/ECTL message can be passed to the library using the FitSec_ApplyTrustInformationMessage
call. The message information field shall be filled in by the message parsing step. The function validates the message, so no needs to call FitSec_ValidateSignedMessage
explicitly.
There is a way to pass the raw data instead of already parsed message using the FitSec_ApplyTrustInformation
call, providing the data buffer containing OER representation of CTL or CRL.
Pay attention, CRL/CTL signing certificate shall be already installed in the system.
There is also a way to request CRL/CTL information from distribution centres (DC) using the FitSec_RequestTrustInfo
.
PKI communication (enrolment and authorization) API is described in fitsec_pki.h.
PKI submodule shall be initialized using FitSecPki_New
providing the following configuration elements of the FitSecPkiConfig
structure:
station
shall contain ITS station identifiers, such as:id
andid_len
contains canonical station identifier to be used for enrolmentpriv
points to the canonical private key to be used to sign enrolment requestsalg
contains security algorithm of that private key
reqStorageDuration
contains duration in seconds to store PKI requests information after been sent. Set it to at least 10 seconds to let PKI servers do their job especially when certificate retransmission mechanism is used.
There are two functions to create outgoing PKI request: FitSecPki_PrepareECRequest
and FitSecPki_PrepareATRequest
and another two functions to process received responses: FitSecPki_loadMessage
and FitSecPki_loadData
.
Outgoing request function takes the certificate request information and the message information as parameters and fills the message buffer in the message information structure with the actual certificate request message. It is up to upper layer to transmit this message to the PKI distribution centre using the known access point URL.
The following message information fields shall be set for both calls:
message
andmessageSize
shall contain memory buffer and it size to store resulting message.
The access point URL can be associated with the CA certificate using CTL or manually using the FSCertificate_SetDC
and got back using the FSCertificate_GetDC
function.
To trigger the enrolment procedure, the upper layer shall call FitSecPki_PrepareECRequest
.
Function prepares the encrypted message in the provided message information structure, either using provided EA certificate in the encryption.cert
field or selecting the proper EA automatically if this field is NULL.
The library can select EA certificate according to the provided requested certificates parameters.
Library will store the request hash internally to be able to proceed with the received answer.
Authorization request messages can be made using the FitSecPki_PrepareATRequest
function call.
The whole procedure is identical to the enrolment one.
- The library doesn't support the Butterfly Key Expansion mechanism, as described in ETSI TS 102 941 v2.x.x
- The library binaries have run-time limitations:
- not more than 100 messages can be processed.
- the library is working only during the year when it was compiled.
To remove all try-&-buy limitations ask author for the license.
- Misbehaviour reporting, as specified in ETSI TS 103 759
- CTL/CRL distribution, as specified in ETSI TS 103 601
The library was created and supported since 2015 by Denis Filatov (denis.filatov()fillabs.com) as a validation tool for the ETSI's ITS security test suite. The library is NOT a free product. Please contact author for the license.