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.
- Generate a key pair.
- Initial enrolment of client certificate using a one-time enrollment code.
- Generate a new key pair.
- 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
Generate a key pair:
BASH$ ./openssl genrsa -out certs/cl_key.pem 2048
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).BASHopenssl 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"
Generate a new key pair:
BASH$ ./openssl genrsa -out certs/cl_new_key.pem 2048
Renew with a new certificate (cmptest user status should be set back to 10 (NEW)):
BASHopenssl 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
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.