7. Hands-On 4: Generating and Revoking Your Own Certificates Using OpenSSL

In this Hands-On, you will take control of your project’s keys and certificates. This way, you will not need to rely on the example artifacts provided with Connext to secure your applications. We will start by generating a self-signed Identity CA, which will issue the Identity Certificates for Alice and Bob. This will require us to set up a minimal security infrastructure first. Then we will generate a new Permissions CA that will sign the Governance Document and all the Permissions Documents. After each certificate generation, we will refer to the modifications needed to make your project load the new artifacts. Finally, we will revoke one Identity Certificate and use a Certificate Revocation List (CRL) to avoid communicating with the revoked DomainParticipant.

We will show examples for ECDSA and RSA as the public-key algorithm to generate the certificates. Note that you can use any public-key algorithm listed in Supported Cryptographic Algorithms in the Security Plugins User’s Manual.

Note

We will use the OpenSSL CLI to perform the security operations in the generation of the security artifacts. Make sure to include in the path your OpenSSL binary directory 3. The installation process is described in the RTI Security Plugins Installation Guide.

Note that the Security Plugins do not depend on OpenSSL to generate these artifacts; you can use the security toolkit of your choice. With that said, we recommend using OpenSSL to make sure that the certificates are in the right format.

7.1. Preliminary Steps

Setting up a security infrastructure requires some preliminary configuration. We will cover a minimal setup here.

  1. If you followed the steps in Hands-On 1: Securing Connext DDS Applications, you should have an OpenSSL configuration file named cert/ecdsa01/ca/ecdsa01RootCa.cnf 1. Make two copies of this file and call them pmiIdentityCa.cnf and pmiPermissionsCa.cnf. To better organize your project, save these copies in a new directory called cert/pmi/ca:

    $ cp cert/ecdsa01/ca/ecdsa01RootCa.cnf cert/pmi/ca/pmiIdentityCa.cnf
    $ cp cert/ecdsa01/ca/ecdsa01RootCa.cnf cert/pmi/ca/pmiPermissionsCa.cnf
    

    Hint

    If you want to use RSA as your public-key algorithm, you may want to copy the homologous example files from the cert/rsa01/ directory.

  2. Modify pmiIdentityCa.cnf to redefine the name variable. Note that this configuration file uses this variable to derive some filenames, such as those used in the next section:

    ...
    # Variables defining this CA
    name = pmiIdentityCa                      # Name
    desc =                                    # Description
    ...
    
1

Read the official documentation for more information on the OpenSSL configuration files.

7.1.1. Initialize the OpenSSL CA Database

When using a CA to perform an operation, OpenSSL relies on special database files to keep track of the issued certificates, serial numbers, revoked certificates, etc. We need to create these database files to be able to use the openssl x509 -req command:

$ mkdir cert/pmi/ca/database
$ touch cert/pmi/ca/database/pmiIdentityCaIndex
$ echo 01 > cert/pmi/ca/database/pmiIdentityCaSerial

7.1.2. Limit the Access of the CA’s Private Key

It is also a good practice to store the CA’s private key in a separate directory with more restrictive access rights, so only you can sign certificates.

$ mkdir cert/pmi/ca/private
$ chmod 700 cert/pmi/ca/private

7.2. Generating a New Identity CA

  1. Modify cert/pmi/ca/pmiIdentityCa.cnf and specify the fields in the req_distinguished_name section. This information will be incorporated into your certificate:

    ...
    [ req_distinguished_name ]
    
    countryName          = US
    stateOrProvinceName  = CA
    localityName         = Santa Clara
    0.organizationName   = Patient Monitoring Innovations
    commonName           = PMI Identity CA
    emailAddress         = identityca@pmi.com
    ...
    
  2. Use the OpenSSL CLI to generate a self-signed certificate using the Identity CA’s configuration. Run the following command from the cert/pmi directory:

    openssl req -nodes -x509 -days 1825 -text -sha256 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout ca/private/pmiIdentityCaKey.pem -out ca/pmiIdentityCaCert.pem -config ca/pmiIdentityCa.cnf
    

    This will produce a new private key, pmiIdentityCaKey.pem in the cert/pmi/ca/private directory, and a new certificate, pmiIdentityCaCert.pem, in the cert/pmi/ca directory. This certificate will be valid for 1825 days (5 years) starting today.

7.2.1. Specifying the New Identity CA Certificate in QoS Profiles

Modify USER_QOS_PROFILES.xml to make your DomainParticipants load the certificate of the new Identity CA:

...
<element>
    <name>dds.sec.auth.identity_ca</name>
    <value>file:./cert/pmi/ca/pmiIdentityCaCert.pem</value>
</element>
...

