PKI - Enroll Certificates HowTo

About

This document aims to show how to enroll two certificates using the SCEP protocol: one from a server running OpenXPKI as a SCEP server and certificate authority, and one from a server running Windows NDES. The configuration of OpenXPKI and Windows NDES servers is not part of this document.

For an overview of all SCEP configuration settings, see: SCEP

Prerequisites

  • When dealing with certificates, it is important that the system clock on the device is correctly set, preferably using an NTP server.

  • In these examples, it is assumed that a DNS server has been configured.

Enrollment Servers

This section covers the configuration of enrollment servers.

OpenXPKI server

To enroll a certificate, we first configure an enrollment server in the PKI config context. Let us start with the OpenXPKI server.

example:/#> configure
example:/config/#> pki
example:/config/pki/#> enroll 1
example:/config/pki/enroll-server-1#>

We give the server a meaningful label that is unique among local CA certificates and enrollment servers. The Root-CA certificate fetched from the server will be given that label. If there are any existing CA certificates with the same label, we recommend removing them first before proceeding with the configuration. Note: The label cannot be changed once the configuration is applied.

example:/config/pki/enroll-server-1#> label xpki-srv

Let us write a short description that fits and specify the complete url to the server, including scheme and port if applicable. Note that the SCEP protocol typically uses HTTP to communicate with the server.

example:/config/pki/enroll-server-1#> label xpki-srv
example:/config/pki/enroll-server-1#> description This is the OpenXPKI server
example:/config/pki/enroll-server-1#> url http://myurl.com:8080/scep/generic

The fingerprint is a hash of the Root-CA certificate in DER format. It is used for automatic integrity and authenticity checks before enrollment.

The fingerprint can be calculated as follows:

$ openssl x509 -outform der -in cert-ca.pem | sha256sum
ddaf9cb51e5bd1e882d0a7a3c1b3bc6cc1cb129071b06a3e6b27c06e503b04b3  -
example:/config/pki/enroll-server-1#> fingerprint ddaf9cb51e5bd1e882d0a7a3c1b3bc6cc1cb129071b06a3e6b27c06e503b04b3

Note

Ensure that the fingerprint and fingerprint-alg match the values calculated for the server’s Root-CA certificate. Using the wrong fingerprint will result in failure.

Be sure to use the Root-CA certificate to get the correct fingerprint.

Lastly, we set the renew-request to PKCSReq. The RFC 8894 standard introduced a dedicated RenewalReq message type. However, some SCEP servers (e.g., OpenXPKI) do not support it and perform renewal using PKCSReq instead of RenewalReq. Windows NDES handles it correctly.

example:/config/pki/enroll-server-1#> cipher aes128-cbc
example:/config/pki/enroll-server-1#> renew-request pkcs-req

A complete configuration of the OpenXPKI enrollment server might look like this:

example:/config/pki/enroll-server-1#> show
Server #                      : 1
Label                         : xpki-srv
Description                   : This is the OpenXPKI server
Status                        : Enabled
URL                           : http://myurl.com:8080/scep/generic
fingerprint                   : 0542DFC5F97A4812E18FBA0CAE092E82...
fingerprint-alg               : SHA256
Protocol                      : SCEP
Cipher                        : AES128-cbc
Renew-request                 : PKCSReq
example:/config/pki/enroll-server-1#>

Now we can apply the enrollment server configuration context with:

example:/config/pki/enroll-server-1#> leave

Windows NDES server

In a similar fashion, we configure a Windows NDES server:

example:/#> configure
example:/config/#> pki
example:/config/pki/#> enroll 2
example:/config/pki/enroll-server-2#> label win-srv
example:/config/pki/enroll-server-2#> description This is the Windows NDES server
example:/config/pki/enroll-server-2#> url http://myurl.com/certsrv/mscep/mscep.dll
example:/config/pki/enroll-server-2#> fingerprint 7BDFAB9BEDB200DE53F34DA2F2A9E8F9
example:/config/pki/enroll-server-2#> fingerprint-alg MD5
example:/config/pki/enroll-server-2#> cipher 3des-cbc
example:/config/pki/enroll-server-2#> show
Server #                      : 2
Label                         : win-srv
Description                   : This is the Windows NDES server
Status                        : Enabled
URL                           : http://myurl.com/certsrv/mscep/mscep.dll
fingerprint                   : 7BDFAB9BEDB200DE53F34DA2F2A9E8F9
fingerprint-alg               : MD5
Protocol                      : SCEP
Cipher                        : 3DES-CBC
Renew-request                 : RenewalReq
example:/config/pki/enroll-server-2#>

Now we can step out of the enrollment server configuration context with:

example:/config/pki/enroll-server-2#> leave

Verification

Let’s verify if our configuration was successful in the PKI exec context.

example:/pki/#> show

