diff --git a/docs/dev/dds_security_effort.md b/docs/dev/dds_security_effort.md new file mode 100644 index 0000000..d554749 --- /dev/null +++ b/docs/dev/dds_security_effort.md @@ -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 + +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 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) + +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) + +The ddsi component needs to be able to load DDS Security plugins at runtime. +These plugins are provided as libraries.
+Loading libraries at runtime is currently not possible in Cyclone DDS. + + +## Hopscotch utility (done)
+ +This hash table is used by the Security plugins.
+Both versions on OpenSplice and Cyclone are equivalent.
+No additional effort is expected. + + +## FSM utility (in progress)
+ +The Finite State Machine utility has been introduced in OpenSplice to support +the handshake of DDS Security.
+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)
+ +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.
+Maybe add some CMake module for both ddsi and the plugins to easily link +against? + + +## De-Serializing messages in DDSI (done)
+ +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) + +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) + +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) + +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.
+- A few files are added which are easy to add to cmake.
+- There's a new dependency on the [DDS Security API](#port-api), which is done. + +Then, of course, there are the tests
+First of all, [Multi Process Testing](#testing) should be available, which now +it is.
+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)
+ +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).
+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.
+However, getting and setting policies are done through getter and setter +functions in ddsc.
+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.
+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
+ +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.
+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
+ +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.
+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.
+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).
+This has to change.
+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.
+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 Security example has to be added. + + +## QosProvider + +The Participant QoS now contains Security related information. This means that +the QosProvider has to be upgraded to support that. + + +## Data Tags (optional) + +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 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.
+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.
+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.
+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?
+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).
+That dds_instance_handle_t can be used to get the right +DDS_Security_PublicationBuiltinTopicDataSecure sample for the related secure +builtin reader [**note1**].
+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.
+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. diff --git a/docs/manual/_static/pictures/dds_security_configuration_overview.png b/docs/manual/_static/pictures/dds_security_configuration_overview.png new file mode 100644 index 0000000..24df753 Binary files /dev/null and b/docs/manual/_static/pictures/dds_security_configuration_overview.png differ diff --git a/docs/manual/_static/pictures/dds_security_overview.png b/docs/manual/_static/pictures/dds_security_overview.png new file mode 100644 index 0000000..9951bf9 Binary files /dev/null and b/docs/manual/_static/pictures/dds_security_overview.png differ diff --git a/docs/manual/_static/pictures/pki_overview.png b/docs/manual/_static/pictures/pki_overview.png new file mode 100644 index 0000000..138493d Binary files /dev/null and b/docs/manual/_static/pictures/pki_overview.png differ diff --git a/docs/manual/_static/pictures/rtps_message_structure.png b/docs/manual/_static/pictures/rtps_message_structure.png new file mode 100644 index 0000000..fb402a4 Binary files /dev/null and b/docs/manual/_static/pictures/rtps_message_structure.png differ diff --git a/docs/manual/security.rst b/docs/manual/security.rst new file mode 100644 index 0000000..b8ae578 --- /dev/null +++ b/docs/manual/security.rst @@ -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 user’s 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 + 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 `` + + +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., ) it is enough that one of the topic expressions listed matches (i.e., an OR of +the expressions with the 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 within + the Governance document. In short, related submessages are protected according to the value + of . 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