CertEnroll

The CertEnroll component of the Keyfactor Web APIs includes all methods necessary to programmatically request and obtain a certificate. Keyfactor Command supports enrollmentClosed Certificate enrollment refers to the process by which a user requests a digital certificate. The user must submit the request to a certificate authority (CA). through Microsoft Active Directory Certificate Services Certificate Authorities, both in the local Active Directory forestClosed An Active Directory forest (AD forest) is the top most logical container in an Active Directory configuration that contains domains, and objects such as users and computers. and, by using Keyfactor Gateways, in remote domains and a variety of public CAClosed A certificate authority (CA) is an entity that issues digital certificates. Within Keyfactor Command, a CA may be a Microsoft CA or a Keyfactor gateway to a cloud-based or remote CA. vendors. Contact your Keyfactor representative for more information about Keyfactor Gateways, including the most recent list of supported Certificate Authorities.) The CertEnroll component allows enrollment through all CAs configured in your Keyfactor Command environment. The APIClosed A set of functions to allow creation of applications. Keyfactor offers the Keyfactor API, which allows third-party software to integrate with the advanced certificate enrollment and management features of Keyfactor Command. supports two variations of enrollment. The more secure variant allows the client application to generate the certificate’s public/private keypair on the device issuing the request, so that the private keyClosed Private keys are used in cryptography (symmetric and asymmetric) to encrypt or sign content. In asymmetric cryptography, they are used together in a key pair with a public key. The private or secret key is retained by the key's creator, making it highly secure. is never transmitted or stored anywhere else. This model is useful in scenarios where the key doesn’t need to be archived or exported. The second model lets the server generate the keys, returning the resulting cert and keypair as a PFXClosed A PFX file (personal information exchange format), also known as a PKCS#12 archive, is a single, password-protected certificate archive that contains both the public and matching private key and, optionally, the certificate chain. It is a common format for Windows servers./PKCS12 blob. This method is suitable when the key does need to be exported or archived, or when the client is not capable of generating a keypair itself.

There are three versions of the CertEnroll API, each with separate methods for the two enrollment variations, and up to three auxiliary methods to help formulate a successful enrollment request or perform related operations. The complete set of endpoints is given here in Table 673: CertEnroll Endpoints.

Table 673: CertEnroll Endpoints

Endpoint

Method

Description

/1/Status

GET

A synonym for GET /Status, included on this path for backwards-compatibility

/1/Templates

GET

Return a list of certificate templates available to this API application

/1/Token

GET

Retrieve a temporary authentication token to be used with an enrollment request

/1/Pkcs10

POST

Obtain a certificate by providing a CSRClosed A CSR or certificate signing request is a block of encoded text that is submitted to a CA when enrolling for a certificate. When you generate a CSR within Keyfactor Command, the matching private key for it is stored in Keyfactor Command in encrypted format and will be married with the certificate once returned from the CA., using a key generated by the client

/1/Pkcs12

POST

Obtain a certificate and private key from Keyfactor Command by providing certain certificate attributes

/2/Status

GET

A synonym for GET /Status, included on this path for backwards-compatibility

/2/Templates

GET

Return a list of certificate templates available to this API application

/2/Token

GET

Retrieve a temporary authentication token to be used with an enrollment request

/2/Pkcs10

POST

Obtain a certificate by providing a CSR, using a key generated by the client

/2/Pkcs12

POST

Obtain a certificate and private key from Keyfactor Command by providing certain certificate attributes

/3/Templates

GET

Return a list of certificate templates available to this API application

/3/Renew

POST

Obtain a new certificate based on content from an existing certificate in Keyfactor Command

/3/Pkcs10

POST

Obtain a certificate by providing a CSR, using a key generated by the client

/3/Pkcs12

POST

Obtain a certificate and private key from Keyfactor Command by providing certain certificate attributes

For historic reasons, slight differences in the templateClosed A certificate template defines the policies and rules that a CA uses when a request for a certificate is received. format necessitated differentiating the methods into a "version 1" and "version 2", with the same set of methods. Then, to allow simplification of the built-in security mechanisms, version 3 of these methods was introduced. In most cases, applications should use the CertEnrollv3 methods if taking advantage of this security mechanism (as described below) and CertEnrollv2 if not.

This Keyfactor Command API component supports an optional application authentication feature to restrict the API to selected third-party software clients. It uses a public application key and a private application secret. The application key identifies the API client application to the server and is sent as part of the HTTP headers for all enrollment endpoints. The application secret is used to compute an HMAC-SHA1 signature that is sent in an HTTP header for certain endpoints. The combination of the application key and the computed signature allows Keyfactor Command to verify the origin and the authenticity of the enrollment request. Although Basic authentication credentials are required in order to connect to the API, this allows a single user to configure different applications for different templates and have the restrictions enforced. The secret allows secure authentication and prevents attackers from attempting to replay successful enrollment requests. The calculation of this HMAC signature differs between v2 and v3 of the API. The different computations are covered in Table 674: CertEnroll Security Headers.