7.3. Generating Identity Certificates

As explained in Introduction to RTI Security Plugins, Identity Certificates are verified against the Identity CA when authenticating remote DomainParticipants. Therefore, in the simplest scenario, it is the Identity CA that is responsible for issuing Identity Certificates. 2 We will create a certificate signing request (CSR) for Alice. Then we will use the new Identity CA to issue the certificate requested by the CSR.

  1. Add the information you want to include in Alice’s certificate in a file called pmiAlice.cnf. Save this file in a new directory called cert/pmi/identities. You may want to use the following contents as a reference:

    Listing 7.1 Sample contents of pmiAlice.cnf
    prompt              = no
    distinguished_name  = req_distinguished_name
    
    [ req_distinguished_name ]
    countryName          = US
    stateOrProvinceName  = CA
    localityName         = Santa Clara
    organizationName     = Patient Monitoring Innovations
    emailAddress         = alice@pmi.com
    commonName           = Alice
    

    You are free to modify any field except countryName, stateOrProvinceName, and organizationName. These fields must match the ones of the Identity CA; otherwise it will refuse to issue the requested certificate (note that a commonName is also required). These requirements are specified in pmiIdentityCa.cnf, in the policy_match section.

  2. Generate Alice’s key and CSR. Run the following command from the cert/pmi directory:

    openssl req -nodes -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -config identities/pmiAlice.cnf -keyout identities/pmiAliceKey.pem -out identities/pmiAlice.csr
    

    This will produce an RSA private key, pmiAliceKey.pem, and a CSR based on that key, pmiAlice.csr. Since CSRs have all the information and cryptographic material that a CA needs to issue a certificate, Alice’s private key must never be known to anyone but her.

  3. Use the new Identity CA’s certificate and private key to issue Alice’s Identity Certificate. Run the following command from the cert/pmi directory:

    openssl x509 -req -days 730 -text -CAserial ca/database/pmiIdentityCaSerial -CA ca/pmiIdentityCaCert.pem -CAkey ca/private/pmiIdentityCaKey.pem -in identities/pmiAlice.csr -out identities/pmiAliceCert.pem
    

    The Identity CA will issue Alice’s public certificate, pmiAliceCert.pem, which will be valid for 730 days (2 years) starting today.

2

Depending on your use case, the Identity Certificates may be issued by an intermediate CA in your PKI instead. For further information, see Public Key Infrastructure (PKI) in the Security Plugins User’s Manual.

7.3.1. Specifying the New Identity Certificates to Your QoS Profiles

Modify USER_QOS_PROFILES.xml to make your publisher application load the new pair of certificate and private key:

...
<!-- Participant Public Certificate and Private Key -->
<element>
    <name>dds.sec.auth.identity_certificate</name>
    <value>file:./cert/pmi/identities/pmiAliceCert.pem</value>
</element>
<element>
    <name>dds.sec.auth.private_key</name>
    <value>file:./cert/pmi/identities/pmiAliceKey.pem</value>
</element>
...

7.4. Updating Permissions Documents with New Credentials

As explained in Binding the Permissions Document to Your DomainParticipants, grants in a Permissions Document are bound to DomainParticipant identities. We will update Alice’s Permissions Document with the same information we included in Alice’s Identity Certificate.

  1. To meet the format requirements of the Permissions Document, you may want to check your certificate’s information with the following command:

    $ openssl x509 -in cert/pmi/identities/pmiAliceCert.pem -text -noout
    Certificate:
        Data:
            Version: 1 (0x0)
            Serial Number: 1 (0x1)
        Signature Algorithm: ecdsa-with-SHA256
            Issuer: C=US, ST=CA, L=Santa Clara, O=Patient Monitoring Innovations, CN=PMI Identity CA, emailAddress=identityca@pmi.com
            Validity
                Not Before: Feb  7 15:37:09 2021 GMT
                Not After : Feb  7 15:37:09 2023 GMT
            Subject: C=US, ST=CA, O=Patient Monitoring Innovations, CN=Alice, emailAddress=alice@pmi.com
            Subject Public Key Info:
            ...
    
  2. Modify the subject_name in the Permissions Document, xml/pmiPermissionsAlice.xml, to match the certificate’s subject.

  3. You may also want to update the validity tag with the information from the Identity Certificate. Note that you are not required to have the same validity dates in the Permissions Document and the Identity Certificate (upon creation, your DomainParticipant will independently verify that the Identity Certificate and the grant in your Permissions Document are valid for the current date). If you decide to update the validity tag, pay attention to the date/time format.

    ...
    <!-- Grants for a specific DomainParticipant will be grouped under this tag -->
    <grant name="ParticipantAlice">
        <!-- 1. The rules below will apply to the DomainParticipant
                whose identity certificate contains this subject name -->
        <subject_name>C=US, ST=CA, O=Patient Monitoring Innovations, CN=Alice, emailAddress=alice@pmi.com</subject_name>
        <!-- 2. Validity dates for this grant -->
        <validity>
            <!-- Format is CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] in GMT -->
            <not_before>2019-11-25T16:17:07</not_before>
            <not_after>2021-11-24T16:17:07</not_after>
        </validity>
        ...
    