PKI
Daemon                                                                
Status                        : Running
Uptime                        : 1 min 12 sec

Enroll Servers
ID  LABEL      STATUS   TIME                 Message                  
1   xpki-srv   Enabled  2025-06-02 14:01:09  responding
2   win-srv    Enabled  2025-06-02 14:01:09  responding

[...]

The PKI daemon responsible for enrollment is up and running and the two SCEP endpoints are responding. For other possible statuses see the troubleshooting section.

We see that CA/RA certificates were successfully downloaded. Notice Root-CA certificates xpki-srv and win-srv that can be referred to from other parts of the system.

example:/pki/cert/#> show full

TYPE     HASH     EXPIRES     NAME                 DIST LABEL          
CA-local 684a8b4c Apr 29 2026 OpenXPKI:scep-ra       SCEP xpki-srv+ra
CA-local 8dff03d8 Apr 28 2026 OpenXPKI Issuing     SCEP xpki-srv-1.792a8246
CA-local 5be49178 Apr 28 2035 OpenXPKI Root~250425 SCEP xpki-srv
CA-local 12ec9d6d Apr 04 2026 WSE-S0307-MSCEP-RA   SCEP win-srv+ra-2
CA-local 12ec9d6d Apr 04 2026 WSE-S0307-MSCEP-RA   SCEP win-srv+ra
CA-local 627f7b0a Apr 04 2049 rndtestad-WSE~307-CA SCEP win-srv
Pub      52ff4f77 Jan 19 2038 zero-ee-00-00.local  web-default
Key      N/A      N/A         web-default          N/A  web-default

Certificate Enrollment Requests

Enrolling from OpenXPKI server

Now it is time to enroll our first certificate from the OpenXPKI server. Let us enter the enrollment context. We are greeted with errors and warnings indicating the need to fill empty fields of the request.

example:/#> pki
example:/pki/#> cert
example:/pki/cert/#> enroll mycert1
╒ Configuration Errors: 3 ═══════════════════════════════════════════════════╕
│#   Description                                                             │
│1   Server label missing.                                                   │
├────────────────────────────────────────────────────────────────────────────┤
│2   Server label not defined in the system.                                 │
├────────────────────────────────────────────────────────────────────────────┤
│3   Certificate Distinguished Name missing.                                 │
└────────────────────────────────────────────────────────────────────────────┘
╒ Configuration Warnings: 2 ═════════════════════════════════════════════════╕
│#   Description                                                             │
│1   The challenge password is missing. It is strongly recommended to use a  │
│    challenge password while enrolling a certificate.                       │
├────────────────────────────────────────────────────────────────────────────┤
│2   Certificate SubjectAlternativeName missing.                             │
└────────────────────────────────────────────────────────────────────────────┘
example:/pki/cert/enroll-mycert1/#> show
Server                        :
Password                      :
DN                            :
Renewal-threshold             : 80 %
SAN                           :
Keysize                       : 2048
Profile                       :

A Certificate Enrollment Request combines in one context parameters related to the enrollment process and parameters of the end-entity certificate we want to enroll.

First, we start by choosing the server to enroll from and the challenge password provided by the server administrator. We keep renewal-threshold to its default value of 80%.

example:/pki/cert/enroll-mycert1/#> server xpki-srv
example:/pki/cert/enroll-mycert1/#> password SecretChallange

Security

It is RECOMMENDED that the challengePassword be a one-time authenticator value to limit the ability of an attacker who can capture the authenticator from the client or CA and reuse it to request further certificates. Read more here: RFC8894.

Second, we fill parameters of the certificate itself:

example:/pki/cert/enroll-mycert1/#> dn CN=mycert1.co.uk, C=UK
example:/pki/cert/enroll-mycert1/#> san 192.168.100.101
example:/pki/cert/enroll-mycert1/#> profile tls-server

The profile and san are not mandatory but are recommended parameters. The profile depends on the server configuration and should be provided by the server administrator.

A complete configuration presents like this:

example:/pki/cert/enroll-mycert1/#> show
Cert label                    : mycert1
Server                        : xpki-srv
Password                      : SecretChallange
DN                            : CN=mycert1.co.uk, C=UK
Renewal-threshold             : 80 %
SAN                           : 192.168.100.101
Keysize                       : 2048
Profile                       : tls-server
example:/pki/cert/enroll-mycert1/#>

Now we can apply the configuration:

example:/pki/cert/enroll-mycert1/#> end

From now on, the device will send enrollment requests to the server until enrollment or failure. Regardless of whether requests reached the server or not, the certificate is considered PENDING. To show the status of the certificate:

example:/pki/cert/#> show
TYPE     HASH     EXPIRES     NAME                 DIST LABEL                 
Pub               PENDING     N/A                  SCEP mycert1
Pub      4e3ca0d2 Jan 19 2038 zero-ee-00-00.local  web-default

