4.15. Security SDK¶
4.15.1. Introduction¶
RTI Security Plugins introduce a robust set of security capabilities, including authentication, encryption, access control and logging. Secure multicast support enables efficient and scalable distribution of data to many subscribers. Performance is also optimized by fine-grained control over the level of security applied to each data flow, such as whether encryption or just data integrity is required.
The RTI Connext DDS Micro Security SDK includes a set of builtin plugins that implement the Service Plugin Interface defined by the DDS Security specification.
RTI Security Plugins is a separate package, available from the RTI Support Portal, https://support.rti.com/.
It is also possible to implement new custom plugins by using the Security Plugins SDK bundle (for more information, please contact support@rti.com). See the RTI Security Plugins Release Notes and RTI Security Plugins Getting Started Guide on the RTI Documentation page.
4.15.2. Installation¶
Please refer to the main Installation section for how to install the RTI Connext DDS Micro Security SDK.
4.15.3. Examples¶
For descriptions and examples of the security configuration in this release,
please consult the HelloWorld_dpde_secure
examples under the
example/[unix, windows]/[C, CPP]
directory. RTI Connext DDS Micro Security SDK supports
both the C and C++ programming languages.
To use the RTI Connext DDS Micro Security SDK, you will need to create private keys, identity certificates, governance and permission files, as well as signed versions for use in secure authenticated, authorized, and/or encrypted communications.
4.15.4. Enabling RTI Security Plugins¶
To enable the RTI Security Plugins, the name of a “plugin suite” (i.e. the collection of security plugins defined by DDS Security) must be specified in a DomainParticipant’s QoS. Plugin factories for this suite must also be registered with the RT_Registry before the DomainParticipant is created.
When using RTI Connext DDS Micro’s C API, this can be achieved with the following code:
RTI_BOOL result = RTI_FALSE;
struct DDS_DomainParticipantQos dp_qos = DDS_DomainParticipantQos_INITIALIZER;
struct SECCORE_SecurePluginFactoryProperty sec_plugin_prop = SECCORE_SecurePluginFactoryProperty_INITIALIZER;
DDS_DomainParticipantFactory *factory = DDS_DomainParticipantFactory_get_instance();
RT_Registry_T *registry = DDS_DomainParticipantFactory_get_registry(factory);
/* Register factories for built-in security plugins, using default
* properties and default name */
if (!SECCORE_SecurePluginFactory_register(
registry,SECCORE_DEFAULT_SUITE_NAME,&sec_plugin_prop))
{
printf("failed to register security plugins\n");
goto done;
}
/* In order to enable security, the name used to register the suite of
* plugins must be set in DomainParticipantQos */
if (!RT_ComponentFactoryId_set_name(
&dp_qos->trust.suite, SECCORE_DEFAULT_SUITE_NAME))
{
printf("failed to set component id\n");
goto done;
}
result = RTI_TRUE;
done:
return result;
For users of RTI Connext DDS Micro’s C++ API, the suite can be registered using the following code:
RTI_BOOL result = RTI_FALSE;
DDS_DomainParticipantQos dp_qos;
SECCORE_SecurePluginFactoryProperty sec_plugin_prop;
DDSDomainParticipantFactory *factory = DDSDomainParticipantFactory::get_instance();
RTRegistry_T *registry = factory->get_registry();
/* Register factories for built-in security plugins, using default
* properties and default name */
if (!SECCORE_SecurePluginFactory::register_suite(
registry,SECCORE_DEFAULT_SUITE_NAME,sec_plugin_prop))
{
printf("failed to register security plugins\n");
goto done;
}
/* In order to enable security, the name used to register the suite of
* plugins must be set in DomainParticipantQos */
if (!dp_qos.trust.suite.set_name(SECCORE_DEFAULT_SUITE_NAME))
{
printf("failed to set component id\n");
goto done;
}
result = RTI_TRUE;
done:
return result;
Additional properties can be controlled using (key,value) pairs in a DomainParticipant’s DDS_PropertyQosPolicy.
The configuration keys (and their corresponding valid values) supported by each security plugin are listed in the tables below:
- Table 4.1, DDS Security Properties for Configuring Authentication
- Table 4.2, DDS Security Properties for Configuring Access Control
- Table 4.3, RTI Properties for Configuring Cryptography
- Table 4.4, RTI Properties for Configuring Logging
In RTI Connext DDS Micro, you must set the security-related participant properties before you
create a participant. You cannot create a participant without security and
then call DomainParticipant::set_qos()
with security properties, even if the
participant has not yet been enabled.
Property Name | Property Value Description |
---|---|
DDS_SECURITY_IDENTITY_CA_PROPERTY | Required. The Identity Certificate Authority for signing authentication certificate files. See Section 4.15.4.1. |
DDS_SECURITY_PRIVATE_KEY_PROPERTY | Required. The private key associated with the first certificate that appears in the identity_certificate. See Section 4.15.4.2. |
DDS_SECURITY_IDENTITY_CERTIFICATE_PROPERTY | Required. An Identity Certificate, required for secure communication. See Section 4.15.4.3. |
DDS_SECURITY_PASSWORD_PROPERTY | Only required if private_key is encrypted. The password used to decrypt the private_key. See Section 4.15.4.4. |
RTI_SECURITY_SHARED_SECRET_ALGORITHM_PROPERTY | Optional. The algorithm used to establish a shared secret during authentication. See Section 4.15.4.5. |
RTI_SECURITY_CRL_FILE_PROPERTY | Optional. The Certificate Revocation List (CRL) that keeps track of untrusted X.509 certificates. See Section 4.15.4.6. |
Property Name | Property Value Description |
---|---|
DDS_SECURITY_PERMISSIONS_CA_PROPERTY | Required. Permissions Certificate Authority for signing access control governance and permissions XML files, and verifying the signatures of those files. See Section 4.15.4.7. |
DDS_SECURITY_GOVERNANCE_PROPERTY | Required. Signed document that specifies the level of security required per domain and per topic. See Section 4.15.4.8. |
Property Name | Property Value Description |
---|---|
RTI_SECURITY_ENCRYPTION_ALGORITHM_PROPERTY | Optional. The algorithm used for encrypting and decrypting data
and metadata. The options are In the Domain Governance document, a “protection kind” set to ENCRYPT will use GCM, and a “protection kind” set to SIGN will use the GMAC variant of this algorithm. Default: |
RTI_SECURITY_MAX_RECEIVER_SPECIFIC_MACS_PROPERTY | Optional. The maximum number of receiver-specific Message Authentication Codes (MACs) that are appended to an encoded result. For example, if this value is 32 and the Participant is configured to protect both RTPS messages and submessages with origin authentication, there could be 32 receiver-specific MACs in the result of encode_datawriter_submessage, and there could be another 32 receiver-specific MACs in the result of encode_rtps_message. If there are more than 32 receivers, the receivers will be assigned one of the 32 possible MACs in a round-robin fashion. Note that in the case of encode_datawriter_submessage, all the readers belonging to the same participant will always be assigned the same receiver-specific MAC. Setting this value to 0 will completely disable receiver-specific MACs. Default: 0. Range: [0, 3275], excluding 1 |
RTI_SECURITY_MAX_BLOCKS_PER_SESSION_PROPERTY | Optional. The number of message blocks that can be encrypted with the same key material. Whenever the number of blocks exceeds this value, new key material is computed. The block size depends on the encryption algorithm. You can specify this value in decimal, octal, or hexadecimal. This value is an unsigned 64-bit integer. Default: 0xffffffffffffffff |
Property Name | Property Value Description |
---|---|
DDS_PARTICIPANT_TRUST_PLUGINS_LOGGING_DISTRIBUTE_PROPERTY_NAME | Optional. This boolean value controls whether security-related log messages should be distributed over a DDS DataWriter. If true, then the Logging Plugin will create a Publisher and DataWriter within the same DomainParticipant that is setting this property. There is no option to use a separate DomainParticipant or to share a DataWriter among multiple DomainParticipants. To subscribe to the log messages, run rtiddsgen on
Default: FALSE |
DDS_PARTICIPANT_TRUST_PLUGINS_LOGGING_LOG_LEVEL_PROPERTY_NAME | Optional. The logging verbosity level. All log messages at and below the log_level setting will be logged. Possible values:
|
DDS_PARTICIPANT_TRUST_PLUGINS_LOGGING_LOG_FILE_PROPERTY_NAME | Optional. The file that log messages are printed to. Default: NULL |
DDS_TRUST_PLUGINS_LOGGING_MAX_REMOTE_READERS_PROPERTY_NAME | Optional. Maximum remote readers the logging writer can write to. Default: 16 |
DDS_TRUST_PLUGINS_LOGGING_MAX_ROUTES_PER_READER_PROPERTY_NAME | Optional. Logging writer resource-limit, which limits the number of routes that can be saved per Reader. Default: 4 |
DDS_TRUST_PLUGINS_LOGGING_WRITER_DEPTH_PROPERTY_NAME | Optional. History depth (in samples) of the logging DataWriter. Integer. Default: 64 |
4.15.4.1. DDS_SECURITY_IDENTITY_CA_PROPERTY¶
DDS_SECURITY_IDENTITY_CA_PROPERTY is a required property. It appears in Table 4.1, DDS Security Properties for Configuring Authentication.
This property’s value specifies an Identity Certificate Authority document that will be used for signing authentication certificate files. Participants that want to securely communicate with each other must use the same Identity Certificate Authority.
You will use OpenSSL and an openssl.cnf
file to create a file in PEM format
named cacert*.pem
.
An example openssl.cnf
file is here:
rti_workspace/version/examples/dds_security/cert
.
You will need to modify this file to match your certificate
folder structure and Identity Certificate Authority desired configuration.
Example OpenSSL commands are shown below.
RSA:
% openssl genrsa -out cakey.pem 2048
% openssl req -new -key cakey.pem -out ca.csr -config openssl.cnf
% openssl x509 -req -days 3650 -in ca.csr -signkey cakey.pem \
-out cacert.pem
DSA:
% openssl dsaparam 2048 > dsaparam
% openssl gendsa -out cakeydsa.pem dsaparam
% openssl req -new -key cakeydsa.pem -out dsaca.csr \
-config openssldsa.cnf
% openssl x509 -req -days 3650 -in dsaca.csr -signkey cakeydsa.pem \
-out cacertdsa.pem
ECDSA:
% openssl ecparam -name prime256v1 > ecdsaparam
% openssl req -nodes -x509 -days 3650 -newkey ec:ecdsaparam \
-keyout cakeyECdsa.pem -out cacertECdsa.pem -config opensslECdsa.cnf
Note
When running the above commands for ECDSA, you may run into these OpenSSL warnings:
WARNING: can't open config file: [default openssl
built-inpath]/openssl.cnf
unable to write 'random state'
To resolve the first warning, set the environmental variable OPENSSL_CONF
with the path to the openssl.cnf
file you are using.
To resolve the second warning, set the environmental variable RANDFILE with
the path to a writable file.
You may specify the value as either a file name or the document contents. The document should be in PEM format.
If setting the property value to a file name: The property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of thecacert*.pem
file that appears after the-out
parameter in the above commands.If setting the property value to the contents of the document: The property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:"data:,-----BEGIN CERTIFICATE-----\nabcdef\n-----END CERTIFICATE-----"
Note that the two
\n
characters are required.
4.15.4.2. DDS_SECURITY_PRIVATE_KEY_PROPERTY¶
DDS_SECURITY_PRIVATE_KEY_PROPERTY is a required property. It appears in Table 4.1, DDS Security Properties for Configuring Authentication.
Its value is a private key associated with the first certificate that appears in the identity_certificate. The default value is NULL.
After generating the ca_file, cacert*.pem
(described in
Section 4.15.4.1), use OpenSSL
to generate a peer1key*.pem
file using commands such as the following.
RSA:
% openssl genrsa -out peer1key.pem 2048
DSA:
% openssl dsaparam 2048 > dsaparam % openssl gendsa -out peer1keydsa.pem dsaparam
ECDSA:
% openssl ecparam -name prime256v1 > ecdsaparam1 % openssl req -nodes -new -newkey ec:ecdsaparam1 -config example1ECdsa.cnf \ -keyout peer1keyECdsa.pem -out peer1reqECdsa.pem
Notice that for ECDSA, OpenSSL also generates
peer1reqECdsa.pem
. That file will be used later to generate the certificate file for DDS_SECURITY_IDENTITY_CERTIFICATE_PROPERTY.
The document should be in PEM format. You may specify either the file name or the document contents.
If setting the property value to a file name: The property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of the filepeer1key*.pem
that appears after the-out
parameters in the above commands.If setting the property value to the contents of the document: The property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:"data:,-----BEGIN PRIVATE KEY-----\nabcdef\n-----END PRIVATE KEY-----"
Note that the two
\n
characters are required.
4.15.4.3. DDS_SECURITY_IDENTITY_CERTIFICATE_PROPERTY¶
DDS_SECURITY_IDENTITY_CERTIFICATE_PROPERTY is a required property. It appears in Table 4.1, DDS Security Properties for Configuring Authentication.
Its value is an Identity Certificate, required for secure communication.
Before generating the certificate file for this property, first generate the ca_file (see Section 4.15.4.1) and the private_key_file (see Section 4.15.4.2).
Next, create a serial file whose contents are 01 and a blank
index.txt
file. The names of these files will depend on the
contents of the openssl*.cnf
file.
Then use OpenSSL to generate the certificate file using commands such as those seen below.
Example .cnf
files are here:
rti_workspace/version/examples/dds_security/cert
.
Note: You will need to modify this file to match your certificate folder structure and Identity Certificate desired configuration:
RSA:
% openssl req -config example1.cnf -new -key peer1key.pem \ -out user.csr % openssl ca -config openssl.cnf -days 365 -in user.csr \ -out peer1.pem
DSA:
% openssl req -config example1dsa.cnf -new -key peer1keydsa.pem \ -out dsauser.csr % openssl ca -config openssldsa.cnf -days 365 \ -in dsauser.csr -out peer1dsa.pem
ECDSA:
Generate
peer1reqECdsa.pem
using the instructions for private_key_file (see Section 4.15.4.2).% openssl ca -batch -create_serial -config opensslECdsa.cnf \ -days 365 -in peer1reqECdsa.pem -out peer1ECdsa.pem
Notes:
openssl((EC)dsa).cnf
must have the same countryName, stateOrProvinceName, and localityName as the example.cnf
files.- Example
.cnf
files for different participants must have different commonNames.
The document should be in PEM format. You may specify either the file name or the document contents.
If setting the property value to a file name: The property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of the filepeer1*.pem
that appears after the-out
parameters in the above commands.If setting the property value to the contents of the document: The property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:"data:,-----BEGIN CERTIFICATE-----\nabcdef\n-----END CERTIFICATE-----"
Note that the two “n” characters are required.
You may put a chain of certificates in the Identity Certificate by concatenating individual certificates and specifying the concatenated result as a single file or string. See Section 8.1, Identity Certificate Chaining, in the Security Plugins Getting Started Guide for 6.0.0 (available here if you have Internet access).
Default: NULL
4.15.4.4. DDS_SECURITY_PASSWORD_PROPERTY¶
This property is only required if private_key is encrypted.
Its value specifies the password used to decrypt the private_key (see Section 4.15.4.2).
This property appears in Table 4.1, DDS Security Properties for Configuring Authentication.
The value is interpreted as the Base64 encoding of the symmetric key that will be used to decrypt the private_key.
For example, suppose the private_key was encrypted using this command:
% openssl req -new -newkey ec:ecdsaparam2 \
-config example2ECdsa.cnf -keyout peer2keyECdsa.pem \
-passout pass:MyPassword -out peer2reqECdsa.pem
Then you can obtain the Base64 encoding of MyPassword with commands such as:
% echo MyPassword > foo
% openssl base64 -e -in foo
TXlQYXNzd29yZAo=
For the above example, the value of the password property should be “TXlQYXNzd29yZAo=”. If the private_key was not encrypted, the password must be NULL.
Default: NULL
4.15.4.6. RTI_SECURITY_CRL_FILE_PROPERTY¶
This is an optional property.
This Certificate Revocation List (CRL) keeps track of untrusted X.509 certificates.
This property appears in Table 4.1, DDS Security Properties for Configuring Authentication.
Use OpenSSL to generate this file using commands such as those seen below.
An example opensslECdsa.cnf
file is here:
rti_workspace/version/examples/dds_security/cert
.
You will need to modify this file to match your certificate folder structure and Certificate Revocation List desired configuration.
% touch indexECdsa.txt
% echo 01 > crlnumberECdsa
% openssl ca -config opensslECdsa.cnf -batch \
-revoke peerRevokedECdsa.pem
% openssl ca -config opensslECdsa.cnf -batch -gencrl \
-out democaECdsa.crl
In this example:
crlnumberECdsa
is the database of revoked certificates. This file should match thecrlnumber
value inopensslECdsa.cnf
.peerRevokedECdsa.pem
is the certificate_file of a revoked DomainParticipant.democaECdsa.crl
should be the value of the crl_file property.- If crl_file is set to NULL, no CRL is checked and all valid certificates will be considered trusted.
- If crl_file is set to an invalid CRL file, DomainParticipant creation will fail.
- If crl_file is set to a valid CRL file, the CRL will be checked upon DomainParticipant creation and upon discovering other DomainParticipants. Creating a DomainParticipant with a revoked certificate will fail. If ParticipantA uses a certificate that does not appear in ParticipantA’s CRL, but does appear in ParticipantB’s CRL, then ParticipantB will reject and ignore ParticipantA. Changes in the CRL will not be enforced until the DomainParticipant using the CRL is deleted and recreated.
Default: NULL
4.15.4.7. DDS_SECURITY_PERMISSIONS_CA_PROPERTY¶
DDS_SECURITY_PERMISSIONS_CA_PROPERTY is a required property. It appears in Table 4.2, DDS Security Properties for Configuring Access Control.
This Permissions Certificate Authority is used for signing access control governance and permissions XML files, and verifying the signatures of those files.
The Permissions Certificate Authority file may or may not be the same as the Identity Certificate Authority file, but both files are generated in the same way. See Section 4.15.4.1 for the steps to generate this file.
Two participants that want to securely communicate with each other must use the same Permissions Certificate Authority.
The document should be in PEM format. You may specify either the file name or the document contents.
If specifying the file name, the property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of the file.If specifying the contents of the document, the property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:``data:,-----BEGIN CERTIFICATE-----\nabcdef\n-----END CERTIFICATE-----``
Note that the two “n” characters are required.
Default: NULL
4.15.4.8. DDS_SECURITY_GOVERNANCE_PROPERTY¶
DDS_SECURITY_GOVERNANCE_PROPERTY is a required property. It appears in Table 4.2, DDS Security Properties for Configuring Access Control.
The Governance property configures the signed document that specifies the level of security required per domain and per topic. To sign an XML document with a Permissions Certificate Authority, run the following OpenSSL command (enter this all on one line):
openssl smime -sign -in Governance.xml -text
-out signed_Governance.p7s -signer cacert.pem
-inkey cakey.pem
Then set this property’s value to signed_Governance.p7s
.
You may specify either the file name or the document contents.
If specifying the file name, the property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of the file.If specifying the contents of the document, the property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:"data:,MIME-Version: 1.0\nContent-Type:...boundary=\”---7236\”\n\n"
Note that for signed XML files, all whitespace characters
(‘ ‘, ‘r’, ‘n’) are significant, and all quotes must be escaped
with a backslash. The safest way to get the correct property value is to
call the fread()
function on the file and use the resulting buffer
as the property value.
Default: NULL
4.15.4.9. DDS_SECURITY_PERMISSIONS_PROPERTY¶
DDS_SECURITY_PERMISSIONS_PROPERTY is a required property. It appears in Table 4.2, DDS Security Properties for Configuring Access Control.
This property configures the signed document that specifies the access control permissions per domain and per topic.
The <subject_name> element identifies the DomainParticipant to which the permissions apply. Each subject name can only appear in a single <permissions> section within the XML Permissions document. The contents of the <subject_name> element should be the X.509 subject name for the DomainParticipant, as given in the “Subject” field of its Identity Certificate.
A <permissions> section with a subject name that does not match the subject name given in the corresponding Identity Certificate will be ignored.
To sign an XML document with a Permissions Certificate Authority, run the following OpenSSL command (enter this all on one line):
openssl smime -sign -in PermissionsA.xml -text
-out signed_PermissionsA.p7s -signer cacert.pem
-inkey cakey.pem
Then set this property value to signed_PermissionsA.p7s
.
The signed permissions document only supports validity dates between 1970010100 and 2038011903. Any dates before 1970010100 will result in an error, and any dates after 2038011903 will be treated as 2038011903. Currently, Connext DDS will not work if the system time is after January 19th, 2038.
You may specify either the file name or the document contents.
If specifying the file name, the property value must have the prefix
file:
(no space after the colon), followed by the fully qualified path and name of the file.If specifying the contents of the document, the property value must have the prefix
data:,
(no space after the comma), followed by the contents inside the document. For example:"data:,MIME-Version: 1.0\nContent-Type:...boundary=\”---7236\”\n\n"
Note that for signed XML files, all whitespace characters
(‘ ‘, ‘r’, ‘n’) are significant, and all quotes must be escaped with a
backslash. The safest way to get the correct property value is to call the
fread()
function on the file and use the resulting buffer as the property value.
Default: NULL