CMP Operations Guide

The following includes operations, configurations, and workflows using the Certificate Management Protocol (CMP).

For more information about CMP and how it works with EJBCA, see the CMP overview page.

3GPP

For 3GPP specific operations and settings, see 3GPP Operations.

Sample Commands Using CMP for OpenSSL

Enrolling in RA Mode

cmpforopenssl works with EJBCA in RA mode with the following EJBCA configuration, using for example alias "opensslra" (unmentioned configurations = default):

CMP Operational Mode : RA Mode
CMP Response Protection : pbe
CMP Authentication Module : HMAC
CMP Authentication Parameters : password

You can then use cmpforopenssl (as an RA):

$ ./openssl genrsa 2048 > key1.pem
$ ./openssl cmp -cmd ir -server localhost:8080 -path ejbca/publicweb/cmp/opensslra -srvcert ManagementCA.cacert.pem -ref NewUser -secret pass:password -certout clcert1.pem -newkey key1.pem -subject "/CN=NewUser/O=My Organization/C=SE"

This requests a certificate, defining the subject DN that will be used. The CA used to sign the certificate is specified in the EJBCA CMP configuration and can be taken from the keyid. EJBCA authenticated the request using the HMAC protection with the password, and accepts any request upon correct authentication.

You can request server generated keys by omitting the public key in the certificate request, using the same request as an ir, but without public key. Note however that the cmpclient cannot be used since no cmpclient parameters support omitting the public key. For example Java code, refer to the test class CrmfRequestTest.test12ServerGeneratedKeys().

For p10cr request type:

First generate a CSR of the type PKCS10 and the RSA key pair using the following command (subject flag is not supported in case of p10cr):

openssl req -new -newkey rsa:2048 -nodes -out cmptestp10cr.csr -keyout cmptestp10cr.key -subj "/C=SE/ST=Stockholm/L=Solna/O=My Org/OU=IT/CN=cmptestp10cr"

Then use the following openssl command to get a certificate from EJBCA cmp backend:

openssl cmp -cmd p10cr -server localhost:8080 -path ejbca/publicweb/cmp/opensslra -srvcert ManagementCA.cacert.pem -ref cmptestp10cr -secret pass:password -certout cmptestp10cr.pem -csr cmptestp10cr.csr

Note that in the above command ref is the common name mentioned in the CSR and the secret used is of type password and should be set in the alias accordingly.

Revoking a Certificate in RA Mode

To revoke an issued certificate the RA can send a CMP Revoke Request:

openssl cmp -cmd rr -server localhost:8080 -path ejbca/publicweb/cmp/opensslra -srvcert ManagementCA.cacert.pem -oldcert ./clcert1.pem -secret pass:password -ref ffaabb

Note that the ref value is a random value.

Enrolling in Client Mode with HMAC Password Authentication

cmpforopenssl works with EJBCA in client mode, with HMAC password authentication, using the following EJBCA configuration with for example the alias "opensslclient" (unmentioned configurations = default):

CMP Authentication Module : HMAC
CMP Authentication Parameters : password
Extract Username Component : CN

You can now add a new user in EJBCA:

$ bin/ejbca.sh ra addendentity user1 --password password "CN=user1,O=My Organization,C=SE" ManagementCA 1 USERGENERATED
$ bin/ejbca.sh ra setclearpwd user1 password
$ bin/ejbca.sh ra setendentitystatus user1 10

You can then use cmpforopenssl (as a client):

$ ./openssl cmp -cmd ir -server localhost:8080 -path ejbca/publicweb/cmp/opensslclient -srvcert ManagementCA.cacert.pem -ref user1 -secret pass:password -certout clcert1.pem -newkey key1.pem -subject "/CN=user1/O=My Organization/C=SE"

This requests a certificate, and the requested subject DN must match the registered subject DN. EJBCA authenticates the request using the HMAC protection with the password of the registered user. See the CMP documentation above for more advanced configuration.


In case of p10cr requests (assuming new user1 with status GENERATED exists in EJBCA):

First create a PKCS#10 CSR using the following command:

openssl req -new -newkey rsa:2048 -nodes -out user1.csr -keyout user1.key -subj "/C=SE/ST=Stockholm/L=Solna/O=My Org/OU=IT/CN=user1"

Then you can use that csr with openssl p10cr sub-command to issue a certificate as follows:

openssl cmp -cmd p10cr -server localhost:8080 -path ejbca/publicweb/cmp/opensslclient -srvcert ManagementCA.cacert.pem -ref user1 -secret pass:password -certout user1p10cr.pem -csr user1.csr


Enrolling in Client Mode, Client Certificate Authentication

cmpforopenssl works with with EJBCA in client mode, with certificate authentication, using the following EJBCA configuration with alias tex. "openssleec" (unmentioned configurations = default):

