7. Hands-On 4: Generating 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 DDS 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 file and all the Permissions files. After each certificate generation, we will refer to the modifications needed to make your project load the new artifacts.

We will use RSA as the public-key algorithm to generate the certificates. Instead, you may want to use DSA, ECDSA, or another algorithm.

Note

We will use the OpenSSL CLI to perform the security operations in the generation of the security artifacts. Note that the Security Plugins do not depend on OpenSSL to generate these artifacts; you can choose another security toolkit.

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 a file called openssl.cnf in the cert directory. Make two copies of this file and call them pmiIdentityCa.cnf and pmiPermissionsCa.cnf. To better organize your project, keep these copies in the cert directory:

    $ cp cert/openssl.cnf cert/pmiIdentityCa.cnf
    $ cp cert/openssl.cnf cert/pmiPermissionsCa.cnf
    
    $ cp cert/openssl.cnf cert/pmiIdentityCa.cnf
    $ cp cert/openssl.cnf cert/pmiPermissionsCa.cnf
    
    > copy cert\openssl.cnf cert\pmiIdentityCa.cnf
            1 file(s) copied.
    > copy cert\openssl.cnf cert\pmiPermissionsCa.cnf
            1 file(s) copied.
    
  2. Modify pmiIdentityCa.cnf to redefine the dir variable:

    ...
    [ CA_default ]
    
    dir      = ./cert          # Top level directory (where everything is kept)
    certs    = $dir/certs      # Where the issued certificates are kept
    crl_dir  = $dir/crl        # Where the issued certificate revocation lists are kept
    database = $dir/index.txt  # Database index file
    ...
    

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 ca command:

$ touch cert/index.txt
$ echo 01 > cert/serial
$ touch cert/index.txt
$ echo 01 > cert/serial
> type nul > cert\index.txt
> echo 01> cert\serial

7.2. Generating a new Identity CA

  1. Modify cert/pmiIdentityCa.cnf to redefine the certificate and private_key variables:

    ...
    [ CA_default ]
    ...
    certificate      = $dir/pmiIdentityCaCert.pem # The CA certificate
    ...
    private_key      = $dir/pmiIdentityCaKey.pem  # The private key
    ...
    
  2. In the same file, 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
    ...
    
  3. Use the OpenSSL CLI to generate a self-signed certificate using the Identity CA’s configuration:

    $ openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert/pmiIdentityCaKey.pem -out cert/pmiIdentityCaCert.pem -config cert/pmiIdentityCa.cnf
    
    $ openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert/pmiIdentityCaKey.pem -out cert/pmiIdentityCaCert.pem -config cert/pmiIdentityCa.cnf
    
    > openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert\pmiIdentityCaKey.pem -out cert\pmiIdentityCaCert.pem -config cert\pmiIdentityCa.cnf
    

    This will produce a new RSA private key, pmiIdentityCaKey.pem, and a new certificate, pmiIdentityCaCert.pem, both in the cert 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/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. [1] 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 Alice.cnf. Save this file in the cert directory. You may want to use the following contents as a reference:

    Listing 7.1 Sample contents of Alice.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:

    $ openssl req -nodes -new -newkey rsa:2048 -config cert/Alice.cnf -keyout cert/AliceKey.pem -out cert/Alice.csr
    
    $ openssl req -nodes -new -newkey rsa:2048 -config cert/Alice.cnf -keyout cert/AliceKey.pem -out cert/Alice.csr
    
    > openssl req -nodes -new -newkey rsa:2048 -config cert\Alice.cnf -keyout cert\AliceKey.pem -out cert\Alice.csr
    

    This will produce an RSA private key, AliceKey.pem, and a CSR based on that key, Alice.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:

    $ openssl ca -config cert/pmiIdentityCa.cnf -days 730 -in cert/Alice.csr -out cert/AliceCert.pem
    
    $ openssl ca -config cert/pmiIdentityCa.cnf -days 730 -in cert/Alice.csr -out cert/AliceCert.pem
    
    > openssl ca -config cert\pmiIdentityCa.cnf -days 730 -in cert\Alice.csr -out cert\AliceCert.pem
    
  4. A dialog will prompt you to confirm the certificate signature.

    After your confirmation, the Identity CA will issue Alice’s public certificate, AliceCert.pem, which will be valid for 730 days (2 years) starting today.

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/AliceCert.pem</value>
</element>
<element>
    <name>dds.sec.auth.private_key</name>
    <value>file:./cert/AliceKey.pem</value>
</element>
...