Another difference between v1, v2 and v3 is that v3 will import the certificate immediately and sync the row from the CA database after the certificate has been issued, whereas v1 and v2 require a manual import of the certificate after it has been issued.

Each application should have its own unique application key and secret pair embedded in the application, as well as in secure storage on the server. These keys can be registered in the API Applications section of the System Settings menu on the Keyfactor Command Management Portal. Giving each application its own key and secret pair provides these advantages:

  • An application can be restricted to request specific certificate templates and from specific CAs.
  • One application key can be disabled while leaving other application keys enabled. This allows insecure or compromised versions of an application to be disabled without affecting up-to-date users.

Table 674: CertEnroll Security Headers

Header Name

Header Value

X-CSS-CMS-AppKey

This header contains the application key assigned to this particular application. This header is a base-64-encoded string created from the key's byte sequence, and not the ASCII/UTF-8 hexadecimal representation of that byte sequence. For example, if the key is entered in the API Applications section as "030303030303030303FF", this represents the bit pattern "00000011000000110000001100000011000000110000001100000011000000110000001111111111", with base-64 encoding "AwMDAwMDAwMD/w==". In Python, this conversion can be accomplished with the following code:

        import base64

        hexKey = "030303030303030303FF"

        binKey = hexKey.decode("hex"))

        b64Key = base64.b64encode(binKey)

X-CSS-CMS-Token

This header field contains the temporary token that was previously obtained from the GET Token method. Like the application key, this header is a base-64-encoded string created from the binary form of the token, and not the ASCII/UTF-8 hexadecimal representation actually returned by the response to the GET Token. This is required for the v1 and v2 endpoints only.

X-CSS-CMS-Signature

This header field contains an HMAC-SHA-1 message signature computed from the request. Producing this signature proves that the client has access to the application secret value that is also present in the server’s configuration, that the message has been transmitted without modification, and that transmission is recent. This is required for all enrollment endpoints, although this requirement can be disabled through the application settings in the management console. The computation of this signature differs between versions; all versions are a base-64 encoding of a SHA-1 hash, but the content to be hashed varies. In general, v1 and v2 GET methods hash the URL and Token; v1 and v2 POST methods hash the URL, Token, and request body; v3 GET methods do not require a signature; and v3 POST methods hash the request body only. The computation of HMAC signatures is significantly easier for v3 methods. Sample Python code is included in Table 675: CertEnroll HMAC computations in Python for each computation type.

Table 675: CertEnroll HMAC computations in Python

Endpoints

Signature

GET Templates (v1 and v2)

token = json.loads(GET_Token_ResponseBody)["SessionTokenValue"]

URLPath = "/CMSApi/CertEnroll/2/Templates"

requestDataString = URLPath + token;

appSecretBytes = appSecretString.decode("hex")

signature = hmac.new(appSecretBytes, requestDataString, hashlib.sha1).hexdigest();

headers["X-CSS-CMS-Signature"] = base64.b64encode(signature.decode("hex"));

POST /1/Pkcs10, /1/Pkcs12, /2/Pkcs10, /2/Pkcs12

token = json.loads(GET_Token_ResponseBody)["SessionTokenValue"]

URLPath = "/CMSApi/CertEnroll/2/Pkcs12"

body=‘{"Flags":0,"TemplateName":"User","Pkcs12Password":"lily1234","SubjectNameAttributes":null}’

Note:  For these methods, the body must be formatted exactly as above, as far as parameterClosed A parameter or argument is a value that is passed into a function in an application. order, capitalization, and whitespace. This is one reason v3 signatures are easier to use.

requestDataString = URLPath + token + body

appSecretBytes = appSecretString.decode("hex")

signature = hmac.new(appSecretBytes, requestDataString, hashlib.sha1).hexdigest();

headers["X-CSS-CMS-Signature"] = base64.b64encode(signature.decode("hex"));

POST /3/Pkcs10 and /3/Pkcs12

data=‘{"Flags":0,"TemplateName":"User","Pkcs12Password":"lily1234","SubjectNameAttributes":null}’

body = ‘{"Timestamp" : "’ + datetime.datetime.utcnow().isoformat()+ ‘", "Request" : ‘ + data + ‘}’

Note:  For these methods, the request can be formatted in any equivalent json format without regard to capitalization, whitespace, or order of elements. This is one reason v3 signatures are easier to use.

appSecretBytes = appSecretString.decode("hex")

signature = hmac.new(appSecretBytes, body, hashlib.sha1).hexdigest();

headers["X-CSS-CMS-Signature"] = base64.b64encode(signature.decode("hex"));