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

Sunday, January 5, 2014

ETSI CAdES PlugTest event with SignServer


SignServer participated in the ETSI CAdES Plugtest Interop event with SignServer developers Markus Kilås and Marcus Lundblad. Here is a summary of Markus's report from the event.

The Plugtest Event

The ETSI Centre for Testing and Interoperability (CTI) organized a Remote Plugtest Interop event for CAdES Signatures scheduled from 2nd to 13th December 2013, and later extended to the 20th December.

The event was conducted remotely using the Electronic Signature Plugtest Portal, e-mail and three conference calls.

About 60 companies joined the event.

The Plugtest Portal

The event was conducted mostly through the portal where the participants could download an “inital package”, a zip file with test case specifications for which signatures to create, as well as folders for the different participants.

After creating the signatures (according to the specifications) those could be placed in the participant's folder, the relevant parts of the folder structure zipped together, then uploaded to the portal. The Portal took care of merging the uploaded files and created a new package for download by all participants. In the same way signature verification reports could be uploaded and a matrix with the results could be viewed in the portal.

There were 84 different test cases in the cross-verification part of the event.

SignServer implementation

SignServer did not support any form of CAdES prior to the event. We decided to base our implementation on the library SD DSS.

Because of limited time and SD DSS using an older version of BouncyCastle, we simply developed a standalone proof of concept not yet integrated in SignServer. We based our implementation on SD DSS version 2.0.2, but during the event version 3.0.2 was released. Yet, we decided to continue on 2.0.2 through the event, as we already had done a lot of changes, both bug fixes and added features, since it otherwise would have taken too long to merge it to the new version. We also took contact with the authors of the library and got informed about version SD DSS version 4, planned for January-February 2014, with major changes in the verification parts.

Our implementation consisted of a standalone Java CLI application, which could either sign or verify a document. The application used a configuration file (similar to the signer configuration file in SignServer) configuring the CryptoTokens to use.

Test Cases

To easily create all necessary signatures and also perform validation of the other participants's signatures, we used JUnit test cases that could be run from within the IDE. A Java base class contained a single test method for each type of signature to create/verify. The method took care of calling the PoC application with the right properties for each type of signature, and then performed the necessary verifications to check that the signature complied with the test specification. This was implemented using JUnit asserts, and some magic in a base class took care of producing a verification report, according to the plug test specification.

To be able to perform all the tests implemented for all participants, the base class was extended and parameterized with a list of all participants, so that each test method was executed for each participant.

A complete run produced about 600 verification reports.

JUnit test results (NetBeans IDE)

Results summary

  • The support for CAdES-BES, CAdES-BpB and CAdES-T was quite good, except for the missing support for counter signatures (BES-6).
  • For CAdES-EPES some participants were reporting problems.
  • For CAdES-C and CadES-X* we had some issues related to the ordering of revocation information references.
  • We did not perform any CAdES-A and signature upgrades (CAdES-UpdArb).
Support for correctly verifying signatures was mostly lacking and we did not put any big effort into resolving that during the event, as the verification support will be largely changed in the next version of SD DSS.


We participated in the event and had good interoperability results for the basic forms of CAdES, during the limited time-frame.

We now have a lot more knowledge about CAdES and the SD DSS library. We also developed a set of test cases that will be helpful when developing and integrating CAdES support in SignServer.

More work is needed to make our CAdES implementation stable and to integrate it in SignServer, as well as adding support for the more evolved forms of CAdES (which we did not have time for during this event).

We look forward to attending the next CAdES PlugTest Event!