While the certificate is in state PENDING, we can see its parameters with:

example:/#> pki cert show mycert1
Certificate request configuration for 'mycert1':
  Server label: xpki-srv
  Password:
  DN: CN=mycert1.co.uk, C=UK
  Renewal-threshold: 80
  SAN: 192.168.100.101
  Keysize: 2048
  Profile: tls-server

At this point, it is up to the CA administrator to either approve or reject our request. After approval, a certificate will be automatically downloaded to the device at the next certificate check done by the device (approximately within 2 minutes). The check can be manually triggered:

example:/#> pki trigger
Triggering PKI daemon.

After approval, the status of the certificate will show:

example:/#> pki cert show
TYPE     HASH     EXPIRES     NAME                 DIST LABEL                 
Pub      5bddad69 Feb 17 2025 mycert1.co.uk        SCEP mycert1
Pub      4e3ca0d2 Jan 19 2038 zero-ee-00-00.local  web-default

When rejected, the status would look like this:

example:/#> pki cert show
TYPE     HASH     EXPIRES     NAME                 DIST LABEL                 
Pub               REJECTED    N/A                  SCEP mycert1
Pub      4e3ca0d2 Jan 19 2038 zero-ee-00-00.local  web-default

There are many potential reasons for rejection, e.g.: the request contained invalid or incomplete information, failed policy checks (such as subject name or key usage restrictions), the requester is not authorized, or the CA administrator manually denies the request due to security concerns or mismatched credentials. Contact the server administrator for details.

In such a case, try re-editing the request and applying it again. A new private key will be generated and the request will get PENDING status again.

example:/pki/cert/#> enroll mycert1

[ *** modify the request ***]

example:/pki/cert/enroll-mycert1/#> end
example:/pki/cert/#> show

Certificates
TYPE     HASH     EXPIRES     NAME                 DIST LABEL                 
Pub               PENDING     N/A                  SCEP mycert1
example:/pki/cert/#>

Enrolling from Windows NDES server

In a similar fashion, we can now enroll a certificate from the NDES server:

example:/#> pki
example:/pki/#> cert
example:/pki/cert/#> enroll mycert2
example:/pki/cert/enroll-mycert2/#> server win-srv
example:/pki/cert/enroll-mycert2/#> password CFFD9A59
example:/pki/cert/enroll-mycert2/#> dn CN=mycert2.co.uk, C=UK
example:/pki/cert/enroll-mycert2/#> san 192.168.100.102
example:/pki/cert/enroll-mycert2/#> profile RnDTestSCEPCertificate
example:/pki/cert/enroll-mycert2/#> show
Server                        : win-srv
Password                      : CFFD9A59
DN                            : CN=mycert2.co.uk, C=UK
Renewal-threshold             : 80 %
SAN                           : 192.168.100.102
Keysize                       : 2048
Profile                       : RnDTestSCEPCertificate

Applying the configuration starts the enrollment.

example:/pki/cert/enroll-mycert2/#> end

After the second certificate request is approved, the

example:/#> pki cert show
TYPE     HASH     EXPIRES     NAME                 DIST LABEL                 

Pub      a9b6da71 Feb 15 2025 mycert2.co.uk       SCEP mycert2
Pub      5bddad69 Feb 17 2025 mycert1.co.uk       SCEP mycert1
Pub      4e3ca0d2 Jan 19 2038 zero-ee-00-00.local      web-default

Now we have two certificates enrolled: one from an OpenXPKI server and the other from a Windows NDES server.

The device will start to send renewal requests for updated certificates when 80% of the validity period has elapsed, as specified in the ‘Renewal-threshold’ setting.

Troubleshooting

Enrollment Server status

example:/pki/#> show

PKI
Daemon                                                                
Status                        : Running
Uptime                        : 10 min 12 sec

Enroll Servers
ID  LABEL      STATUS   TIME                 Message                  
1   xpki-srv   Enabled  2025-06-02 14:01:09  CA fingerprint mismatch
2   win-srv    Enabled  2025-06-02 14:01:09  responding

[...]

When server is not responding one of the following STATUS messages might show up:

  • server not reachable - Indicates that server’s end point is not reached, the server’s url might be misspelled. Trying pinging the server to verify that the host is reachable.
  • CA not downloaded - Attempt to download CA/RA certificates failed.
  • CA fingerprint mismatch - CA certificate has been download but its Root-CA’s fingerprint does not match the one configured.
  • no RA cert found - No RA certificate has been download.

Examine syslog messages, verify configuration.

Certificate keeps PENDING

If a certificate keeps pending after applying the enrollment request there might be several reasons for that. To solve the issue:

  • Check if the enrollment server is responding.
  • Check if the correct server is associated with the certificate request.
  • Contact the server administrator, the request might need manual approval.