Distributing Data Securely with OpenDDS
By Adam Mitz, OCI OpenDDS Product Lead and Principal Software Engineer
The Object Management Group's (OMG) middleware standard Data Distribution Service (DDS) for real-time systems defines a framework for applications to share data using a publish/subscribe paradigm, which helps shield them from the inherent complexities of distributed computing.
Unlike low-level transport protocols, DDS implementations like OpenDDS are aware of the schema and semantics of the data. The Industrial Internet Consortium Connectivity Framework defines a stack model consisting of multiple layers.
The DDS API sits at the Framework Layer, providing syntactic interoperability among heterogeneous systems.
OpenDDS also includes an interoperable standards-based Transport Layer providing technical interoperability: communication with other DDS peers (be they OpenDDS or another DDS implementation) using the RTPS protocol.
Many alternatives to DDS provide only the Transport Layer, requiring each application to provide its own solutions to the concerns of the Framework Layer.
DDS applications share data across a network. Without the features defined by the DDS Security specification, this data is sent in the clear. This limits non-secure DDS to closed networks or to networks that provide security outside the application space, such as VPNs.
To broaden the applicability of DDS, the OMG developed the DDS Security specification.
With DDS Security, now available in OpenDDS, applications take advantage of configurable data protection for both infrastructure- and application-generated messages. Data can be protected by signing, (i.e., data is sent in the clear, but with a signature to prevent modification), or to accommodate more stringent data protection requirements, data can be encrypted.
This article makes use of a few terms that are defined by the DDS specification.
A Topic is a unique name that, along with a data type, logically links the publishing and subscribing parts of a distributed application.
For example, a Topic named "Sensor" could be used by applications that publish sensor readings, as well as those that subscribe in order to display sensor data on a user interface.
A data sample is an item published on a Topic. The type of a data sample is the data type associated with its Topic.
A DataWriter writes data samples to a single Topic while a DataReader reads data samples from a single Topic.
A Publisher is a collection of one or more DataWriters, and a Subscriber is a collection of one or more DataReaders.
Publishers and Subscribers are created by a DomainParticipant, which is the top-level object that each application creates to access a DDS Domain.
A Domain is represented as an integer and logically partitions DDS traffic – no DDS communications will cross from one domain to another.
How does DDS Security fit in?
The DDS Security specification uses industry-standard cryptographic algorithms and techniques to protect DDS applications from three specific threats:
- Unauthorized publication/subscription
- Unauthorized access to data
Architecturally this is similar to HTTPS, however DDS's RTPS protocol with Security runs over UDP and supports multicast (including encryption).
By analogy, DDS Security is to plain DDS as HTTPS is to HTTP.
Security Functional Areas
The DDS Security specification defines plugin APIs for Authentication, Access Control, and Cryptographic operations. The specification also defines built-in implementations of these plugins.
OpenDDS includes these implementations, but developers could also write their own alternative implementations. This article assumes an application is using the built-in plugins.
Authenticating Peer Applications
DDS Authentication uses the Public-Key Infrastructure common to many internet protocols.
Application identities are determined by Certificates signed by a common Certificate Authority. The identity principal is the Domain Participant. Mutual authentication of peers and key agreement is achieved using industry-standard Digital Signature and Diffie-Hellman algorithms.
Access Control by Topic
Configuration files, which must be signed by the Certificate Authority to prevent tampering, determine which applications have access (read and/or write) to which topics. The configuration files use two different XML schemas, each defined by the DDS Security specification:
- Governance: security requirements that are common across the entire Domain
- Permissions: different files for each Domain Participant, which are bound to that Participant's certificate
Cryptographic operations provide data protection via Message Authentication and/or Encryption. Each topic may be configured so that its data samples will be encrypted, signed, or sent without protection.
The scope of data protection is also configurable; it can apply to the payload only or it can include the headers added by DDS.
DDS Security uses the Advanced Encryption Standard (AES) in Galois Counter Mode (GCM) with 256-bit keys.
As an example, consider an Industrial Internet of Things (IIoT) application wherein a network of sensors measure valve pressure on pneumatic manifolds. The software embedded in these devices contains the Publishers while the Subscriber is a web-based UI that collects and displays the sensor readings.
Using DDS Security, we can achieve two important security goals:
- Keep operational data confidential
- Prevent an attacker from injecting false readings that appear in the UI
A recorded screencast video of such an application is available from OCI.
DDS Security's Impact on the RTPS Protocol
When configured for DDS Security, all network messages sent and received by OpenDDS use the RTPS protocol over UDP. Each UDP datagram contains a single RTPS Message. Each RTPS Message consists of a fixed header followed by some number of Submessages (often more than one).
There are a few different types of Submessages that are relevant for DDS Security:
- Data submessages are generated by DataWriters and contain a payload which is a binary serialization of the data sample.
- Control submessages are generated by DataWriters or DataReaders.
- Info submessages are part of the RTPS protocol internals and logically belong to the Domain Participant.
The DDS Security specification includes provisions for protecting (encrypting/signing) at three different levels:
- Protecting the payload wraps the data payload inside the Data submessage in its own header/footer pair. If encrypting, the normal payload plaintext is replaced by its ciphertext.
- Protecting the submessage is applied per-DataWriter/DataReader. If this option is enabled on a given DataWriter/DataReader, each submessage (Data or Control) generated by that entity is wrapped in its own header/footer pair. If encrypting, the normal submessage plaintext is replaced by its ciphertext.
- Protecting the message can be configured for the Domain Participant as a whole. This option wraps the message's entire sequences of submessages in a single header/footer pair.
More than one of these protection levels can be active concurrently, which would mean that data that's already encrypted/signed could be encrypted/signed again. This can be desirable in certain use cases but should be avoided in general.
Adding Security to a DDS Application
DDS Security can be applied to existing OpenDDS applications by modifying their configuration and updating some Quality of Service (QoS) settings. Although this article only contains an overview, details of these changes are documented in the OpenDDS Developer's Guide and Using DDS Security in OpenDDS documents.
- Configure OpenDDS to use RTPS Discovery and the RTPS_UDP transport (see the OpenDDS Developer's Guide for details)
- Enable Security in the overall OpenDDS settings (.ini file or API call)
- Create configuration files (see below)
- Update source code that calls
create_participantto use new QoS settings (see below)
Files Used by DDS Security
The following files are needed when using DDS Security.
Example file names are used below; the actual names are arbitrary.
- Certificate Authority for Identity: can be an existing CA or one created for the application
- Certificate Authority for Permissions: can be the same as identity_ca_cert.pem or distinct
- A distinct CA allows this private key to sign XML configuration files but not issue new Identity Certificates
- Certificate issued by Identity CA that identifies this Domain Participant
- Private Key for the Certificate above
- Governance rules common to all participants in the domain
- XML document signed by the Permissions CA
- Permissions for this particular participant, contains its Subject Name (matches its Certificate)
- XML document signed by the Permissions CA
The files ending in
.pem can be generated by OpenSSL or other compatible tools. They are for the PKI (Certificate Authorities, Certificates, Private Keys) and are not specific to DDS.
The files ending in
.p7s are PKCS#7 signed documents. The input to the signing process is an XML file defined by the DDS Security specification. The OpenSSL command-line tool can be used to sign documents.
Examples of generating certificates and signing configuration files are available in "Using DDS Security in OpenDDS," available on OpenDDS's documentation page.
Source Code Changes
The DDS Security specification introduces a new DomainParticipant QoS policy called
property that allows arbitrary name/value pairs to be passed from the application to the DDS internals when a Domain Participant is created. This QoS policy is used to give OpenDDS the names and locations of the files described above (using the example file names from that section).
The example below is in C++, but the relevant code is similar in the other supported languages.
- DDS::DomainParticipantQos qos;
- // append() is a helper, see example in "Using DDS Security in OpenDDS"
- append(qos.property.value, "dds.sec.auth.identity_ca", "file:identity_ca_cert.pem");
- append(qos.property.value, "dds.sec.access.permissions_ca", "file:permissions_ca_cert.pem");
- append(qos.property.value, "dds.sec.auth.identity_certificate", "file:test_participant_01_cert.pem");
- append(qos.property.value, "dds.sec.auth.private_key", "file:test_participant_01_private_key.pem");
- append(qos.property.value, "dds.sec.access.governance", "file:governance_signed.p7s");
- append(qos.property.value, "dds.sec.access.permissions", "file:permissions_1_signed.p7s");
- DDS::DomainParticipant_var participant = factory->create_participant(DOMAIN_ID, qos, 0);
The overall configuration mechanism is shown in the diagram below.
Governance XML File
A portion of the Governance XML file used by the demo described above is shown here:
discovery_protection_kindsetting allows encrypting or signing discovery messages (those sent by OpenDDS in order to locate other peers on the network)
enable_discovery_protectionsetting turns on/off protected discovery per topic
metadata_protection_kindsetting can enable protection at the submessage level (see DDS Security's Impact on the RTPS Protocol above)
data_protection_kindsetting can enable protection at the payload level
Permissions XML File
A portion of the Permissions XML file used by the demo described above is shown here:
- <grant name="Permission">
- <subject_name>emailAddressemail@example.com, CN=DDS Shapes Demo, OU=CTO Office, O=ACME Inc., L=Sunnyvale, ST=CA, C=US</subject_name>
subject_namemust match the subject of this participant's identity certificate. This binds the identity to the permissions.
allow_rulegrants this participant permission to publish (that is, create a DataWriter for) any topic in domain 23
defaultrule applies to any access control not otherwise matched by a rule in the file
Security Plugins in Action
In the running system with DDS Security, each of the three plugins has its own responsibilities. Together they enforce the security aspects such as authorization, confidentiality, and tamper-resistance.
As an extension of DDS Discovery, Security-enabled peers mutually authenticate using a digital signature algorithm. Each pair of participants completes a 3-way handshake that includes exchanging Certificates and Permissions files.
If authentication succeeds, the Diffie-Hellman key agreement algorithm ensures that each peer has the same "shared secret," which was not sent over the network.
The access control plugin provides details of domain-wide configuration (Governance) to the rest of the DDS system. The plugin also checks that actions undertaken by the local participant (such as creating a DataReader) are allowed by its Permissions.
Crucially, the plugin also enforces permissions of remote participants. If a remote participant sends a message that its Permissions say it should not send, that message is ignored.
The permissions claimed by a peer are validated by checking the XML document's signature.
The cryptographic plugin has three roles:
- Key Generation: based on the configuration in Governance, create keys required for encryption or signing
- Key Exchange: provide keys to the DDS core libraries in a format that can be transferred (securely) to peers
- Data Transformation: change from the plain RTPS protocol format to the security-enhanced messages and back; this includes the actual encrypt/decrypt (AES-GCM) and sign/verify algorithms (AES-GMAC) implemented by the OpenSSL cryptography library.
The way keys are used in DDS Security allows a given DataWriter to encrypt a data sample once and send it to more than one DataReader, which may happen with multicast. This maintains the scalability and real-time nature of DDS even with encryption.
OpenDDS is a completely open-source solution for real-time distributed applications.
OpenDDS's flexible QoS-based configuration and decoupling of publishers and subscribers has proven to meet the requirements of many types of applications. Now with DDS Security, OpenDDS is applicable to even more domains and network deployments, providing protection from unauthorized publication/subscription, tampering/replay, and access to data.
For More Information
Screencasts and webinar recordings are available on the links page.
Software Engineering Tech Trends (SETT) is a regular publication featuring emerging trends in software engineering.