Added some security documentation.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
Martin Bremmer 2019-12-16 15:59:42 +01:00 committed by eboasson
parent 91111af0ea
commit 514bf75276
6 changed files with 1052 additions and 0 deletions

View file

@ -0,0 +1,406 @@
# DDS Security effort
ADLink has decided to donate their Vortex OpenSplice DDS Security
implementation to the Cyclone DDS project. However, that will not be a simple
code drop.
This document catches all the work that is foreseen to port Vortex OpenSplice
DDS Security to Cyclone DDS.
This document can be removed when DDS Security has been implemented.
**Table of contents**
- [Definition of done](#done)
- [Footprint](#footprint)
- [Multi process testing (done)](#testing)
- [Runtime library loading (done)](#loading)
- [Hopscotch utility (done)](#hopscotch)
- [FSM utility (in progress)](#fsm)
- [Port DDS Security plugin API (done)](#port-api)
- [De-Serializing messages in DDSI (done)](#deserializing)
- [De-Serializing security message parameters in DDSI (done)](#deserializing_plist)
- [Port DDS Security builtin plugins (in progress)](#port-plugins)
- [Port DDSI DDS Security (in progress)](#port-ddsi)
- [Move configuration (in progress)](#Move-configuration)
- [Failure handling](#failures)
- [Multiple configurations](#multiple-configurations)
- [Example](#example)
- [QosProvider](#qosprovider)
- [Data Tags (optional)](#datatags)
## Definition of done<a name="done" />
When this document tells that a certain aspect is 'done', it means that it
has been accepted into the security branch of the cyclonedds repository
(https://github.com/eclipse-cyclonedds/cyclonedds/tree/security).
However, it is possible that various parts need some rework before the security
branch can be merged into the cyclonedds master branch.
## Footprint<a name="footprint" />
A non-functional requirement is that cyclonedds should be buildable without
the DDS Security support in it. That will reduce the footprint (and possibly
improve performance) for applications that don't need security.
For that, the ENABLE_SECURITY build option is introduced that translates into
the DDSI_INCLUDE_SECURITY compile switch. However, the usage of that switch
should not explode. That'll reduce the maintainability.
For instance, the usage of the switch can be minimized by using functions that
will reduce to an inline function that just returns a hardcode value when
security is not included (otherwise they'll do some certain task).
The compiler can use these inline functions to do clever stuff regarding
footprint and performance.
There can be other solutions to decrease security footprint without impeding
on the maintainability of the code by inserting the switch too much.
## Multi process testing (done)<a name="testing" />
To properly test DDS Security, multi process testing will be necessary.
This is not yet available in Cyclone DDS.
See the [Multi Process Testing](multi_process_testing.md) document for
more information.
## Runtime library loading (done)<a name="loading" />
The ddsi component needs to be able to load DDS Security plugins at runtime.
These plugins are provided as libraries.<br>
Loading libraries at runtime is currently not possible in Cyclone DDS.
## Hopscotch utility (done)<a name="hopscotch" />
This hash table is used by the Security plugins.<br>
Both versions on OpenSplice and Cyclone are equivalent.<br>
No additional effort is expected.
## FSM utility (in progress)<a name="fsm" />
The Finite State Machine utility has been introduced in OpenSplice to support
the handshake of DDS Security.<br>
This has to be ported to Cyclone.
However, it already has some technical dept, which should be removed before
adding it to Cyclone. This means that a refactor should happen as part of the
porting.
The related DBTs should also be ported to Cyclone unit tests.
It was decided to just port the FSM at the moment. The refactor will take place
when trying to get the security branch into master.
## Port DDS Security plugin API (done)<a name="port-api" />
The DDS Security plugin API are just a few header files. The ddsi component
uses that to link against. The implementation of the API is done in the
individual plugins. The plugins are [loaded at runtime](#loading) (when
configured).
This means that ddsi can be DDS Security prepared (after building against this
API) without there being actual DDS Security plugins.
It seems to be just a code drop of a number of header files.<br>
Maybe add some CMake module for both ddsi and the plugins to easily link
against?
## De-Serializing messages in DDSI (done)<a name="deserializing" />
DDSI needs to be able to (de)serialize a few Security messages. In OpenSplice,
some functionality of the database is used. This is unavailable in Cyclone.
What is available is a serializer that uses marshaling operations (see, for
for instance, m_ops in the dds_topic_descriptor struct).
The (de)serializing of the Security messages should be supported by supplying
the m_ops sequences, message structs (if not yet available) and some
convenience functions using both.
## De-Serializing security message parameters in DDSI (done)<a name="deserializing_plist" />
DDSI needs to be able to (de)serialize a few message parameters that have
been introduced by the DDS Security spec.
## Port DDS Security builtin plugins (in progress)<a name="port-plugins" />
No major changes between the DDS Security plugins in OpenSplice and Cyclone
are expected.
The DDS Security plugins require OpenSSL. Cyclone DDS already uses OpenSSL.
However, it expects (or at least it's preferred to have) version 1.1 or newer,
while the OpenSplice Security plugins are build against 1.0.2. There are some
API changes between the two versions. This will take some porting effort.
The build system should be ported from makefiles to cmake files.
There are security_plugin DBTs in OpenSplice. These tests are base on cunit,
which is also used in Cyclone. However, it is used slightly different. A small
porting effort is expected (i.e. let it work with cmake and runner generation).
This means some additional effort, compared to just a code drop. But it is not
expected to be major.
- Authentication plugin (done).
- Access Control plugin (in progress).
- Cryptography plugin (done).
There are a few sub-features that can be implemented separately.
- Check/handle expiry dates (in progress).
- Trusted directory support.
- etc?
## Port DDSI DDS Security (in progress)<a name="port-ddsi" />
There is already quite a bit of difference between the DDSI codebases in
OpenSplice and Cyclone. So, the copy/merge of the DDSI Security code from
OpenSplice to Cyclone will not be trivial.
Most parts of the merging will not be trivial, but should be quite
straightforward nonetheless. Things that are noticed to be somewhat different
between the DDSI code bases that could impact the merging work:
- Entity matching is slightly different.
- The q_entity.c has a lot of differences that can obfuscate the differences
related to DDS Security.
- Unacked messages logic has changed a bit. Does that impact gaps?
- (De)serializing, of course
(see also [De-Serializing in DDSI](#deserializing)).
- Writer history cache is different, which can impact the builtin volatile
Security endpoints.
- Unknown unknowns.
The buildsystem has to be upgraded.<br>
- A few files are added which are easy to add to cmake.<br>
- There's a new dependency on the [DDS Security API](#port-api), which is done.
Then, of course, there are the tests<br>
First of all, [Multi Process Testing](#testing) should be available, which now
it is.<br>
When that's the case, then the OpenSplice tests business
logic have to be ported from scripts and applications to that new framework.
That porting shouldn't be that hard. However, it will probably take a while.
The DDSI Port doesn't have to be a big bang. It can be split up into various
different pull requests. Examples are
- Extend configuration XML parsing with the security configuration (done).
- Extend nn_qos with security related policies. Fill them with values from the
configuration when applicable (done).
- Add DDS Security endpoints that are non-volatile (done).
- Add DDS Security endpoint that is volatile. This change has more impact than
all the non-volatile endpoints combined (done).
- Handshake (in progress).
- Payload (en)(de)coding (DDSI support: done. Wrapper: todo).
- Submsg (en)(de)coding (DDSI support: done. Wrapper: todo).
- RTPSmsg (en)(de)coding (DDSI support: done. Wrapper: todo).
- Etc
## Move configuration (in progress)<a name="Move-configuration" />
After the port, the DDS Security configuration is still (partly) done through
the overall configuration XML file (rest is coming from the permissions and
governance files).<br>
However, according to the specification, the configuration should happen by
means of the Participant QoS.
The ddsc dds_qos_t is mapped on the ddsi xqos. The ddsi xqos already has the
necessary policy (after the [port](#port-ddsi)), namely the property_policy.
This means that the ddsc qos itself is automatically prepared.<br>
However, getting and setting policies are done through getter and setter
functions in ddsc.<br>
This means we have to add these functions for the security configuration values.
The ddsc policy getter and setter functions use (arrays of) primitive types as
arguments. The configuration of Security is given by means of the property
policy, which isn't a primitive. To keep in line with the QoS API, we could add
something like:
```cpp
typedef struct dds_properties_t; /* opaque type in API, but mapped to
nn_property_qospolicy_t internally */
dds_properties_t *dds_properties_create();
void dds_properties_delete(dds_properties_t *);
void dds_properties_merge(dds_properties_t *, dds_properties_t *);
void dds_properties_add_property(dds_properties_t *, char *name, char *value);
void dds_properties_add_binaryproperty(dds_properties_t *, char *name,
uchar *value, int valuelength);
void dds_qset_properties(dds_qos_t*, dds_properties_t *);
void dds_qget_properties(dds_qos_t*, dds_properties_t **);
```
But this is very preliminary and is still up for debate.
After moving the Security configuration to the participant QoS, it's possible
to have different configurations within a single application if you have
multiple participants. However, ddsi only supports one Security configuration
for now. That doesn't change by changing where that configuration comes
from.<br>
To solve this, it is expected that creation of a participant with a different
configuration will force a failure for now.
Until [Multiple Configurations](#multiple-configurations) is implemented.
After the ddsc API has been extended, we can decide on what to do with the
configuration through XML.
- Keep it. It seems usable: no need to change applications when changing (or
adding) Security settings. However, conflicts between XML and QoS
configuration could cause problems. Simplest seems to be to only allow QoS
security configuration when it's not configured in XML already.
- Remove it. No conflict resolving needed.
All the Security tests depend on providing (different) configurations through
XML. Depending on if we keep or remove the XML configuration option, a lot of
tests have to be updated, or a few added (that test security configuration
through QoS).
For the loading of the plugin libraries, properties with specific names have to
be added to the property policy to know the location and names of the plugins.
As inspiration, fastrtps can be used:
https://github.com/ros2/rmw_fastrtps/blob/master/rmw_fastrtps_shared_cpp/src/rmw_node.cpp#L296
## Failure handling<a name="failures" />
Currently, when an local action is tried that isn't allowed by DDS Security
(like creating a participant when it's not permitted), DDSI is shut down.<br>
Mainly because in OpenSplice it's quite hard to get a failure state from DDSI
to the application.
In Cyclone, however, ddsc::dds_create_participant() results in a direct call to
ddsi::new_participant(). This means that if creation of an entity (or
participant in this example) fails due to security issues in ddsi, we can fail
the actual ddsc API call with a proper error result (there's already the
DDS_RETCODE_NOT_ALLOWED_BY_SECURITY in the ddsc API (not used)).
Maybe we have to do some additional cleanup when a failure is encountered.
Some tests probably have to be adjusted for the new behaviour.
## Multiple configurations<a name="multiple-configurations" />
Currently (because it's done through the overall XML configuration), only one
DDS Security configuration could be supported. Because of this fact, at various
locations, shortcuts could be made in both DDSI and plugins.<br>
However, because the configuration is coming from participants now (see
[Move Configuration](#Move-configuration), we should be able to support
multiple different DDS Security configurations.
Until now, the creation of a second participant with a different configuration
would force a failure (again, see [Move Configuration](#Move-configuration)).
It is expected that the plugin loading still happens through the configuration
XML (see [Move Configuration](#Move-configuration)). This means that DDSI doesn't have to support
multiple sets of plugins. Just the one set, provided at initialization. This
means that DDSI shouldn't have to be changed to support this.
So, it's the plugins need to be able to support multiple configurations.
The Cryptography plugin doesn't seem to care about global DDS Security
configurations. It has basically configurations per participant/topic/
endpoints, which already works. So, this plugin doesn't have to be upgraded.
The Authentication plugin does have global DDS Security configurations. Main
function related to that is validate_local_identity(). This function already
creates a new local identity every time it is called. So, this plugin doesn't
have to be upgraded either.
That leaves the Access Control plugin.<br>
The main function related to configuration is validate_local_permissions().
This function creates access rights depending on Permissions and Governance
files. Currently, there's only one local 'rights' structure that is linked
directly to the plugin (see also the ACCESS_CONTROL_USE_ONE_PERMISSION compile
switch).<br>
This has to change.<br>
The local rights structure needs to be coupled to a participant. This also
means that we have to search for it instead of having direct access when
entering the plugin.<br>
The remote rights can be used as example. That is basically a list of rights/
permissions with the remote identity handle as key.
Tests have to be added to make sure that a setup with different Security
configurations works.
## Example<a name="example" />
A Security example has to be added.
## QosProvider<a name="qosprovider" />
The Participant QoS now contains Security related information. This means that
the QosProvider has to be upgraded to support that.
## Data Tags (optional)<a name="datatags" />
The specification is somewhat fuzzy about the data tags.
The following is a summary (still elaborate) of how it seems to work:
The permissions document can contain the <data_tags> tag on publish and
subscribe level. It's related to the data samples, but don't have to be related
to the keys of those samples.<br>
The QoS of a writer/reader can also have data tags by means of the
DataTagQosPolicy. A writer/reader can only be created when the data_tags in the
QoS matches those in the permissions document. This check should happen on both
the local and remote level.
This creation check is the only thing that DDS Security actually does with the
data tags. They are only authenticated by DDS Security, but not interpreted
further.<br>
This is only a minor security addition, because the publisher can still publish
data that doesn't match the data tags because DDS doesn't interpret the data
nor compares it with the data tags.
What it can be used for is a kind of custom access control scheme on the
application level.<br>
An application that consumes data can see if a publisher is allowed to publish
that sample by comparing the data within the sample with the data tag(s)
associated with that publisher. As said, this comparison is not done on the DDS
level, but has to be done within the application itself.
That leaves the question, how does the application get the tags associated with
the related writer?<br>
In other words; the application gets a sample. It has to know from which writer
it originated and it has to have access to the data tag(s) of that writer.
The dds_sample_info_t contains the dds_instance_handle_t publication_handle,
which is unique to the writer (locally).<br>
That dds_instance_handle_t can be used to get the right
DDS_Security_PublicationBuiltinTopicDataSecure sample for the related secure
builtin reader [**note1**].<br>
DDS_Security_PublicationBuiltinTopicDataSecure contains QoS information
regarding that writer, including the DataTagQosPolicy. The remote
DDS_Security_PublicationBuiltinTopicDataSecure contents have been authenticated
by DDS Security and the data tags can be trusted.<br>
The application can check the sample data against the data_tags within that
QoS.
Things to do:
- Add DataTagQosPolicy to the ddsc API and the related QoSses.
- Add DDS_Security_PublicationBuiltinTopicDataSecure data type to the ddsc API
(better yet, all secure builtin types).
- Add the related builtin reader to the ddsc99 API (better yet, all secure
builtin readers).
- Add test regarding the secure builtin readers and data.
- Add data tag comparisons between QoS and permission documents during local
and remote entity creation.
- Add data tag remote/local (mis)match tests.
Especially because of the lack of access to builtin secure readers, supporting
data tags doesn't seem feasible in the near future. Also, it's optional in the
specification.
**note1**
That DDS_Security_PublicationBuiltinTopicDataSecure reader is not yet available
within the ddsc API, nor is the related data type. Don't know how much work it
would be to add them to that API.

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

646
docs/manual/security.rst Normal file
View file

@ -0,0 +1,646 @@
.. _`DDS Security`:
############
DDS Security
############
CycloneDDS is (will be) compliant with The Object Management Group (OMG) DDS Security specification.
This specification defines the Security Model and Service Plugin Interface (SPI) architecture for
compliant DDS implementations. The DDS Security Model is enforced by the invocation of these SPIs
by the DDS implementation.
.. image:: ./_static/pictures/dds_security_overview.png
:width: 1000
The three plugins that comprise the DDS Security Model in CycloneDDS are:
**Authentication Service Plugin**
Provides the means to verify the identity of the application and/or user that invokes operations
on DDS. Includes facilities to perform mutual authentication between participants and establish
a shared secret.
**AccessControl Service Plugin**
Provides the means to enforce policy decisions on what DDS related operations an authenticated
user can perform. For example, which domains it can join, which Topics it can publish or
subscribe to, etc.
**Cryptographic Service Plugin**
Implements (or interfaces with libraries that implement) all cryptographic operations including
encryption, decryption, hashing, digital signatures, etc. This includes the means to derive keys
from a shared secret.
----
CycloneDDS provides built-in implementations of these plugins. Authentication uses PKI
(Public Key Infrastructure) with a pre-configured shared Certificate Authority, RSA is used for
authentication and Diffie-Hellman is used for key exchange. AccessControl use Permissions document
signed by shared Certificate Authority. Cryptography uses AES-GCM (AES using Galois Counter Mode)
for encryption and AES-GMAC for message authentication.
The plugins are accessed by the DDSI2 service when DDS Security is enabled by supplying the
security configuration within the XML configuration or Participant QoS.
Security plugins are dynamically loaded where the locations are defined in CycloneDDS
configuration or Participant QoS settings.
*******************************************************
Brief information about PKI (public key infrastructure)
*******************************************************
The comprehensive system required to provide public-key encryption and digital signature services
is known as a public-key infrastructure (PKI). The purpose of a PKI is to manage keys and
certificates. By managing keys and certificates through a PKI, an organization establishes and
maintains a trustworthy networking environment.
Public Key Cryptography: Each user has a key pair, generated during the initial certificate
deployment process, that is comprised of a public key, which is shared, and a private key, which
is not shared. Data is encrypted with the users public key and decrypted with their private key.
Digital signatures, used for non-repudiation, authentication and data integrity, are also generated
using public key cryptography.
**Identity Certificate**
This is an electronic document used to prove the ownership of a public key. The certificate
includes information about the key, information about the identity of its owner (called the
subject), and the digital signature of an entity that has verified the certificate's contents
(called the issuer). If the signature is valid, and the software examining the certificate
trusts the issuer, then it can use that key to communicate securely with the certificate's
subject.
**Certificate Authority**
This issues user certificates and acts as the chief agent of trust. When issuing a certificate
to a user, the CA signs the certificate with its private key in order to validate it. During
electronic transactions the CA also confirms that certificates are still valid. Certificates
may be revoked for various reasons. For example, a user may leave the organization or they may
forget their secret passphrase, the certificate may expire or become corrupt. This process is
usually accomplished through the use of a Certificate Revocation List (CRL) which is a list of
the certificates that have been revoked. Only the certificates that have been revoked appear on
this list.
**Subject of Identity Certificate**
This is the identity to be secured. It contains information such as common name (CN),
organization (OU), state (ST) and country (C).
**Subject Name**
This is aka distinguished name and is the string representation of certificate subject.
ie: emailAddress=alice\@adlink.ist,CN=Alice,OU=IST,O=ADLink,ST=OV,C=NL
*************************
PKI Usage in DDS Security
*************************
.. image:: ./_static/pictures/pki_overview.png
:width: 1000
Alice and Bob are the DDS participants who have their private and public keys. Identitity
Certificate Authority (ID CA) has its own self-signed certificate (IdentityCA in the diagram).
ID CA gets Alice's subject information and public key and generates an IdentityCertificate for her.
Alice's certificate includes her public key and certificate of ID CA; so that her certificate can
be verified if it is really issued by ID CA.
Access Control is configured with governance and permissions files.
Governance file defines the security behavior of domains and topics.
Permissions file contains the permissions of the domain participant, topics, readers and writers,
binds them to identity certificate by subject name (distinguished name).
Governance files and Permissions files are signed by Permission CA. Signed documents also
contains Permissions CA certificate; so that they can be verified if they are really issued
by Permissions CA.
Authenticated participants handshakes with each other and generates a shared key by Diffie-Hellman
key exchange. This shared key is used for encrypting/decrypting data with AES.
During the handshake Alice checks Bob's certificate and Bob's Permissions file if they are really
issued by the ID CA certificate and Permissions CA Certificate that **she** has. Also Bob checks
Alice's certificate and Alice's Permissions file if they are really issued by the ID CA certificate
and Permissions CA that **he** has.
Permissions file can contain permissions for several identities; so subject name of identity
certificate exist in permissions file to establish a binding between identity and its permissions.
*************
Configuration
*************
.. image:: ./_static/pictures/dds_security_configuration_overview.png
:width: 1000
The configuration of DDS Security is split up into two parts.
- `Plugins Configuration`_
- `Access Control Configuration`_
This section explains the configuration in details. However, you can see a concrete example on
security section of Example Readme file.
.. _`Plugins Configuration`:
Plugins Configuration
*********************
TODO: Update to reflect the configuration through QoS policies.
| CyclonDDS gets the plugin configuration from DDS2I configuration elements or the Participant QoS
Policies as stated in the DDS Security specification.
| This behavior allows applications to use DDS Security without update. Only supplying a new
configuration with DDS Security enabled is enough to switch from a non-secure to a secure
deployment. However, the same DDS Security configuration is forced upon all the participants
within the federation.
| The configuration options are bundled in the ``DDSSecurity`` configuration section in DDS2I.
| Every DDS Security plugin has its own configuration sub-section.
.. _`Authentication Properties`:
=========================
Authentication Properties
=========================
| To authenticate CycloneDDS, it has to be configured with IdentityCertificate
(DDSSecurity/Authentication/IdentityCertificate - see Configuration Guide - DDS Security).
This IdentityCertificate is used to authenticate all participants of that particular
CycloneDDS domain.
| Associated with the IdentityCertificate is the corresponding PrivateKey
(DDSSecurity/Authentication/PrivateKey).
The PrivateKey may either be a 2048-bit RSA or a 256-bit Elliptic Curve Key with
a prime256v1 curve.
| IdentityCA (DDSSecurity/Authentication/IdentityCA) is the certificate of Identity Certificate
Authority (CA) which is the issuer of the IdentityCertificate. The public key of the
IdentityCA shall either be a 2048-bit RSA key or a 256-bit Elliptic Curve Key for the prime256v1
curve. The identity_ca can be a self-signed certificate.
| Currently the IdentityCertificate, IdentityCA and PrivateKey should be a X509 document in pem
format.
It may either be specified directly in the configuration file or the configuration file should
contain a reference to a corresponding file.
| Optionally the PrivateKey could be protected by a password (DDSSecurity/Authentication/Password).
| Furthermore the CycloneDDS configuration allows to configure a directory containing additional
IdentityCA's
which are used to verify the identity certificates that are received by remote instances
(DDSSecurity/Authentication/TrustedCADirectory). This option allows to use more than one identity
CA throughout the system. TrustedCADirectory is an extension to DDS Security specification; so it
can not be used when communicating with other vendors.
.. _`Access Control Properties`:
=========================
Access Control Properties
=========================
Governance Document (DDSSecurity/AccessControl/Governance),
Permissions Document (DDSSecurity/AccessControl/Permissions) and
Permissions CA Certificate (DDSSecurity/AccessControl/PermissionsCA) are required for access
control plugin. See DDS Security section of Configuration Guide for property descriptions. They
can be provided by data itself (with CDATA) or path to file on disk.
.. _`Cryptography Properties`:
=======================
Cryptography Properties
=======================
Cryptography plugin has no property
.. _`Access Control Configuration`:
Access Control Configuration
****************************
| Access Control configuration consists of Governance document and Permissions document.
Both governance and permissions files must be signed by the Permissions CA in S/MIME format.
Participants use their own permissions CA to validate remote permissions. So, all permissions CA
Certificates must be same for all participants.
| The signed document should use S/MIME version 3.2 format as defined in IETF RFC 5761 using
SignedData Content Type (section 2.4.2 of IETF RFC 5761) formatted as multipart/signed (section
3.4.3 of IETF RFC 5761). This corresponds to the mime-type application/pkcs7-signature.
Additionally the signer certificate should be be included within the signature.
===================
Governance Document
===================
Governance document defines the security behavior of domains and topics. It is an XML document and
its format is specified in OMG DDS Security Version 1.1 Section 9.4.1.2.3
The attributes that specified in Governance document must match with the remote one for
establishing communication.
Protection Kinds
================
The domain governance document provides a means for the application to configure the kinds of
cryptographic transformation applied to the complete RTPS Message, certain RTPS SubMessages, and
the SerializedPayload RTPS submessage element that appears within the Data.
.. image:: ./_static/pictures/rtps_message_structure.png
:width: 300
The configuration allows specification of five protection levels: NONE, SIGN, ENCRYPT,
SIGN_WITH_ORIGIN_AUTHENTICATION and ENCRYPT_WITH_ORIGIN_AUTHENTICATION.
**NONE**
indicates no cryptographic transformation is applied.
**SIGN**
indicates the cryptographic transformation shall be purely a message authentication code (MAC),
that is, no encryption is performed.
**ENCRYPT**
indicates the cryptographic transformation shall be an encryption followed by a message
authentication code (MAC) computed on the ciphertext, also known as Encrypt-then-MAC.
**SIGN_WITH_ORIGIN_AUTHENTICATION**
indicates the cryptographic transformation shall be purely a set of message authentication codes
(MAC), that is, no encryption is performed. This cryptographic transformation shall create a
first “common authenticationcode” similar to the case where Protection Kind is SIGN. In addition
the cryptographic transformation shall create additional authentication codes, each produced with
a different secret key. The additional MACs prove to the receiver that the sender originated the
message, preventing other receivers from impersonating the sender.
**ENCRYPT_WITH_ORIGIN_AUTHENTICATION**
indicates the cryptographic transformation shall be an encryption followed by a message
authentication code (MAC) computed on the ciphertext, followed by additional authentication
codes, Each of the additional authentication codes shall use a different secret key. The
encryption and first (common) authentication code is similar to ones produced when the Protection
Kind is ENCRYPT. The additional authentication codes are similar to the ones produced when the
Protection Kind is SIGN_WITH_ORIGIN_AUTHENTICATION.
Participant attributes
======================
**Allow Unauthenticated Participants**
This is used for allowing communication with non-secure participants. If this option is enabled,
secure participant can communicate with non-secure participant by only non-protected topics.
**Enable Join Access Control**
If this option is enabled, remote participant permissions are checked if its subject name is
allowed to create a topic anyhow.
**Discovery Protection Kind**
Protection attribute for discovery communication when it is enabled for topic. Please see the
DDS Security specification document for available options.
**Liveliness Protection Kind**
Protection attribute for liveliness communication when it is enabled for topic. Please see the
DDS Security specification document for available options.
**RTPS Protection Kind**
Protection attribute for all messages on the wire. Please see the DDS Security specification
document for available options. If encryption is selected for RTPS, there is no need to encrypt
submessages (metadata_protection_kind) and payloads (data_protection_kind) which are defined in
topic settings.
Topic Attributes
================
**Enable Discovery protection:**
If enabled, discovery is protected according to Discovery Protection Kind attribute of
corresponding participant.
**Enable Liveliness protection:**
If enabled, liveliness is protected according to Liveliness Protection Kind attribute of
corresponding participant.
**Enable Read Access Control:**
If enabled, the permissions document is checked if the participant is allowed to create
a datareader for the related topic.
**Enable Write Access Control:**
If enabled, the permissions document is checked if the participant is allowed to create
a datawriter for the related topic.
**Metadata protection Kind:**
Protection attribute for submessages.
**Data protection Kind:**
Protection attribute for data payload.
There are different settings for different domain ranges. The domain rules are evaluated in the
same order as they appear in the document. A rule only applies to a particular DomainParticipant
if the domain Section matches the DDS domain_id to
which the DomainParticipant belongs. If multiple rules match, the first rule that matches is the
only one that applies.
The topic access rules are evaluated in the same order as they appear within the
<topic_access_rules> Section. If multiple rules match the first rule that matches is the only one
that applies.
fnmatch pattern matching can be used for topic expressions including the following patterns
.. _`fnmatch pattern matching`:
+----------+----------------------------------+
|Pattern |Meaning |
+==========+==================================+
| \* | matches everything |
+----------+----------------------------------+
| \? | matches any single character |
+----------+----------------------------------+
| [seq] | matches any character in seq |
+----------+----------------------------------+
| [!seq] | matches any character not in seq |
+----------+----------------------------------+
====================
Permissions Document
====================
The permissions document is an XML document containing the permissions of the domain participant
and binding them to the subject name of the DomainParticipant as defined in the identity
certificate. Its format is specified in OMG DDS Security Version 1.1 Section 9.4.1.3.
Validity period
===============
It is checked before creating participant; expired permissions document results with DDSI shutdown.
Validity period is also checked during handshake with remote participant; expired remote
permissions document prevents communications to be established.
Subject Name
============
The subject name must match with Identity Certificate subject. It is checked during create
participant and during handshake with remote participant. Use the following openssl command to get
subject name from identity certificate:
``openssl x509 -noout -subject -nameopt RFC2253 -in <identity_certificate_file.crt>``
Rules
=====
DomainParticipant permissions are defined by set of rules.
The rules are applied in the same order that appear in the document. If the criteria for the rule
matches the domain_id join and/or publish or subscribe operation that is being attempted, then the
allow or deny decision is applied. If the criteria for a rule does not match the operation being
attempted, the evaluation shall proceed to the next rule. If all rules have been examined without
a match, then the decision specified by the “default” rule is applied. The default rule, if
present, must appear after all allow and deny rules. If the default rule is not present, the
implied default decision is DENY. The matching criteria for each rule specify the domain_id,
topics (published and subscribed), the partitions (published and subscribed), and the data-tags
associated with the DataWriter and DataReader.
For the grant to match there shall be a match of the topics, partitions, and data-tags criteria.
This is interpreted as an AND of each of the criteria. For a specific criterion to match
(e.g., <topics>) it is enough that one of the topic expressions listed matches (i.e., an OR of
the expressions with the <topics> section).
`fnmatch pattern matching`_ can be used for topic expressions and partition expressions.
Interactions with DDS Security
******************************
DDS Security provides the responses through CycloneDDS error and info log. Users can get
messages for:
- Configuration errors such as plugin library files, certificate files, governance and permissions
files that can not be found on filesystem.
- Permission errors such as denied permission for creating writer of a topic.
- Attribute mismatch errors such as mismatches of security attributes between participants, topics,
readers and writers.
- Integrity errors such as Permissions file-Permissions CA and Identity Cert-Identity CA integrity.
Local subscription, publication and topic permission errors are written to error log.
Remote participation, subscription and publication permission errors are written to info log as
warning message.
Data Communication And Handshake Process
*******************************************
Authentication handshake between participants starts after participant discovery.
If a reader and a writer created during that period, their match will be delayed until after the
handshake succeeds.
This means, during the handshake process, volatile data will be lost, just like there is no reader.
After publication match, the encryption / decryption keys are exchanged between reader and writer.
Best-effort data that are sent during this exchange will be lost, however reliable data will be
resent.
DDS Secure Discovery
******************************
Just like normal operation, DDSI will discover local and remote participants, topics, readers and
writers.
However, when DDS Security is enabled, it is more complex and will take a longer time (especially
due to the handshaking that has to happen).
With every new node in the system, the discovery takes exponentially longer. This can become a
problem if the system contains a number of slow platforms or is large.
The Security discovery performance can be increased quite a bit by using the DDSI
Internal/SquashParticipants configuration.
Proprietary builtin endpoints
******************************
| The DDS standard contains some builtin endpoints. A few are added by the DDS Security
specification. The behaviour of all these builtin endpoints are specified (and thus are be
handled by the plugins that implement the DDS Security specification), meaning that they
don't have to be present in the Governance or Permissions documents and the users don't
have to be bothered with them.
|
| A few of these builtin endpoints slave according to the <discovery_protection_kind> within
the Governance document. In short, related submessages are protected according to the value
of <discovery_protection_kind>. This protects meta information that is send during the
discovery phase.
*******************
DataTag Permissions
*******************
| Data Tags provide an extra (optional) level of identification. This can mean f.i. that
a certain reader is not allowed to read data from writer A but it is allowed to read from
writer B (all the same topic).
|
| This optional feature is not yet supported.
***************************
External Plugin Development
***************************
DDS Security consists of three plugins (authentication, cryptography and access control).
CycloneDDS comes with built-in security plugins that comply with OMG DDS Security specification.
The plugins are loaded in the run-time. However, you can also implement your own custom plugin by
implementing the given API according to OMG DDS Security specification.
You can implement all of the plugins or just one of them.
| The followings are the key points for implementing you own plugin:
Interface
*********
Implement all plugin specific functions with exactly same prototype. Plugin specific function
interfaces are in dds_security_api_access_control.h, dds_security_api_authentication.h and
dds_security_api_cryptography.h header files accordingly.
Init and Finalize
*****************
| A plugin should have an init and a finalize functions. plugin_init and plugin_finalize
interfaces are given in dds_security_api.h header file and function should be same as in
configuration file.
| Init function is called once, just after the plugin is loaded. Finalize function is
called once, just before the plugin is unloaded.
Inter Plugin Communication
**************************
| There is a shared object (*DDS_Security_SharedSecretHandle*) within authentication and
cryptography plugins. If you want to implement only one of them and use the builtin for the
other one, you have to get or provide the shared object properly.
| *DDS_Security_SharedSecretHandle* is the integer representation of
*DDS_Security_SharedSecretHandleImpl* struct object. Cryptography plugin gets the
*DDS_Security_SharedSecretHandle* from authentication plugin and casts to
*DDS_Security_SharedSecretHandleImpl* struct. Then all needed information can be retieved
through *DDS_Security_SharedSecretHandleImpl* struct:
::
typedef struct DDS_Security_SharedSecretHandleImpl {
DDS_Security_octet* shared_secret;
DDS_Security_long shared_secret_size;
DDS_Security_octet challenge1[DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE];
DDS_Security_octet challenge2[DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE];
} DDS_Security_SharedSecretHandleImpl;
Error Codes
***********
| Most of the plugin functions have parameter for reporting exception. The following exception
codes should be used in the reported exception data according to the situation.
dds_security_api_err.h header file contains the code and message constants.
+-------+----------------------------------------------------------------+
| Code | Message |
+=======+================================================================+
| 0 | (OK) |
+-------+----------------------------------------------------------------+
| 100 | Can not generate random data |
+-------+----------------------------------------------------------------+
| 110 | Identity empty |
+-------+----------------------------------------------------------------+
| 111 | Participant Crypto Handle empty |
+-------+----------------------------------------------------------------+
| 112 | Permission Handle empty |
+-------+----------------------------------------------------------------+
| 113 | Invalid Crypto Handle |
+-------+----------------------------------------------------------------+
| 114 | Invalid argument |
+-------+----------------------------------------------------------------+
| 115 | Invalid Crypto token |
+-------+----------------------------------------------------------------+
| 116 | Invalid parameter |
+-------+----------------------------------------------------------------+
| 117 | File could not be found, opened or is empty, path: %s |
+-------+----------------------------------------------------------------+
| 118 | Unknown or unexpected transformation kind |
+-------+----------------------------------------------------------------+
| 119 | Message cannot be authenticated, incorrect signature |
+-------+----------------------------------------------------------------+
| 120 | Can not open trusted CA directory |
+-------+----------------------------------------------------------------+
| 121 | Identity CA is not trusted |
+-------+----------------------------------------------------------------+
| 122 | Certificate start date is in the future |
+-------+----------------------------------------------------------------+
| 123 | Certificate expired |
+-------+----------------------------------------------------------------+
| 125 | Certificate authentication algorithm unknown |
+-------+----------------------------------------------------------------+
| 126 | Failed to allocate internal structure |
+-------+----------------------------------------------------------------+
| 127 | Failed to parse PKCS7 SMIME document |
+-------+----------------------------------------------------------------+
| 128 | Property is missing: (%s) |
+-------+----------------------------------------------------------------+
| 129 | Permissions document is invalid |
+-------+----------------------------------------------------------------+
| 130 | Governance document is invalid |
+-------+----------------------------------------------------------------+
| 131 | Operation is not permitted in this state |
+-------+----------------------------------------------------------------+
| 132 | Remote permissions document is not available |
+-------+----------------------------------------------------------------+
| 133 | Certificate is invalid |
+-------+----------------------------------------------------------------+
| 134 | Certificate type is not supported |
+-------+----------------------------------------------------------------+
| 135 | Governance property is required |
+-------+----------------------------------------------------------------+
| 136 | Permissions CA property is required |
+-------+----------------------------------------------------------------+
| 137 | Can not parse governance file |
+-------+----------------------------------------------------------------+
| 138 | Can not parse permissions file |
+-------+----------------------------------------------------------------+
| 139 | Could not find permissions for topic |
+-------+----------------------------------------------------------------+
| 140 | Could not find domain %d in permissions |
+-------+----------------------------------------------------------------+
| 141 | Could not find domain %d in governance |
+-------+----------------------------------------------------------------+
| 142 | Could not find %s topic attributes for domain(%d) in governance|
+-------+----------------------------------------------------------------+
| 143 | PluginClass in remote token is incompatible |
+-------+----------------------------------------------------------------+
| 144 | MajorVersion in remote token is incompatible |
+-------+----------------------------------------------------------------+
| 145 | Access denied by access control |
+-------+----------------------------------------------------------------+
| 146 | Subject name is invalid |
+-------+----------------------------------------------------------------+
| 147 | Permissions validity period expired for %s |
+-------+----------------------------------------------------------------+
| 148 | Permissions validity period has not started yet for %s |
+-------+----------------------------------------------------------------+
| 149 | Could not find valid grant in permissions |
+-------+----------------------------------------------------------------+
| 150 | Permissions of subject (%s) outside validity date: %s - %s |
+-------+----------------------------------------------------------------+
| 151 | Unsupported URI type: %s |
+-------+----------------------------------------------------------------+
.. EoF