7.5. Generating a New Permissions CA

Note

  • The Identity CA and Permissions CA may be the same, depending on your use case.

  • This section is analogous to Generating a New Identity CA.

  1. Modify cert/pmi/ca/pmiPermissionsCa.cnf and specify the fields under the req_distinguished_name section.

    This information will be incorporated into your certificate:

    ...
    [ req_distinguished_name ]
    
    countryName          = US
    stateOrProvinceName  = CA
    localityName         = Santa Clara
    0.organizationName   = Patient Monitoring Innovations
    commonName           = PMI Permissions CA
    emailAddress         = permissionsca@pmi.com
    ...
    
  2. Use the OpenSSL CLI to generate a self-signed certificate using the Permissions CA’s configuration. Run the following command from the cert/pmi directory:

    openssl req -nodes -x509 -days 1825 -text -sha256 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout ca/private/pmiPermissionsCaKey.pem -out ca/pmiPermissionsCaCert.pem -config ca/pmiPermissionsCa.cnf
    

    This will produce a new private key, pmiPermissionsCaKey.pem in the cert/pmi/ca/private directory, and a new certificate, pmiPermissionsCaCert.pem, in the cert/pmi/ca directory. This certificate will be valid for 1825 days (5 years) starting today.

7.5.1. Specifying the New Permissions CA Certificate in QoS Profiles

Modify USER_QOS_PROFILES.xml to make your DomainParticipants load the certificate of the new Permissions CA:

...
    <element>
        <name>dds.sec.access.permissions_ca</name>
        <value>file:./cert/pmi/ca/pmiPermissionsCaCert.pem</value>
    </element>
    ...

7.6. Signing the Governance and Permissions Documents