7.4. Updating Permissions files with new credentials

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

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

    $ openssl x509 -in cert/AliceCert.pem -text -noout
    
    Certificate:
         Data:
         Version: 1 (0x0)
         Serial Number: 1 (0x1)
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=US, ST=CA, L=Santa Clara, O=Patient Monitoring Innovations, CN=PMI Identity CA/emailAddress=identityca@pmi.com
         Validity
             Not Before: Nov 25 16:17:07 2019 GMT
             Not After : Nov 24 16:17:07 2021 GMT
         Subject: C=US, ST=CA, O=Patient Monitoring Innovations, CN=Alice/emailAddress=alice@pmi.com
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 ...
    
    $ openssl x509 -in cert/AliceCert.pem -text -noout
    
    Certificate:
         Data:
         Version: 1 (0x0)
         Serial Number: 1 (0x1)
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=US, ST=CA, L=Santa Clara, O=Patient Monitoring Innovations, CN=PMI Identity CA/emailAddress=identityca@pmi.com
         Validity
             Not Before: Nov 25 16:17:07 2019 GMT
             Not After : Nov 24 16:17:07 2021 GMT
         Subject: C=US, ST=CA, O=Patient Monitoring Innovations, CN=Alice/emailAddress=alice@pmi.com
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 ...
    
    > openssl x509 -in cert\AliceCert.pem -text -noout
    
    Certificate:
         Data:
         Version: 1 (0x0)
         Serial Number: 1 (0x1)
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=US, ST=CA, L=Santa Clara, O=Patient Monitoring Innovations, CN=PMI Identity CA/emailAddress=identityca@pmi.com
         Validity
             Not Before: Nov 25 16:17:07 2019 GMT
             Not After : Nov 24 16:17:07 2021 GMT
         Subject: C=US, ST=CA, O=Patient Monitoring Innovations, CN=Alice/emailAddress=alice@pmi.com
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 ...
    
  2. Modify the subject_name in the Permissions file, 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 file and the Identity certificate (upon creation, your DomainParticipant will independently verify that the Identity certificate and the grant in your Permissions file 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/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:

    $ openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert/pmiPermissionsCaKey.pem -out cert/pmiPermissionsCaCert.pem -config cert/pmiPermissionsCa.cnf
    
    $ openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert/pmiPermissionsCaKey.pem -out cert/pmiPermissionsCaCert.pem -config cert/pmiPermissionsCa.cnf
    
    > openssl req -nodes -x509 -days 1825 -text -sha256 -newkey rsa:2048 -keyout cert\pmiPermissionsCaKey.pem -out cert\pmiPermissionsCaCert.pem -config cert\pmiPermissionsCa.cnf
    

    This will generate a new RSA private key, pmiPermissionsCaKey.pem, and a new certificate, pmiPermissionsCaCert.pem, both in the cert 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/pmiPermissionsCaCert.pem</value>
    </element>
    ...

7.6. Signing the Governance and Permissions files

Note

This section was covered in Signing the Governance File and Signing the Permissions Files.

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

  1. Run the command below to create the signed Governance file (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/pmiPermissionsCaCert.pem -inkey cert/pmiPermissionsCaKey.pem
    
    $ openssl smime -sign -in xml/pmiGovernance.xml -text -out xml/signed/pmiSigned_pmiGovernance.p7s -signer cert/pmiPermissionsCaCert.pem -inkey cert/pmiPermissionsCaKey.pem
    
    > openssl smime -sign -in xml\pmiGovernance.xml -text -out xml\signed\pmiSigned_pmiGovernance.p7s -signer cert\pmiPermissionsCaCert.pem -inkey cert\pmiPermissionsCaKey.pem
    
  2. Run the command below to create the signed Permissions file (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/pmiPermissionsCaCert.pem -inkey cert/pmiPermissionsCaKey.pem
    
    $ openssl smime -sign -in xml/pmiPermissionsAlice.xml -text -out xml/signed/pmiSigned_pmiPermissionsAlice.p7s -signer cert/pmiPermissionsCaCert.pem -inkey cert/pmiPermissionsCaKey.pem
    
    > openssl smime -sign -in xml\pmiPermissionsAlice.xml -text -out xml\signed\pmiSigned_pmiPermissionsAlice.p7s -signer cert\pmiPermissionsCaCert.pem -inkey cert\pmiPermissionsCaKey.pem
    

7.6.1. Specifying the new Governance and Permissions files in your QoS profiles

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

...
<!-- Signed Governance and Permissions files -->
<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. Further Exercises

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 a new Identity CA. After this step, Bob’s QoS profile in USER_QOS_PROFILES.xml should load his new Identity certificate, Bob.pem, and private key, BobKey.pem.
  2. Update Bob’s Permissions file, pmiPermissionsBob.xml, to match his new credentials (see Updating Permissions files with new credentials).
  3. Finally, sign Bob’s Permissions file with your new Permissions CA, as explained in Signing the Governance and Permissions files. After this step, Bob’s QoS profile in USER_QOS_PROFILES.xml should load the signed version of his new Permissions file, pmiSigned_pmiPermissionsBob.p7s.

Now, run your publisher and subscriber using domain 1 (specified as the first argument to your applications). You should see communication.

7.8. Troubleshooting

  • When I run OpenSSL, I get an error similar to this:

    Can't open ./demoCA/pmiIdentityCaKey.pem for reading, No such file or directory
    

    Make sure you have modified the dir variable in pmiIdentityCa.cnf as described in Preliminary steps.

  • 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 peer2key.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.

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

[1]Depending on your use case, the Identity certificates may be issued by an intermediate CA in your PKI instead.