Monday, January 20, 2014

Using CMP with the CMP for OpenSSL tool, to integrate client and RAs in a PKI


Implementing CMP to enroll for certificates and do automatic certificate renewal against a CA that supports the CMP protocol, the open source tool CMP for OpenSSL should be considered. Using the CMP protocol is a great way to integrate client and RAs in a PKI, and CMP for OpenSSL is a very promising tool.

Some background on CMP

The open source CA EJBCA implements many standard PKI protocols. One of them is CMP, which has been around since September 2005 when the RFC4210 first was published. In the early days adoption of CMP was progressing slowly due to the great complexity. The huge amount of options still make CMP somewhat cumbersome both to implement and use.

In the beginning CMP was mostly used from RAs, such as card/token management systems and in-house RAs. In the last couple of years adoption of CMP has increased and is now used in several systems, for example in LTE mobile networks where CMP is profiled by 3GPP (supported in PrimeKey's EJBCA Enterprise).

However, being a complex protocol with many options, CMP can be used for many different use cases. From clients that enrolls for certificates with optional automatic renewal, to RAs that registers end entities and issues certificates for those. All combined with several different ways of authentication, such as shared secrets and client certificates. One important distinction to make, is that messages specified by the protocol are one thing, another is the expected behavior in the back end (for example if a client needs to be pre-registered or not, or if any fields are accepted from an RA, or if there are any profile limitations). The messages themselves are specified in the CMP standard, but the behavior is defined by the specific use cases and sometimes standardization groups such as 3GPP.

CMP has been implemented within EJBCA since ECA-99 in 2006. PrimeKey's implementation has matured a lot during this time, and the latest evolution is CMP Aliases. In the current state CMP can be used for an uncountable number of different use cases with different back-end behavior, depending on the configuration.

CMP for OpenSSL

The main obstacle slowing the adoption of any protocol, is lack of free and open source implementations. So it is both pleasing and welcome to see CMP for OpenSSL appear. Being an excellent tool, we hope to see it integrated into OpenSSL at some point.

Note: Before using CMP for OpenSSL you must download and build it. It is not included in any standard distribution of OpenSSL.

Using CMP for OpenSSL as CMP client

Here I will show three different enrollment types; A client with a pre-registered shared secret, a client using certificate authentication, and an RA using shared secret authentication.
There is of course much else you can do. The RA can for example use certificate authentication, you can do nested messages with multiple layers of authentication etc. Only your imagination sets the limits on how to use CMP :-). Along with EJBCA 6 all these different configurations can be active at the same time.

For complete documentation, see the Admin Guide at

Pre-registered client with password authentication

  • Download the CA certificate to the client
  • Add a new end entity in EJBCA
  • Run the command
./openssl cmp -cmd ir -server -path ejbca/publicweb/cmp -srvcert MyCA.cacert.pem -user username -pass password -certout clcert1.pem -newkey key1.pem -keyfmt PEM -certfmt PEM -subject "/CN=username/O=My Organization/C=SE"

Where username is the username you added (you have to type it twice it's in the CN as well) and password is the password you entered when adding the end entity.

The above requires a CMP alias in EJBCA with the following configuration:
  • Client mode
  • HMAC authentication module
  • CN as extract username component

Pre-registered client with certificate authentication

Since this requires an existing certificate for the client, you can use the above enrollment method to generate it, but other possibilities exist of course.

./openssl cmp -cmd ir -server -path ejbca/publicweb/cmp/alias1 -srvcert MyCA.cacert.pem -cert clcert1.pem -key key1.pem -certout clcert2.pem -newkey key1.pem -keyfmt PEM -certfmt PEM

Where clcert1.pem and key1.pem is the cert and key generated previously (used for authentication to the same user). clcert2.pem will be the new certificate, and for simplicity we re-use key1.pem as -newkey, but you can generate a new one as well.

The above requires a CMP alias in EJBCA with the following configuration:
  • Client mode
  • EndEntityCertificate authentication module
  • CN as extract username component

RA with shared secret authentication

Using an RA means that the RA should be able to order certificates for clients of the RA. The clients themselves will not be pre-registered by the CA, but will be added by the RA when the RA enrolls for the client.

./openssl cmp -cmd ir -server -path ejbca/publicweb/cmp/alias2 -srvcert MyCA.cacert.pem -user user4711 -pass password -certout clcert1.pem -newkey key1.pem -keyfmt PEM -certfmt PEM -subject "/CN=user4711/O=My Organization/C=SE"

Where User and CN should be the same, and afterwards the client will be available as "username" in EJBCA.

The above requires a CMP alias in EJBCA with the following configuration:
  • RA mode
  • HMAC authentication module
  • Specified secret 'password1'
  • DN parts with CN as RA name generation scheme

About the author

Tomas Gustavsson, CTO of PrimeKey, founder of EJBCA
Contact me at: tomas(at)
Follow me on Twitter: primetomas


tomas said...

The Admin Guide has moved to docs subdirectory.

tomas said...

Note that cmpforopenssl has evolved and some command syntax has changed.
In particular the -user and -pass options have been generatlized and renamed to -ref and -secret.

Check the cmpforopenssl documentation at:

The latest code resides on:

Kumaresh said...

Adding to the change in Syntax/command line arguments:
-keyform has become -keyform
-certfmt seems to have been divided to -ownform and -otherform (I may not be precise here but -certfmt is no more an argument)