We will use the Permissions CA’s certificate and key that we generated to sign the Governance and Permissions Documents that we composed in previous Hands-On sections.

  1. Run the command below to create the signed Governance Document (with PKCS#7 format) named xml/signed/pmiSigned_pmiGovernance.p7s:

    openssl smime -sign -in xml/pmiGovernance.xml -text -out xml/signed/pmiSigned_pmiGovernance.p7s -signer cert/pmi/ca/pmiPermissionsCaCert.pem -inkey cert/pmi/ca/private/pmiPermissionsCaKey.pem
    
  2. Run the command below to create the signed Permissions Document (with PKCS#7 format) named xml/signed/pmiSigned_pmiPermissionsAlice.p7s:

    openssl smime -sign -in xml/pmiPermissionsAlice.xml -text -out xml/signed/pmiSigned_pmiPermissionsAlice.p7s -signer cert/pmi/ca/pmiPermissionsCaCert.pem -inkey cert/pmi/ca/private/pmiPermissionsCaKey.pem
    

7.6.1. Specifying the New Governance and Permissions Documents in Your QoS Profiles

Lastly, update USER_QOS_PROFILES.xml so that your DomainParticipants will load the Governance and Permissions Documents signed by your Permissions CA:

...
<!-- Signed Governance and Permissions Documents -->
<element>
    <name>dds.sec.access.governance</name>
    <value>file:./xml/signed/pmiSigned_pmiGovernance.p7s</value>
</element>
<element>
    <name>dds.sec.access.permissions</name>
    <value>file:./xml/signed/pmiSigned_pmiPermissionsAlice.p7s</value>
</element>
...

7.7. Updating the Subscriber’s Configuration

At this point, you have control of the keys and certificates used in your project. Congratulations!

In the previous steps, we have focused on updating your publisher application, Alice, with a new identity and matching permissions. Now, we will update Bob’s identity and permissions accordingly.

  1. Create an identity for your subscriber application, Bob, as described in Generating Identity Certificates. After this step, Bob’s QoS profile in USER_QOS_PROFILES.xml should load his new Identity Certificate, pmiBob.pem, and private key, pmiBobKey.pem.

  2. Update Bob’s Permissions Document, pmiPermissionsBob.xml, to match his new credentials (see Updating Permissions Documents with New Credentials).

  3. Finally, sign Bob’s Permissions Document with your new Permissions CA, as explained in Signing the Governance and Permissions Documents. After this step, Bob’s QoS profile in USER_QOS_PROFILES.xml should load the signed version of his new Permissions Document, pmiSigned_pmiPermissionsBob.p7s.

Now, run your publisher and subscriber using Domain 1 (specified with the -d option in the command line). You should see communication.

Publisher:

$ ./objs/<architecture>/PatientMonitoring_publisher -d 1
Writing PatientMonitoring, count 0
Writing PatientMonitoring, count 1
Writing PatientMonitoring, count 2
Writing PatientMonitoring, count 3

Subscriber:

$ ./objs/<architecture>/PatientMonitoring_subscriber -d 1
PatientMonitoring subscriber sleeping up to 1 sec...
PatientMonitoring subscriber sleeping up to 1 sec...
PatientMonitoring subscriber sleeping up to 1 sec...
[patient_condition: ]
PatientMonitoring subscriber sleeping up to 1 sec...
[patient_condition: ]
PatientMonitoring subscriber sleeping up to 1 sec...
PatientMonitoring subscriber sleeping up to 1 sec...
[patient_condition: ]
PatientMonitoring subscriber sleeping up to 1 sec...
3

In the license-managed version (with “lm” in the bundle name), OpenSSL is installed automatically when you install the Connext host bundle. After installation, OpenSSL will be in <installdir>/third_party/openssl-<version>.

7.8. Revoking an Identity Certificate

At this point, Alice and Bob are communicating using Identity Certificates that you generated yourself. Congratulations!

Now, we will learn how to revoke Alice’s Identity Certificate and how Bob can react to Alice’s change in status.

  1. To revoke Alice’s Identity Certificate, run the following command from the cert/pmi directory:

    $ openssl ca -config ca/pmiIdentityCa.cnf -batch -revoke identities/pmiAliceCert.pem
    

    You may repeat this command to revoke more certificates issued by the same CA.

  2. When you are done revoking certificates, you have to inform the DomainParticipants about the revoked certificates by generating a list of the revoked identities, which is called a Certificate Revocation List (CRL). To generate the list, run the following commands from the cert/pmi directory:

$ echo 01 > ca/database/pmiIdentityCaCrlNumber
$ openssl ca -config ca/pmiIdentityCa.cnf -batch -gencrl -out ca/pmi.crl

7.8.1. Specifying the New Certificate Revocation List in QoS Profiles

Each DomainParticipant that cares about avoiding communication with revoked DomainParticipants needs to load this list. Let’s assume Bob cares about avoiding communication with Alice. Modify USER_QOS_PROFILES.xml to make Bob’s DomainParticipant load the new CRL:

...
<element>
    <name>com.rti.serv.secure.authentication.crl</name>
    <value>file:./cert/pmi/ca/pmi.crl</value>
</element>
...

The CRL only takes effect when the DomainParticipant using the CRL is deleted and recreated. Stop and restart the subscriber application, Bob. Now when Bob discovers Alice, Bob will print this error:

"X509_verify_cert returned 0 with error 23: certificate revoked
subject name: /C=US/ST=CA/L=Santa Clara/O=Patient Monitoring Innovations/emailAddress=alice@pmi.com/CN=Alice
issuer name: /C=US/ST=CA/L=Santa Clara/O=Patient Monitoring Innovations/CN=PMI Identity CA/emailAddress=identityca@pmi.com"

Communication will not occur between Alice and Bob.

7.9. Troubleshooting

  • When I run my subscriber, I get the following error:

    [CREATE Participant] RTI_Security_CertHelper_loadPrivateKey:private_key is not encrypted, yet password is supplied. Aborting participant creation due to inconsistent configuration.
    

    In previous Hands-On sections, your subscriber used the ecdsa01Peer02Key.pem private key, which is password protected. If you did not specify a password for BobKey.pem, make sure you remove the dds.sec.auth.password property from Bob’s profile in USER_QOS_PROFILES.xml.

  • How can I verify whether a CA correctly issued an Identity Certificate?

    openssl verify -CAfile <identityCACert> <peerIdentityCert>
    
  • How can I verify the signed Governance and Permissions Documents?

    openssl smime -verify -CAfile <permissionsCACert> -in <signedFile>
    
  • I am using the Security Plugins with wolfSSL and see the following error when running either my publisher or my subscriber:

    RTI_Security_CertHelper_loadCertsCrls:WolfSSL function PEM_X509_INFO_read_bio failed with error: (error details not available)
    RTI_Security_CertHelper_loadCertsCrls:Error loading certificates
    

    This might be caused by the certificates being in an incompatible format. We recommend generating the certificates using OpenSSL version 1.1.1k or above, which you can install using the process described in the RTI Security Plugins Installation Guide.

For further troubleshooting, see Troubleshooting in Hands-On 3.