CMP Authentication Module : EndEntityCertificate
CMP Authentication Parameters : ManagementCA (use the CA that issues your client authentication certificate)
Extract Username Component : CN

You can now issue a certificate using certificate authentication in EJBCA (the end entity needs a certificate before so we re-use user1 from above):

$ bin/ejbca.sh ra setclearpwd user1 password
$ bin/ejbca.sh ra setendentitystatus user1 10

You can then use cmpforopenssl (as a client):

$ ./openssl cmp -cmd ir -server localhost:8080 -path ejbca/publicweb/cmp/openssleec -srvcert ManagementCA.cacert.pem -cert clcert.pem -key key.pem -certout clcert1.pem -newkey key1.pem -subject "/CN=user1/O=My Organization/C=SE"

This requests a certificate, and the requested subject DN must match the registered subject DN. EJBCA authenticates the request using the signature protection with the certificate of the registered user. See the CMP documentation above for more advanced configuration.

You can also use a 'cr' instead of an 'ir';

$ bin/ejbca.sh ra setendentitystatus user1 10
./openssl cmp -cmd cr -server localhost:8080 -path ejbca/publicweb/cmp/openssleec -srvcert ManagementCA.cacert.pem -cert clcert.pem -key key.pem -certout clcert1.pem -newkey key1.pem -subject "/CN=user1/O=My Organization/C=SE"

In case of p10cr message you can use the following openssl command (set the user1 status back to 10 before):

openssl cmp -cmd p10cr -server localhost:8080 -path ejbca/publicweb/cmp/openssleec -srvcert ManagementCA.cacert.pem -ref user1 -cert user1p10cr.pem -certout user1p10cr2.pem -csr user1.csr -key user1.key

user1.key is the key used to sign the original CSR.

Enrolling Device with HMAC password

A typical PKI workflow using CMP involves enrolling a device with a certificate and then having the device automatically renew the certificate when it is about to expire.

  1. Generate a key pair.

  2. Initial enrolment of client certificate using a one-time enrollment code.

  3. Generate a new key pair.

  4. Renew with a new certificate for the new key pair, authenticated using the old key pair and certificate.

The above steps can be simulated in reality using the openssl and cmpforopenssl client, but also using the EJBCA cmpclient.

This works with a default cmpalias (named cmp) configured with parameters:

CMP Authentication Module : HMAC
CMP Authentication Parameters : password
Extract Username Component : CN
  1. Generate a key pair:

    $ ./openssl genrsa -out certs/cl_key.pem 2048
  2. Initial enrolment:
    Before initial enrolment, add a new End Entity in EJBCA, in this example with user name cmptest and subject DN 'CN=cmptest', and enrolment code 'CMP-pwd' (clear text password should be set for the cmptest user).

    openssl cmp -cmd ir -server localhost:8080 -path ejbca/publicweb/cmp/cmp -srvcert ManagementCA.cacert.pem -ref cmptest -secret pass:CMP-pwd -newkey certs/cl_key.pem -certout certs/cl_cert.pem -subject "/CN=cmptest"
  3. Generate a new key pair:

    $ ./openssl genrsa -out certs/cl_new_key.pem 2048
  4. Renew with a new certificate (cmptest user status should be set back to 10 (NEW)):

    openssl cmp -cmd kur -server localhost:8080 -path ejbca/publicweb/cmp/cmp -srvcert ManagementCA.cacert.pem -key certs/cl_key.pem -cert certs/cl_cert.pem -newkey certs/cl_new_key.pem -certout certs/cl_new_cert.pem

    For p10cr request type key update, generate a new key pair first:

openssl genrsa -out certs/cl_new_key_p10cr.pem 2048

Set the status of the cmptestp10cr user (assuming it already exists in EJBCA) back to NEW (10) :

bin/ejbca.sh ra setendentitystatus cmptestp10cr 10

And update the keys (getting a new cert) using the new key pair generated above with the following command:

openssl cmp -cmd kur -server localhost:8080 -path ejbca/publicweb/cmp/cmp -srvcert ManagementCA.cacert.pem -key cmptestp10cr.key -cert cmptestp10cr.pem -newkey certs/cl_new_key_p10cr.pem -certout p10cr_new_cert.pem


Custom Handling of Certificate Requests

A custom plug-in class can be added to handle a certificate request. The class implementing this plug-in must implement the org.ejbca.core.protocol.ExtendedUserDataHandler interface.

For more information, see Creating Custom Request Processors.

Sample Client Messages

While many CMP clients exist (as listed on the CMP overview page), many use cases require writing custom clients. Using the BouncyCastle crypto libraries, we've produced some sample implementations in Java if you need some help in getting going.

For more information, see CMP Client Support.