PKI 10.4 CMC Feature Update (RFC5272)

From Dogtag
Jump to: navigation, search

Contents

Overview

Prior to Dogtag 10.4, CMC implementation was based on a subset of rfc2797, released in 2000, while the most current RFC (5272 with update from RFC 6402) was dated 2011. The only means of authentication for CMC requests was the CMCAuth authentication plugin, which only allows a CA agent to pre-sign a CMC request. The only form of proof of possession is by the nature of PKCS#10 CSR signature or CRMF POP control, both of which require the private key to be capable of signing.

In 10.4, our goal was to try to fill the fairly large gap by adding the missing and updating the outdated features to conform to RFC 5272 with update from RFC 6402.

This document describes how this release provides the following tighter security and better versatility:

  • Proof of Identity (or Proof of Origin) for non-agent users
  • Proof of Possession (POP) - proving that the enrollment initiator (subscriber) possesses the private key that pairs with the public key in the request
  • link between the identity and the POP - in this case, a control that contains data generated from the shared-secret between the server and the initiator is signed into the POP.
  • Various enrollment and renewal conditions
  • Appropriate auditing.

Design

For 10.4, the CMC certificate request mechanism has been updated to conform to RFC 5272 with update from RFC 6402. It does so by adding the following cmc features.

Proof of Origin, Proof of Possession, and Id-POP linking for non-agent users

  • CMC Identity proof by signing with another cert owned by the same entity- If a subscriber already possesses a signing cert, the individual can just use the signing cert to sign another cmc request (this applies to enrollment, renewal, as well as revocation requests). Upon receiving a request, CA will verify the signature (as identity proof), verify the POP, and verify whether the signer matches with the request subject before issuance. Note that when this form of identity proof is provided, the identity proof control(v1 and v2), if exists in the cmc request, will be bypassed.
    • This signing verification effectively proves the identity based on previously proven (the fact the valid signing cert exists and signs) identity.
    • uses SignerIdentifier.ISSUER_AND_SERIALNUMBER support per rfc
    • The new enrollment profile used with this method is caFullCMCUserSignedCert.cfg where cmcUserSignedSubjectNameDefault and cmcUserSignedSubjectNameConstraint are used to ensure that the resulting certificate has matching subject name as that of the signing certificate.
    • For renewal, uniqueKeyConstraint has the configuration parameter “allowSameKeyRenewal” to control whether same key renewal is allowed or not (revoked certs cannot be renewed); renewGracePeriodConstraint can be used to control how long before or after expiration date can a cert be renewed.
  • CMC Identity Proof V2 - This control requires administrator to generate and distribute a shared secret to the subscriber before each enrollment; When the subscriber generates a certificate request, the shared secret is used to compute a witness value that the server could verify with. For efficiency, the implementation requires the identification control to be used in combination with the identity prof v2 control. By default, the SharedToken plugin that retrieves the shared secret uses subscriber’s ldap uid. Upon receipt of the certificate request, if the cmc request is not signed by a valid subscriber certificate (as per described in the previous bullet), CA will retrieve the shared secret associated with the identification provided in the request and compute the witness value to compare with the witness value in the request. Note: It is intended to be used when the subscriber does not already have a signing cert. In the case one already has a signing cert, the above signing method could be used instead for efficiency (no need for distributing shared secrets)
    • This control effectively provides the Proof of Origin based on the secret that can only be shared between CA and the intended subscriber.
    • CMC controls added:
      • id-cmc-identityProofV2 - corresponding CMCRequest parameter e.g.:
        • identityProofV2.enable=true
        • identityProofV2.hashAlg=SHA-512
        • identityProofV2.macAlg=SHA-256-HMAC
      • id-cmc-identification - corresponding CMCRequest parameter e.g.:
        • identification.enable=true
        • identification=testUser
    • added SignerIdentifier.SUBJECT_KEY_IDENTIFIER support per rfc
      • The enrollment profile to be used with this method is caFullCMCSelfSignedCert.cfg
  • CMC Encrypted POP and Decrypted POP - Since encryption-only keys cannot do the signing operation required for the proof of possession required before this release, new controls are implemented to allow that. In this release, if a signing POP is not present in the certificate request, CA will assume that it is an encryption-only key. CA will generate a challenge and encrypt it with the subscriber public key in the request. CA will then compute and place all necessary information in the request record and construct an EncryptedPOP along with a failed response with the requestId in the responseInfo control back to the client. Client can process the EncryptedPOP, decrypt and retrieve the challenge, compute the witness value and construct a DecryptedPOP requestID in the regInfo control and send back to the server. CA will then use the requestId embedded in the DecryptedPOP to find the pending request, retrieve all the POP-related info, recompute and compare/varify the witness value before issuance.
    • This control effectively provides the Proof of Possession (POP) for encryption-only keys based on the fact that only the subscriber that possesses the matching private key of the request public key can decrypt the challenge and compute the witness.
    • controls added:
      • id-cmc-encryptedPOP
      • id-cmc-decryptedPOP
      • id-cmc-responseInfo
      • id-cmc-regInfo
  • CMC POP Link Witness V2 - In the case when Proof of Identity and Proof of Possession are verified, there is still no proof that the identity proven in the Proof of Identity is the same identity that owns the private key in the Proof of Possession. The POP Link Witness V2 provides such proof by making sure that a shared secret associated with an identity is used to compute a witness value which in turns is placed in the underlying (CRMF or PKCS#10) request. This release requires the identification control to be used in combination with this control so that CA can find the sharedSecret more efficiently.
    • This control effectively provides the link between the Proof of identity and the POP.
    • control added: id-cmc-popLinkWitnessV2
    • control used: id_cmc_idPOPLinkRandom
  • TLS client authentication enforcement for user-signed CMC requests (enrollment & revocation), where the authenticating TLS client certificate must match that of the CMC request signing certificate. This means, for HttpClient the condig file will need the following:
    • secure=true
    • clientMode=true
    • nickname=<cert nickname that matches the cmc request signer's>

New (CMC UserSigned / SelfSigned) Authentication Plugin

As mentioned above, prior to this release, CMCAuth was the only method of CMC authentication. It requires a CA agent to sign the requests. In 10.4, CMCUserSignedAuth has been introduced to handle:

  • Requests that are self-signed (signed with private key of the request itself) -- via SignerIdentifier SUBJECT_KEY_IDENTIFIER
    • This is normally used to obtain user's first certificate (a signing cert), which would later be used to obtain other type of certificates.
    • Again, this has to be combined with the Identity Proof (v2) control for proof of origin.
    • Both CRMFPopClient and PKCS10Client have been updated to handle the “-y” option for self-signed requests.
  • Requests signed by non-privileged users -- via SignerIdentifier ISSUER_AND_SERIALNUMBER
    • This can only be used when the user already obtained a signing certificate so that it can be used to prove its identity for other certificates.

Here is an example that shows a profile that requires authentication through CMCUserSignedAuth (user-signed)

auth.instance_id=CMCUserSignedAuth

The new profiles that has this authentication by default are :

  • caFullCMCUserSignedCert
  • caFullCMCSelfSignedCert

Here is an example that shows a profile that requires authentication through CMCAuth (agent-signed)

auth.instance_id=CMCAuth

New Enrollment/Renewal Profiles and corresponding URIs

10.5 update

In the 10.5, profileSubmitCMCFull servlet has been updated so that profile id can be specified. This provides flexible profile specification without having to add new URI's as in the following "10.4" section.

Here is an example from HttpClient configuration file:

servlet=/ca/ee/ca/profileSubmitCMCFull?profileId=caFullCMCUserSignedCert

where we expect the CMCUserSignedAuth authentication plugin to be specified in the profile caFullCMCUserSignedCert.cfg:

auth.instance_id=CMCUserSignedAuth

Some examples in the Examples section will use this method, and will be labeled for ease of distinction.

Note: I think the URIs in the "10.4" section still work at time of this writing, but one should try to use the new method described above.

10.4

Prior to 10.4, the accessing URI to CMC requests is /ee/ca/profileSubmitCMCFull, which would lead to the enrollment profile caFullCMCUserCert.cfg, where authentication instance CMCAuth is specified. As discussed before, that is an agent-only authentication.

In this release, for non-agent approved cmc enrollment, two new accessing URI are introduced, each would lead to a new enrollment profile:

  • /ee/ca/profileSubmitUserSignedCMCFull ==> caFullCMCUserSignedCert.cfg
    • As the name implied, this is the case when a user already has a valid signing certificate, which is used to sign other cmc certificate requests.
    • This is the same access point for renewals.
    • Profile caFullCMCUserSignedCert.cfg by default contains the following relevant profile default/constraints:
      • CmcUserSignedSubjectNameDefault / CmcUserSignedSubjectNameConstraint - to ensure that the new certificate will contain the same subject name as that of the signing certificate
      • UniqueKeyConstraint - provides control for whether same key renewal is allowed or not; It searches for the newest cert in the repository with the same key to renew if allowed. Revoked certificates are not renewable.
      • RenewGracePeriodConstraint - allows for control of renewal grace period in case of same key renewals. Rekey renewal would not be able to use this as it would be treated as new enrollment.
  • /ee/ca/profileSubmitSelfSignedCMCFull ==> caFullCMCSelfSignedCert.cfg
    • As the name implied, this is the case when a user does not already have a valid signing certificate, so it's self-signed, and Identity Proof (v2) control would be needed to complete the proof of origin.

For system certificates using cmc enrollment, the following new accessing URIs are introduced, each would lead to a new enrollment profile:

  • /ee/ca/profileSubmitCMCFullCACert ==> caCMCcaCert.cfg
  • /ee/ca/profileSubmitCMCFullServerCert ==> caCMCserverCert.cfg
  • /ee/ca/profileSubmitCMCFullSubsystemCert ==> caCMCsubsystemCert.cfg
  • /ee/ca/profileSubmitCMCFullOCSPCert ==> caCMCocspCert.cfg
  • /ee/ca/profileSubmitCMCFullAuditSigningCert ==> caCMCauditSigningCert.cfg
  • /ee/ca/profileSubmitCMCFullKRAstorageCert ==> caCMCkraStorageCert.cfg
  • /ee/ca/profileSubmitCMCFullKRAtransportCert ==> caCMCkraTransportCert.cfg

Configuration

The following are cmc-related configuration parameters in the CA's CS.cfg (with defaults displayed)

cmc.popLinkWitnessRequired=false
cmc.token=internal

cert.issuance_protection.nickname=cmcIssuanceProtectionCert
  • cmc.popLinkWitnessRequired - This requires sharedSecret; By default it is "false"; Replace with "true" to turn it on
    • note: see "cmc.sharedSecret" below
  • cmc.revokeCert.sharedSecret.class - (to be implemented) - 10.5 update: implemented. See http://pki.fedoraproject.org/wiki/PKI_10.5_CMC_Shared_Token
    • note: before the sharedSecret class is implemented, this parameter is removed from the default CS.cfg at installation
    • for testing purposes, "mock SharedSecret plugin" can be added in CS.cfg, but be sure to remove it for production:
      • cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
  • cmc.sharedSecret.class (to be implemented) - 10.5 update: implemented. See http://pki.fedoraproject.org/wiki/PKI_10.5_CMC_Shared_Token
    • note: before the sharedSecret class is implemented, this parameter is removed from the default CS.cfg at installation
    • for testing purposes, "mock SharedSecret plugin" can be added in CS.cfg, but be sure to remove it for production:
      • cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
  • cmc.token - This is the token name that should matches with the token where the CA's subsystem certificate(and keys) reside.
  • cert.issuance_protection.nickname - Contains the nickname of the Issuance Protection certificate used for PoP related encryption; By default, when this parameter is not set, the subsystem certificate specified in cert.subsystem.nickname is used.

Client changes

The following clients have been updated to support the new CMC features:

  • CRMFPopClient
    • a "-y" option has been added to support self-sign, where a subjectKeyIdentifier extension is required by the RFC to be present in the request
    • private key id is printed in output for use in needed CMC controls
    • due to limitation of HSM, if KRA is employs HSM, CRMFPopClient should be run with the following option:
      • -w "AES/CBC/PKCS5Padding".
  • PKCS10Client
    • a "-y" option has been added to support self-sign, where a subjectKeyIdentifier extension is required by the RFC to be present in the request
    • private key id is printed in output for use in needed CMC controls
  • CMCRequest (for more information: "man CMCRequest")
    • identityProofV2 - prove identity in self-signed case
      • identityProofV2.enable - true to enable, false otherwise.
      • identityProofV2.hashAlg - supported values are: SHA-1, SHA-256, SHA-384, and SHA-512
      • identityProofV2.macAlg - supported values are: SHA-1-HMAC, SHA-256-HMAC, SHA-384-HMAC, and SHA-512-HMAC
    • witness - Used for identityProofV2 and popLinkWitnessV2
      • witness.sharedSecret - value must match what's stored with CA;
    • request.selfSign - true is self-sign, false otherwise
    • request.privKeyId - used for the case of self-sign or popLinkWitnessV2
    • identification - Used for identityProofV2 and popLinkWitnessV2
      • identification.enable - true will add id-cmc-identification control, false otherwise
      • identification - value must match what CA knows;
    • popLinkWitnessV2 - used to link identity with POP
      • popLinkWitnessV2.enable - true to enable, flase otherwise
      • popLinkWitnessV2.keyGenAlg - supported values are: SHA-1, SHA-256, SHA-384, and SHA-512
      • popLinkWitnessV2.macAlg - supported values are: SHA-1-HMAC, SHA-256-HMAC, SHA-384-HMAC, and SHA-512-HMAC
    • DecryptedPOP -used after EncryptedPop is received after round-1, where round-1 being a CMC request without POP
      • decryptedPop.enable - true enabled, false otherwise
      • encryptedPopResponseFile - input file from the output of round-1 in case of success
      • decryptedPopRequestFile - output file
  • CMCResponse (for more information: "man CMCResponse")
    • modified to handle EncryptedPOP; no new options;
Note: clients that are not listed above have not been updated to support the newest CMC features.
  • (New in 10.5) CMCSharedToken (for more information: "man CMCSharedToken")
    • new tool to process a user passphrase and create shared token to be stored by the CA to allow Shared Secret-based proof of origin in cases such as CMC certificate issuance and revocation.

Tips: If CA's system keys are on an HSM, Two things to keep in mind

  • CRMFPopClient should be used with the "-y false"
  • CA's CS.cfg should have the "cmc.token" parameter set to the HSM token

Revocation

In RFC5272, CMC revocation requests are done with the id-cmc-revokeRequest control. In releases prior to Dogtag 10.4, there appear to be two ways intended for submitting a CMC revocation request.

  • One is via ca/ee/ca/CMCRevReq.html, which would lead into backend servlet CMCRevReqServlet.java and authenticate the CMC signer using the above-mentioned agent authentication method, CMCAuth.
    • This provision is provided at the CA ee portal "CMC Revoke" tab.
    • This method is actually in violation with the https://tools.ietf.org/html/rfc5273 CMC Transport Protocols, as for HTTP/HTTPS, the body of the message is the binary value of the BER encoding of the PKI Request or Response, so HTML is not an approved method.
  • The other method follows the same path as the CMC requests described above by submitting directly to the /ca/ee/ca/profileSubmitCMCFull servlet, where it is authenticated with the agent authenticator CMCAuth. While in terms of CMC Protocol (RFC 5273) it is conforming, it is limited to agent authentication, much like CMC enrollment requests prior to the 10.4 release.
Note: The second method described above had not been maintained or tested so it appears not to work prior to this release.  It is unclear when it was broken, but the intent is to fix it for this release and add the additional feature below.

In this release, we will add revocation handling to the new /ca/ee/ca/profileSubmitUserSignedCMCFull servlet with the method 2 described above so that a user with matching subjectdn can sign its own revocation requests.

Shared Secret

Update: this feature has been implemented and documented here: http://pki.fedoraproject.org/wiki/PKI_10.5_CMC_Shared_Token

Note, this area has not yet been implemented at time of writing.  Please consider this a high-level design.

In prior releases, areas where “shared secrets” are needed were done with a dummy class SharedSecret, which implements ISharedToken, where a hardcoded string “testing” was returned. In this release, a real class will be written to respond to the “getSharedToken(...)” method of the ISharedToken class. CMC features that will take advantage of the new ISharedToken class include:

  • IdentifyProofV2
  • popLinkWitnessV2
  • revokeRequest

Framework

RFC5272 does not dictate how the shared secret provision should be implemented. For 10.4, while we will provide a default implementation, we will continue the tradition of allowing the flexibility for sites to implement their own mechanism by making the shared secret provision a Java Plugin framework, much like how the existing authentication, authorization, and many other mechanisms are provided in the current system.

Repository

By default, we use CA’s internal ldap repository for storing uid/sharedToken information. The ldap instance will be configurable so that an external ldap system could be used. The configuration will be much like like ldap-based authentication plugin is configured.

Protection

Like many other areas that require protection of the directory entries, mechanism much like the KRA’s key archival/recovery mechanism will be used to encrypt/decrypt the shared secrets stored in the repository. The mechanism involves generation of a symmetric key that is used to encrypt the shared secrete, a system-wide certificate that is used to encrypt the per-entry symmetric key. Each repository entry will contain at the minimum (userID, symm-encrypted-sharedSecret, system-cert-encrypted-symm). Retrieval of the entry is based on the usrID provided through the relevant CMC requests id_cmc_identification control.

One-Time Use Provision

One-Time use can be configured so that sites can choose to disallow a shared secret being reused.

Set Up

In the first release of this implementation, administrators are expected to:

  • use auxiliary mechanism to generate the shared secrets
  • Use any ldap mechanisms to store the secret into corresponding user entries
    • this could be done by enhancing pki-user
  • Use any site-approved method to communicate the shared secrets to their intended users.

Future

In the future, we should improve on usability.

Notes

A couple notes:

  • Auditing have been added (not finalized - TBD)
  • CMC controls not mentioned should continue to function as was before

Certificate Issuance User Workflow

This section gives users a high-level walk through of the certificate issuance process. It is recommended that you read this section first before looking at the Examples sections below.

Getting a certificate issuance using CMC involves the following steps:

  1. Generating a PKCS#10 or CRMF certificate signing request (CSR) - This can be done using any available tools such as PKCS10Client or CRMFPopClient provided by the Dogtag pki-tools package, or openssl, etc.
    1. note that if key archival is desired and KRA is set up to do so, one would want to use CRMFPopClient with KRA's transport certificate in PEM format set in the kra.transport file to do that.
  2. Transforming the CSR from step 1 into CMC request - This involves running CMCRequest (provided by the Dogtag pki-tools package) over the CSR generated from the above step to generate a CMC request. Note that CMCRequest takes a configuration file where the "input" should point to the CSR and "format" should be either pkcs10 or crmf. There are many options to fine tune the resulting CMC request. Please run "man CMCRequest" at command line to see the instruction, then look at examples in the following sections.
  3. Sending the resulting CMC request from step 2 to the CA - This involves running HttpClient over the CMC request generated from step 2 above and sending to the issuing CA. Note that HttpClient takes a configuration file where the "input" should point to the CMC request generated in step 2 above. The result of HttpClient will be in the file pointed to by the "output" parameter. Please run HttpClient at command line to see the instruction, then look at examples in the following sections. The result of running HttpClient, if successful, should be a PKCS #7 chain with CMCStatus controls;
  4. Checking the issuance result (optional, but recommended) - This involves running CMCResponse over the output from step 3 above to interpret the CMCStatus and if successful, present the cert chain in human readable form to the user.
  5. Importing the new certificate - There are many ways to do so. For a user certificate, you could use tools such as certutil to import the output PKCS #7 chain from step 3 above; for servers, you might be running some installation tool such as pkispawn from Dogtag. Follow the instruction from whichever application that you are running to import the certificate. Keep in mind that the certificate chain is in PKCS #7 data format. Some application might be expecting Base64 encoding, in which case, you would want to transform that by running BtoA, and some application might expect header and footer for PEM format, then you need to add that as well.
Note: in case when POP is missing (as in the case of encryption-only keys), you need to follow the EncryptedPOP DecryptedPOP example below to complete the enrollment.
      In which case, HttpClient would receive an EncryptedPOP CMCStatus (you would see that by running CMCResponse in step 4), and you will need to go run CMCRequest
      again with a different set of parameters for it's config.  Please see example below for details.

Practical Usage Scenarios

(Work in Progress)

This section depicts the most practical usage scenarios to assist CA administrators in deciding which CMC method to go with which situation.

Obtaining System/Server Certificates

When a TLS server (web server, ldap server, Dogtag subsystems, etc.) needs a TLS server certificate, the administrator of the said server should follow the instruction from the respective server to generate a CSR (generally in PKCS#10). The CSR then can be sent to a CA's agent for approval.

System/Server certificate issuance should require agent approval. It is therefore strongly advised that each of the following categories are being met.

  • Enrollment Profiles
    • One should use either one of the existing CMC system/server profiles or create a custom profile that employs the CMCAuth authentication mechanism. i.e. the profile should contain:
      • auth.instance_id=CMCAuth
  • CMC Signing Certificate
    • A CA agent should generate and sign the CMC request. This is done by specifying the nickname value in the CMCRequest configuration file as one of the CA agents. Note that only the CA agent should have access to his/her own private key so the CMC request generation itself should be done by the CA agent. The generation of the PKCS#10 CSR should normally be done by the requesting system/server's administrator. Note: System/server CSRs are normally in the format of PKCS#10.
  • HttpClient SSL Client nickname
    • This should be the same agent certificate, so should be done by the same CA agent.
  • Other Useful Information
    • When an agent pre-signs a CSR, the Proof of Identification is considered established. As the agent is expected to have examined the CSR for identification. No additional CMC-specific identification proof is needed.
    • PKCS#10 by itself already provides Proof of Origin, so no additional POP is needed.
    • popLinkWitness(v2) should in general be bypassed in agent pre-approved requests because the identification is checked out-of-band by the agent. Plus, the establishment of popLinkWitness(v2) would require shared token being set up , which adds unnecessary complication and redundancy to what the agent would have done.

Examples

Obtaining First User Signing Certificate

there are two ways to approve a user's first signing certificate:

  1. Signing CMC request with an Agent Certificate
  2. Authenticating for Certificate Enrollment with a Shared Secret

Signing CMC request with an Agent Certificate

In this case, user generates a CSR (with tools such as PKCS10Client or CRMFPopClient) and sends to a CA agent for approval. This is no different than the "Obtaining System/Server Certificates" case above. Please see the section for information.

Upon receiving the CSR (PKCS#10 or CRMF), CA agent runs CMCRequest tool to generate a CMC request, then HttpClient to submit the request.

When certificate is issued successfully, user can import the certificate into the token where the initial keys were generated for the CSR.

Example

PKI_10.4_CMC_Feature_Update_(RFC5272)#Agent-signed_CMC_requests_Example

Authenticating for Certificate Enrollment with a Shared Secret

In the case when user-initiated enrollment is desired (e.g. in case when agent pre-approval is not practical), getting the first user signing certificate should be the first step for such automation for the reason that once the first signing cert is obtained, it can be used to sign other certificates for the same user.

In this scenario, the CMC Shared Secret mechanism could be employed to carry out the Proof of Origin. The workflow would be like the following:

  • Generating a shared token (man CMCSharedToken)
    • this could be done either by the user (preferred) or by the CA administrator
      • If done by the user, then the token generated from CMCSharedToken needs to be snet to the CA administrator
      • Note: the "token" generated from CMCSharedToken is encrypted; Only the user who generates the token knows the actual "secret" or "passphrase." Therefore this method is more secure.
      • If done by the administrator, then the shared secret (the actual "secret" or "passphrase") needs to be distributed to the intended user
        • extra caution will need to be taken so that the shared secret is not disclosed (how distribution is done is outside the scope of this software)
      • The user is not the only person that knows about the "secret" or "passphrase" in this scenario.
  • Storing the shared token into user's ldap record
    • Once the CA administrator has the encrypted shared token, instruction should be followed to enter the value into the user's ldap record.
  • User follows instruction for using shared secret to obtain his/her first signing certificate.
  • Other Useful Information
    • Since Shared Token is required, the following CMCRequest configuration parameters are required:
      • identification[.enable]
      • witness.sharedSecret
      • identityProofV2.[enable, hashAlg, macAlg]
      • request.selfSign
      • request.privKeyId
    • Optionally, if required by the CA, the following CMCRequest configuration parameters could be used
      • popLinkWitnessV2.[enable, keyGenAlg, macAlg]

Examples

Note: setup procedure is needed before the Shared Secret feature can be exercised.

Obtaining User Encryption-only Certificate

If a user is expected to possess multiple certificates with different usages, where one being signing, then signing certificate should be obtained via the procedure documented in Obtaining First User Signing Certificate section above. This is so that once a user owns a signing certificate, it can be used to achieve Proof Of Origin without the hassle of having to set up and rely on the CMC Shared Secret mechanism.

The following is the workflow for getting an encryption-only certificate by signing with an existing user signing certificate.

  • User: make sure the signing cert/keys are in user crypto token (e.g. nssdb or smartcard)
  • User: generate PKCS#10 or CRMF requests (possibly depending on site policy on whether key archival is required)
  • User: generate CMC request
    • Since this is an encryption-only certificate, the private key would not be able to sign, hence POP will not be included; This would cause EncryptedPOP/DecryptedPOP to happen (two trips).
      • First trip:
        • The following are the key first-trip CMCRequest configuration parameters (man CMCRequest for detail), aside from the basic paramsters:
          • identification[.enable]
          • witness.sharedSecret
          • identityProofV2.[enable, hashAlg, macAlg]
          • popLinkWitnessV2.[enable, keyGenAlg, macAlg] (if required by CA)
          • request.privKeyId
        • Response will contain
          • CMC encrypted POP control
          • CMCStatusInfoV2 with "POP required" failInfo
          • CMC ResponseInfo with requestID
      • Second trip:
        • The following are the key second-trip CMCRequest configuration parameters (man CMCRequest for detail), aside from the basic paramsters:
          • decryptedPop.enable
          • encryptedPopResponseFile
          • decryptedPopRequestFile
          • request.privKeyId

Example

#User-signed_CMC_request_Without_POP_.28Encrypted_POP_.2F_Decrypted_POP.29

Revocatoin

Revocation can either be done in two ways:

  • User Signed
  • Shared Token based

Revocation - User Signed

Example

#CMC_Revocation_Request_.28User-signed.29

Revocation - Shared Token based

Example

PKI_10.5_CMC_Shared_Token#Example_Revocation_Procedure

Examples (User Certificates -RSA)

Note: It is highly recommended that you read the "Certificate Issuance User Workflow" section above first before following the examples in this section.
Note: Audit events shown in the examples are for information only; They are not finalized at the point of this writing.

User-signed CMC requests Example (with PopLinkWitnessV2)

This example demonstrates a cmc request signed by an existing (non-privileged) user signing certificate. This example also demonstrates PopLinkWitnessV2 control.

  • Enroll for a user signing cert (use any working mechanism is fine), and import into your test nssdb.
    • In my test nssdb, I have a user signing cert
      • nickname “ladyCfu cert”
      • Subject dn “CN=Lady Christina Fu,UID=cfu”
      • This user signing cert will be the existing user signing cert used for signing other CMC requests for certs belong to the same user
  • Generate a cert request (pkcs10 or crmf)
> PKCS10Client -d . -p netscape -n "cn=just me cfu, uid=cfu" -o pkcs10.req
PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: -3ee22f9ba039c9c4b65f8512beea7b009b730e9d

-----BEGIN CERTIFICATE REQUEST-----
MIICcDCCAVgCAQAwKzETMBEGCgmSJomT8ixkAQEMA2NmdTEUMBIGA1UEAwwLanVzdCBtZSBjZnUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: pkcs10.req
  • Edit CMCRequest cfg file so that
    • the nickname contains the user signing cert instead of admin cert
    • make sure identityProofV2.enable=false
    • make sure request.privKey contains the matching "private key id" from the csr generation above
    • see cmc config file: cmc-p10-user-signed.cfg
> CMCRequest cmc-p10-user-signed.cfg
cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: lady cfu cert
got request privKeyId: -3ee22f9ba039c9c4b65f8512beea7b009b730e9d
got private key
createPKIData: begins
createPopLinkWitnessV2Attr: begins
createPopLinkWitnessV2Attr: keyGenAlg=SHA-256; macAlg=SHA-256-HMAC
createPopLinkWitnessV2Attr: Successfully created id_cmc_idPOPLinkRandom control. bpid = 1
createPopLinkWitnessV2Attr: Successfully created PopLinkWitnessV2 control.
createPopLinkWitnessV2Attr: returning...

k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
createPKIData: popLinkWitnessV2 enabled. reconstructing pkcs#10
createPKIData:  new pkcs#10 Attribute created for id_cmc_popLinkWitnessV2.
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createPKIData:  new pkcs#10 CertificationRequestInfo created.
createPKIData: new pkcs#10 CertificationRequest created.
createPKIData: calling Utils.b64encode.
createPKIData: new PKCS#10 b64encode completes.
-----BEGIN CERTIFICATE REQUEST-----
MIICuzCCAaMCAQAwKzETMBEGCgmSJomT8ixkAQEMA2NmdTEUMBIGA1UEAwwLanVz
<snip>
-----END CERTIFICATE REQUEST-----

identification control: identification =testuser
Successfully create identification control. bpid = 2

selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins

The CMC enrollment request in base-64 encoded format:

MIINKQYJKoZIhvcNAQcCoIINGjCCDRYCAQMxDzANBglghkgBZQMEAgEFADCCA1QG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.pkcs10.req.
  • Submit the cmc request
    • Make sure clientmode=true
    • Make sure nickname=<the certificate that has a subject matching that of the cmc request signer>
    • Make sure HttpClient config file “servlet” points to servlet=/ca/ee/ca/profileSubmitUserSignedCMCFull
    • see HttpClient config file: HttpClient-cmc-p10-user-signed.cfg
> HttpClient HttpClient-cmc-p10-user-signed.cfg

Total number of bytes read = 3373
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
Total number of bytes read = 2568
MIIKBAYJKoZIhvcNAQcCoIIJ9TCCCfECAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.pkcs10Resp
  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
    • At the end of the CMCResponse call below, observe that
      • the CMCResponse has a SUCCESS status
      • the new cert was really issued
      • the new cert bears the same subject as that of the user signing cert (NOT what’s specified in the initial pkcs10 request)
      • If key archival is set up, check that key is archived (only available if the underlying request is CRMF)
      • Check relevant audit messages in audit log (e.g.) TBD
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=y.y.y.y][ServerIP=x.x.x.x[SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success] access session establish success
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][ReqType=enrollment][CertSubject=CN=just me cfu,UID=cfu][SignerInfo=Signer Christina Fu] User signed CMC request signature verification success
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=AUTH_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][AuthMgr=CMCUserSignedAuth] authentication success
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=CMC_ID_POP_LINK_WITNESS][SubjectID=Signer Christina Fu][Outcome=Success][Info=EnrollProfile: parseCMC: : ident_s=testuser] Identification Proof of Possession linking witness verification
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=Signer Christina Fu][Outcome=Success][Info=method=EnrollProfile: fillTaggedRequest: ] proof of possession
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=83][ProfileID=caFullCMCUserSignedCert][CertSubject=CN=Signer Christina Fu,UID=cfu,OU=self-signed] certificate request made with certificate profiles
0.http-bio-8443-exec-1 - [14/Jun/2017:10:06:59 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=83][CertSerialNum=43] certificate request processed
> CMCResponse -d . -i /root/cfu/test/cmc/cmc.pkcs10Resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x17
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, May 24, 2017 2:56:47 PM PDT America/Los_Angeles
                Not  After: Monday, November 20, 2017 2:56:47 PM PST America/Los_Angeles
            Subject: CN=Lady Christina Fu,UID=cfu,OU=self-signed
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   Status: SUCCESS
  • Import the new certificate
> certutil -d . -A -t "u,u,u" -n "new lady cfu cert" -i cmc.pkcs10Resp

Self-Signed CMC Request Example (with IdentityProofV2)

This example demonstrates a cmc request signed by the paring private key of that of the certificate request. It also demonstrates IdentityProofV2, which is required in the self-sign case.

  • Generate a cert request (pkcs10 or crmf. Though in case of PKCS10Client, "-y true" is needed instead of just "-y")
    • Note: the following CRMFPopClient example assumes that kra.transport contains the KRA's transport certificate in PEM format to achieve key archival.
> CRMFPopClient -d . -p netscape -n "cn=Christina Fu, uid=cfu" -q POP_SUCCESS -b kra.transport -y -v -o crmf.req
Initializing security database: .
Loading transport certificate
Parsing subject DN
RDN: OU=self-signed
RDN: UID=cfu
RDN: CN=Lady Christina Fu
Generating key pair
Keypair private key id: -32cdd65ab08ae3ed35ae529c1e3c8ca5cb3b776e
Creating certificate request
CRMFPopClient: self_sign true. Generating SubjectKeyIdentifier extension.
CryptoUtil: createKeyIdentifier: begins
Creating signer
Creating POP
Creating CRMF request
Storing CRMF requrest into crmf.self.req

  • Edit CMCRequest cfg file so that
    • make sure request.selfSign=true
    • make sure identityProofV2.enable=true
    • make sure identification.enable=true
    • make sure request.privKey contains the matching "private key id" from the csr generation above
    • see cmc config file: cmc-crmf-self.cfg
> CMCRequest cmc-crmf-self.cfg
cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got request privKeyId: -32cdd65ab08ae3ed35ae529c1e3c8ca5cb3b776e
got private key
createPKIData: begins
createPopLinkWitnessV2Attr: begins
createPopLinkWitnessV2Attr: keyGenAlg=SHA-256; macAlg=SHA-256-HMAC
createPopLinkWitnessV2Attr: Successfully created id_cmc_idPOPLinkRandom control. bpid = 1
createPopLinkWitnessV2Attr: Successfully created PopLinkWitnessV2 control.
createPopLinkWitnessV2Attr: returning...

k=0
createPKIData:  format: crmf
CryptoUtil: getSKIExtensionFromCertTemplate: checking extension in request:{2 5 29 14}
CryptoUtil: getSKIExtensionFromCertTemplate: extension found
createPKIData:  SubjectKeyIdentifier extension found in self-signed request
createPKIData: popLinkWitnessV2 enabled. reconstructing crmf
createNewPOP: begins
createNewPOP: about to create POPOSigningKey
createNewPOP: creating and returning newPopOfSigningKey
createPKIData: new CRMF b64encode completes.
-----BEGIN CERTIFICATE REQUEST-----
MIIJFzCCCRMwggf3AgEBMIIBk4ABAqVJMEcxFDASBgNVBAsTC3NlbGYtc2lnbmVk
<snip>
-----END CERTIFICATE REQUEST-----

identification control: identification =testuser
Successfully create identification control. bpid = 1

CMCRequest: addIdentityProofV2Attr: hashAlg=SHA-512; macAlg=SHA-256-HMAC
Identity Proof V2 control: 
   Value: -106 -107 45 -39 120 22 -104 103 -50 127 32 4 -58 84 28 92 107 -69 -112 -71 -57 -26 34 -125 97 -78 -54 -24 -76 87 4 -9 
Successfully create identityProofV2 control. bpid = 2

selfSign is true...
signData for selfSign: begins: 
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
getCMCBlob: begins

The CMC enrollment request in base-64 encoded format:

MIILsAYJKoZIhvcNAQcCoIILoTCCC50CAQMxDzANBglghkgBZQMEAgEFADCCCfQG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.self.req.
  • Submit the cmc request
    • Make sure HttpClient config file “servlet” points to servlet=/ca/ee/ca/profileSubmitSelfSignedCMCFull
    • see HttpClient config file: HttpClient-cmc-crmf.self.cfg
> HttpClient HttpClient-cmc-crmf.self.cfg

Total number of bytes read = 2996
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
Total number of bytes read = 2568
MIIKBAYJKoZIhvcNAQcCoIIJ9TCCCfECAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.self.Resp
  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
    • At the end of the CMCResponse call below, observe that
      • the CMCResponse has a SUCCESS status
      • the new cert was really issued
      • If key archival is set up, check that key is archived (only available if the underlying request is CRMF)
      • Check relevant audit messages in audit log (e.g.) TBD
0.http-bio-8443-exec-2 - [24/May/2017:16:21:23 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=$NonRoleUser$][Outcome=Success][ReqType=enrollment][CertSubject=OU=self-signed, , CN=Lady Christina Fu][SignerInfo=selfSigned] User signed CMC request signature verification success
0.http-bio-8443-exec-2 - [24/May/2017:16:21:23 PDT] [14] [6] [AuditEvent=CMC_PROOF_OF_IDENTIFICATION][SubjectID=testuser][Outcome=Success][Info=method=EnrollProfile:verifyIdentityProofV2: ] proof of identification in CMC request
0.http-bio-8443-exec-2 - [24/May/2017:16:21:23 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=testuser][Outcome=Success][Info=method=EnrollProfile: verifyPOP: ] proof of possession
0.http-bio-8443-exec-2 - [24/May/2017:16:21:23 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=testuser][Outcome=Success][ReqID=43][ProfileID=caFullCMCSelfSignedCert][CertSubject=CN=Lady Christina Fu,UID=cfu,OU=self-signed] certificate request made with certificate profiles
0.http-bio-8443-exec-2 - [24/May/2017:16:21:24 PDT] [14] [6] [AuditEvent=PRIVATE_KEY_ARCHIVE_REQUEST][SubjectID=testuser][Outcome=Success][ReqID=43][ArchiveID=43] private key archive request
0.http-bio-8443-exec-2 - [24/May/2017:16:21:24 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=testuser][Outcome=Success][ReqID=43][CertSerialNum=24] certificate request processed
> CMCResponse -d . -i /root/cfu/test/cmc/cmc.self.Resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x18
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, May 24, 2017 4:21:23 PM PDT America/Los_Angeles
                Not  After: Monday, November 20, 2017 4:21:23 PM PST America/Los_Angeles
            Subject: CN=Lady Christina Fu,UID=cfu,OU=self-signed
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   Status: SUCCESS
  • Import the new certificate

User-signed CMC request Without POP (Encrypted POP / Decrypted POP)

This example demonstrates a user-signed CMC request where the CRMF request contains no POP, which would subsequently trigger an EncryptedPOP response from the CA and how to prepare the client to respond with DecryptedPOP to complete the certificate issuance. This method will require round trip.

Note that a request that contains no POP is a general indication that it’s not a signing key, so it could not be self-signed.
  • Generate a certificate request with no POP
    • Note that to see Encrypted POP and Decrypted POP in action, the initial crmf request has to contain no signing pop, hence the “POP_NONE” directive in the CRMFPopClient command
    • Note: the following CRMFPopClient example assumes that kra.transport contains the KRA's transport certificate in PEM format to achieve key archival.
> CRMFPopClient -d . -p netscape -n "cn=Lady Christina Fu, uid=cfu" -q POP_NONE -b kra.transport -v -o crmf2.req
Initializing security database: .
Loading transport certificate
Parsing subject DN
RDN: UID=cfu
RDN: CN=Lady Christina Fu
Generating key pair
Keypair private key id: -25aa0a8aad395ebac7e6a19c364f0dcb5350cfef
Creating certificate request
Creating CRMF request
Storing CRMF requrest into crmf2.req

  • Edit the CMCRequest cfg file to make sure that
    • the nickname contains the user signing cert instead of admin cert
    • make sure identityProofV2.enable=false
    • make sure popLinkWitnessV2.enable=false
    • make sure request.privKey contains the matching "private key id" from the csr generation above
    • see cmc config file: cmc-crmf-EncryptedPOP.cfg
  • Generate CMC Request
> CMCRequest cmc-crmf-EncryptedPOP.cfg
cert/key prefix =
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: signer cfu cert
createPKIData: begins
k=0
createPKIData:  format: crmf
identification control: identification =testuser
Successfully create identification control. bpid = 1

selfSign is false...
signData: begins:
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSASignatureWithSHA256Digest
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIR9gYJKoZIhvcNAQcCoIIR5zCCEeMCAQMxDzANBglghkgBZQMEAgEFADCCCCEG
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc2.req.

> HttpClient HttpClient2.cfg
Total number of bytes read = 2529
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
Total number of bytes read = 4124
MIIQGAYJKoZIhvcNAQcCoIIQCTCCEAUCAQMxDzANBglghkgBZQMEAgEFADCCCg0G

<snip>

The response in data format is stored in /root/cfu/test/cmc/cmcResp2-round1

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
    • At the end of the CMCResponse call below, observe that
      • NO CERT was being issued
      • The return controls contains “encrypted POP”
      • The return status is FAIL with failInfo=POP required
      • The request id is displayed under CMC ResponseInfo
      • Check relevant audit messages in audit log (e.g.) Observe that the PROFILE_CERT_REQUEST event is logged and CMCResposne below shows pending state
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success] access session establish success
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][ReqType=enrollment][CertSubject=, CN=Lady Christina Fu][SignerInfo=Signer Christina Fu] User signed CMC request signature verification success
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=AUTH_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][AuthMgr=CMCUserSignedAuth] authentication success
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=AUTHZ_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][aclResource=certServer.ee.profile][Op=submit] authorization success
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=CMC_ID_POP_LINK_WITNESS][SubjectID=Signer Christina Fu][Outcome=Success][Info=EnrollProfile: parseCMC: : ident_s=testuser] Identification Proof of Possession linking witness verification
0.http-bio-8443-exec-1 - [15/Jun/2017:15:43:45 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=85][ProfileID=caFullCMCUserSignedCert][CertSubject=CN=Signer Christina Fu,UID=cfu,OU=self-signed] certificate request made with certificate profiles
> CMCResponse -d . -i /root/cfu/test/cmc/cmcResp2-round1

Certificates:
    Certificate:
        Data:
            Version:  v3
            Serial Number: 0x1
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity:
                Not Before: Wednesday, May 17, 2017 6:06:50 PM PDT America/Los_Angeles
                Not  After: Sunday, May 17, 2037 6:06:50 PM PDT America/Los_Angeles
            Subject: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain

<snip>

Number of controls is 3
Control #0: CMC encrypted POP
   OID: {1 3 6 1 5 5 7 7 9}
     encryptedPOP decoded
Control #1: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   OtherInfo type: FAIL
     failInfo=POP required
Control #2: CMC ResponseInfo
   requestID: 15
> CMCRequest cmc-crmf-DecryptedPOP.cfg
cert/key prefix =
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: lady cfu cert
got request privKeyId: -25aa0a8aad395ebac7e6a19c364f0dcb5350cfef
got private key
processEncryptedPopResponse:  begins.
processEncryptedPopResponse:  previous response read.
processEncryptedPopResponse: Number of controls is 3
processEncryptedPopResponse: Control #0: CMC encrypted POP
processEncryptedPopResponse:    OID: {1 3 6 1 5 5 7 7 9}
processEncryptedPopResponse:      encryptedPOP decoded successfully
processEncryptedPopResponse: Control #1: CMCStatusInfoV2
processEncryptedPopResponse:    OID: {1 3 6 1 5 5 7 7 25}
processEncryptedPopResponse:    BodyList: 1 
processEncryptedPopResponse:    OtherInfo type: FAIL
processEncryptedPopResponse:      failInfo=POP required
processEncryptedPopResponse:    what we expected, as decryptedPOP.enable is true;
processEncryptedPopResponse: Control #2: CMC ResponseInfo
processEncryptedPopResponse:    requestID: 15
processEncryptedPopResponse: ends
constructDecryptedPopRequest: begins
constructDecryptedPopRequest:  previous response parsed.
constructDecryptedPopRequest: symKey unwrapped.
constructDecryptedPopRequest: challenge decrypted.
CryptoUtil: getNameFromHashAlgorithm: {2 16 840 1 101 3 4 2 1}
constructDecryptedPopRequest: Yay! witness verified
constructDecryptedPopRequest: calculating POP Proof Value
constructDecryptedPopRequest: constructing DecryptedPOP...
constructDecryptedPopRequest: DecryptedPOP constructed successfully
constructDecryptedPopRequest: adding decryptedPop control
constructDecryptedPopRequest: decryptedPop control added
constructDecryptedPopRequest: regInfo control added
constructDecryptedPopRequest:  completes.
selfSign is false...
signData: begins:
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSAignatureWithSHA256Digest
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIR2wYJKoZIhvcNAQcCoIIRzDCCEcgCAQMxDzANBglghkgBZQMEAgEFADCCCAYG

<snip>
The CMC enrollment request in data format is stored in cmc.decreyptedPOP.req.

Total number of bytes read = 4472
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
Total number of bytes read = 2437
MIIJgQYJKoZIhvcNAQcCoIIJcjCCCW4CAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmcResp2-round2
  • Check the result
    • Check that the CMCResponse has a SUCCESS status
    • Check that the new cert was really issued
    • If key archival is set up, check that key is archived
    • Observe audit log events, where CERT_REQUEST_PROCESSED even is logged and the CMCResponse shows success
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success] access session establish success
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][ReqType=enrollment][CertSubject=, CN=Lady Christina Fu][SignerInfo=Signer Christina Fu] User signed CMC request signature verification success
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=AUTH_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][AuthMgr=CMCUserSignedAuth] authentication success
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=AUTHZ_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][aclResource=certServer.ee.profile][Op=submit] authorization success
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=85][CertSerialNum=45] certificate request processed
0.http-bio-8443-exec-2 - [15/Jun/2017:15:51:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated
> CMCResponse -d . -i /root/cfu/test/cmc/cmcResp2-round2
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x2D
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Thursday, June 15, 2017 3:43:45 PM PDT America/Los_Angeles
                Not  After: Tuesday, December 12, 2017 3:43:45 PM PST America/Los_Angeles
            Subject: CN=Signer Christina Fu,UID=cfu,OU=self-signed
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   Status: SUCCESS

User-Signed CMC Renewal Request

The following example demonstrates how a CMC same-key renewal is processed. To demonstrate this, we will just resend one of the CMC requests we generate earlier to the uri /ca/ee/ca/profileSubmitUserSignedCMCFull. e.g.

> HttpClient HttpClient-cmc-p10-user-signed.cfg

Total number of bytes read = 3373
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
Total number of bytes read = 1601
MIIGPQYJKoZIhvcNAQcCoIIGLjCCBioCAQMxDzANBglghkgBZQMEAgEFADA0Bggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.pkcs10Resp
  • Check the result
    • Since the default RenewGracePeriodConstraint is 30 days before and after the expiration, and we only just got the certificate of the same key at previous example, we should expect a failure.
      • One could set the renew grace period to be shorter to see success result
      • One could also try to revoke an earlier cert with same key to see that renewal will be rejected
    • see the audit log failure message at end of relevant audit messages below:
0.http-bio-8443-exec-5 - [24/May/2017:17:43:33 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=Lady Christina Fu][Outcome=Success][ReqType=enrollment][CertSubject=CN=just me cfu,UID=cfu][SignerInfo=Lady Christina Fu] User signed CMC request signature verification success
.http-bio-8443-exec-5 - [24/May/2017:17:43:33 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=Lady Christina Fu][Outcome=Success][Info=method=EnrollProfile: fillTaggedRequest: ] proof of possession
0.http-bio-8443-exec-5 - [24/May/2017:17:43:34 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=Lady Christina Fu][Outcome=Success][ReqID=44][ProfileID=caFullCMCUserSignedCert][CertSubject=CN=Lady Christina Fu,UID=cfu,OU=self-signed] certificate request made with certificate profiles
0.http-bio-8443-exec-5 - [24/May/2017:17:43:34 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=Lady Christina Fu][Outcome=Failure][ReqID=44][InfoName=rejectReason][InfoValue=Request Outside of Renewal Grace Period: 30 days before and 30 days after original cert expiration date Rejected - {1}] certificate request processed
</per>
<pre>
> CMCResponse -d . -i /root/cfu/test/cmc/cmc.pkcs10Resp
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   OtherInfo type: FAIL
Note: re-key renewal will be treated just like new enrollment;  It would not be able to utilize the RenewGracePeriodConstraint

CMC Revocation Request (User-signed)

This example demonstrates a user-signed CMC revocation request.

  • Create a CMC revocation request config file; Note that
    • nickname should be a valid user signing certificate that belongs to the same user subject as that of the certificate to be revoked (but not necessarily the same certificate)
    • revRequest.serial and revRequest.reason must contain valid values e.g.
      • revRequest.serial=56
      • revRequest.reason=unspecified
    • optionally revRequest.comment can be added
    • note that in case of User-signed cmc revocation request, revRequest.issuer and revRequest.sharedSecret are ignored because
      • issuer is obtained from the signer's certificate
      • a signed request already proves the origin; sharedSecret is only used when it's an unsigned request
    • See example: cmc-user-signed-revoke.cfg
> CMCRequest cmc-revoke-user-signed.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: signer cfu cert
addRevRequestAttr: no sharedSecret found; request will be signed;
addRevRequestAttr: RevokeRequest control created.
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIKiQYJKoZIhvcNAQcCoIIKejCCCnYCAQMxDzANBglghkgBZQMEAgEFADCBswYI
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.revoke.userSigned.req.
> HttpClient HttpClient.revoke.userSigned.cfg

Total number of bytes read = 2701
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 1598
MIIGOgYJKoZIhvcNAQcCoIIGKzCCBicCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.revoke.userSigned.resp
  • check the result:
> CMCResponse -d . -i /root/cfu/test/cmc/cmc.revoke.userSigned.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x1
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   Status: SUCCESS

  • Observe the audit log events:
.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success] access session establish success
0.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][ReqType=revocation][CertSubject=$Unidentified$][SignerInfo=Signer Christina Fu] User signed CMC request signature verification success
0.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=AUTH_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][AuthMgr=CMCUserSignedAuth] authentication success
0.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=AUTHZ_SUCCESS][SubjectID=Signer Christina Fu][Outcome=Success][aclResource=certServer.ee.profile][Op=submit] authorization success
0.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=CERT_STATUS_CHANGE_REQUEST_PROCESSED][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=Signer Christina Fu][CertSerialNum=45][RequestType=revoke][RevokeReasonNum=Unspecified][Approval=complete] certificate status change request processed
0.http-bio-8443-exec-22 - [15/Jun/2017:17:10:05 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=CN=Signer Christina Fu,UID=cfu,OU=self-signed][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated

CMC Revocation Request (unsigned; sharedToken-based)

This example demonstrate an unsigned, sharedToken-based CMC revocation request.

  • Create a CMC revocation request config file; Note that
    • nickname is not needed in the unsigned case and will be ignored
    • revRequest.serial, revRequest.reason, revRequest.issuer and revRequest.sharedSecret must contain valid values e.g.
      • revRequest.serial=56
      • revRequest.reason=unspecified
      • revRequest.issuer=<issuer subjectdn>
      • revRequest.sharedSecret=<shared secret>
    • optionally revRequest.comment can be added
  • See example cmc-revoke-shared-secret.cfg
> CMCRequest cmc-revoke-shared-secret.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
Missing format..assume revocation
addRevRequestAttr: sharedSecret found; request will be unsigned;
addRevRequestAttr: RevokeRequest control created.
getCMCBlob: begins
getCMCBlob: generating unsigned data

The CMC enrollment request in base-64 encoded format:

MIHTBgkqhkiG9w0BBwGggcUEgcIwgb8wgbYwgbMCAQEGCCsGAQUFBwcRMYGjMIGg
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.revoke.sharedSecret.req.

> HttpClient HttpClient.revoke.sharedSecret.cfg

Total number of bytes read = 214
after SSLSocket created, thread token is Internal Key Storage Token
handshake happened
writing to socket
handshake happened
Total number of bytes read = 1598
MIIGOgYJKoZIhvcNAQcCoIIGKzCCBicCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.revoke.resp
  • Observe the CMCResponse to be SUCCESS
CMCResponse -d . -i /root/cfu/test/cmc/cmc.revoke.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x1
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, May 17, 2017 6:06:50 PM PDT America/Los_Angeles
                Not  After: Sunday, May 17, 2037 6:06:50 PM PDT America/Los_Angeles
            Subject: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
<snip>
Number of controls is 1
Control #0: CMCStatusInfo
   OID: {1 3 6 1 5 5 7 7 1}
   BodyList: 1 
   Status: SUCCESS

  • observe the audit log events
0.http-bio-8443-exec-19 - [15/Jun/2017:18:08:53 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=][Outcome=Success] access session establish success
0.http-bio-8443-exec-19 - [15/Jun/2017:18:08:53 PDT] [14] [6] [AuditEvent=AUTHZ_SUCCESS][SubjectID=$Unidentified$][Outcome=Success][aclResource=certServer.ee.profile][Op=submit] authorization success
0.http-bio-8443-exec-19 - [15/Jun/2017:18:08:54 PDT] [14] [6] [AuditEvent=CERT_STATUS_CHANGE_REQUEST_PROCESSED][SubjectID=Signer Christina Fu][Outcome=Success][ReqID=$Unidentified$][CertSerialNum=44][RequestType=revoke][RevokeReasonNum=Unspecified][Approval=complete] certificate status change request processed
0.http-bio-8443-exec-19 - [15/Jun/2017:18:08:54 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=y.y.y.y][ServerIP=x.x.x.x][SubjectID=][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated

Examples (User Certificates -EC)

The following are a couple examples for EC user certs.

Note that for convenience, in the following examples, I'm using an RSA CA as the issuance CA, and the agent certificate itself is an RSA certificate.

Agent-signed EC cmc request

This example shows generation of and EC cert request that is pre-signed with an agent (RSA) cert.

  • Generate an EC pkcs10 request
    • e.g.
# PKCS10Client -d . -p netscape -a ec -c nistp256 -o p10-ec.req -n "CN=cfuEC"
PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 1aaa5f1c7e68cded2a9aeaeca1c203e9e65449b4

-----BEGIN CERTIFICATE REQUEST-----
MIHJMHICAQAwEDEOMAwGA1UEAwwFY2Z1RUMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS1KwcgUYIYLQn8V216jOqhlv/5t36rjdFD6Xe2/unLzvq5i92iiRr0GD8pp99x0CYA4KXZmnwvgb4J5MR5s9T9oAAwCgYIKoZIzj0EAwIDRwAwRAIgV9DVBvNhudP8nvt6jJLBjAbTq8iDa6ArZVQKGtVjlQQCIEzfw+neiCWZ3bLX8dQTedqj7lRHjh2ifh5iDc5mtEDg
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: p10-ec.req
  • Create an agent-signed CMC request config file: cmc.role_p10.cfg
    • make sure the nickname value in cmc.role_p10.cfg is an agent cert
    • make sure the input points to the csr you just generated
    • (in this case) make sure the format is pkcs10
  • Run CMCRequest to generate the CMC request
# CMCRequest cmc.role_p10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: cfuAgent2 cert
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIKlwYJKoZIhvcNAQcCoIIKiDCCCoQCAQMxDzANBglghkgBZQMEAgEFADCB8AYI
<snip>
The CMC enrollment request in binary format is stored in /root/cfu/test/cmc/cmc.role_p10-ec.req
# HttpClient HttpClient_role_p10-ec.cfg

Total number of bytes read = 2715
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2291
MIII7wYJKoZIhvcNAQcCoIII4DCCCNwCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in binary format is stored in /root/cfu/test/cmc/cmc.role_p10-ec.resp
  • run CMCResponse to see result:
# CMCResponse -d . -i /root/cfu/test/cmc/cmc.role_p10-ec.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x165
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=sjc.redhat.com Security Domain
            Validity: 
                Not Before: Wednesday, October 25, 2017 11:55:31 AM PDT America/Los_Angeles
                Not  After: Monday, April 23, 2018 11:55:31 AM PDT America/Los_Angeles
            Subject: CN=cfuEC
            Subject Public Key Info: 
                Algorithm: EC - 1.2.840.10045.2.1
                Public Key: 
                    04:B5:2B:07:20:51:82:18:2D:09:FC:57:6D:7A:8C:EA:
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS
  • Note the "SUCCESS" status in the CMCResponse; In addition, you can
    • Check relevant audit messages. e.g.
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=CMC_SIGNED_REQUEST_SIG_VERIFY][SubjectID=UID=TestAgent2,OU=example][Outcome=Success][ReqType=enrollment][CertSubject=CN=cfuEC][SignerInfo=UID=TestAgent2,OU=example] agent pre-approved CMC request signature verification
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=ROLE_ASSUME][SubjectID=cfu][Outcome=Success][Role=Certificate Manager Agents] assume privileged role
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=cfu][Outcome=Success][Info=method=EnrollProfile: fillTaggedRequest: ] proof of possession
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=cfu][Outcome=Success][ReqID=563][ProfileID=caFullCMCUserCert][CertSubject=CN=cfuEC] certificate request made with certificate profiles
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=cfu][Outcome=Success][ReqID=563][CertSerialNum=357] certificate request processed
0.http-bio-8443-exec-2 - [25/Oct/2017:11:55:31 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=x1.x2.x3.x4][ServerIP=y1.y2.y3.y4][SubjectID=UID=TestAgent2,OU=example][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated

User-signed EC cmc request

This example shows generation of an EC cert request that is signed with an a previously issued user EC cert. In this example, we are using the EC cert issued in the above example to sign the next request.

  • Prepare the user signing cert:
    • Copy and paste the previously enrolled EC user cert into a file in PEM format and add to the working NSS db. e.g.:
      • # certutil -d . -A -t "u,u,u" -n "cfuEC cert1" -a -i cfu-ec-cert.b64
    • Make sure the EC user signing cert has its key in the nss db (must show "u,u,u"):
# certutil -d . -L

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

<snip>
cfuEC cert1                                                  u,u,u

  • Generate an EC pkcs10 request
    • e.g.
# PKCS10Client -d . -p netscape -a ec -c nistp256 -o p10-ec2.req -n "CN=cfuEC2"
PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 5db268462ffb0c0c5735a157b5c95d2a760d8c41

-----BEGIN CERTIFICATE REQUEST-----
MIHLMHMCAQAwETEPMA0GA1UEAwwGY2Z1RUMyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgK3LPJ9YVokPPPdJRKaFrr798eSSgMTkado7Q3j5qcZUYi/qfVcwe/A60Kr1ezH0nRKyB2zr5sR8l6OFB3S+2aAAMAoGCCqGSM49BAMCA0gAMEUCIQCtBLmB6TBMcZdQzAkjiGCtP9XB1DdfVW6Ocsy0OuIadwIgH+rskwMWEiwOKncNUQTcPVrvwLq6jajSGtzdqglAHwA=
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: p10-ec2.req
  • Create a CMCRequest cfg file, e.g. cmc-p10-user-signed-ec2.cfg
    • make sure nickname contains the EC user cert that was issued previously
    • make sure the input is the csr we just generated from the PKCS10Client command above
  • run CMCRequest to generate a user-signed CMC request:
# CMCRequest cmc-p10-user-signed-ec2.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: cfuEC cert1
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=EC
getSigningAlgFromPrivate: using SignatureAlgorithm: ECSignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =EC
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIII7gYJKoZIhvcNAQcCoIII3zCCCNsCAQMxDzANBglghkgBZQMEAgEFADCB8gYI
<snip>
The CMC enrollment request in binary format is stored in /root/cfu/test/cmc/cmc.p10-ec2.req
  • Create the HttpClient cfg file (e.g. HttpClient.p10-ec2.cfg)
    • Make sure nickname contains the same EC user signing cert that was used to sign the CMC request from CMCRequest above
  • Run HttpClient to submit the cmc request
# HttpClient HttpClient.p10-ec2.cfg

Total number of bytes read = 2290
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2291
MIII7wYJKoZIhvcNAQcCoIII4DCCCNwCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>

The response in binary format is stored in /root/cfu/test/cmc/cmc.p10-ec2.resp
  • run CMCResponse to check the result:
# CMCResponse -d . -i /root/cfu/test/cmc/cmc.p10-ec2.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x166
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=sjc.redhat.com Security Domain
            Validity: 
                Not Before: Wednesday, October 25, 2017 3:16:27 PM PDT America/Los_Angeles
                Not  After: Monday, April 23, 2018 3:16:27 PM PDT America/Los_Angeles
            Subject: CN=cfuEC
            Subject Public Key Info: 
                Algorithm: EC - 1.2.840.10045.2.1
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

  • Note the "SUCCESS" status in the CMCResponse; In addition, you can
    • Check relevant audit messages. e.g.
0.http-bio-8443-exec-8 - [25/Oct/2017:15:16:27 PDT] [14] [6] [AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID=CN=cfuEC][Outcome=Success][ReqType=enrollment][CertSubject=CN=cfuEC2][SignerInfo=CN=cfuEC] User signed CMC request signature verification success
0.http-bio-8443-exec-8 - [25/Oct/2017:15:16:27 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=CN=cfuEC][Outcome=Success][Info=method=EnrollProfile: fillTaggedRequest: ] proof of possession
0.http-bio-8443-exec-8 - [25/Oct/2017:15:16:27 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=CN=cfuEC][Outcome=Success][ReqID=564][ProfileID=caFullCMCUserSignedCert][CertSubject=CN=cfuEC] certificate request made with certificate profiles
0.http-bio-8443-exec-8 - [25/Oct/2017:15:16:27 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=CN=cfuEC][Outcome=Success][ReqID=564][CertSerialNum=358] certificate request processed
0.http-bio-8443-exec-8 - [25/Oct/2017:15:16:27 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=x1.x2.x3.x4][ServerIP=u1.y2.y3.y4][SubjectID=CN=cfuEC][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated

Examples (System Certificates)

Note: A generic "CMC servlet" (https://pagure.io/dogtagpki/issue/2815) improvement has been made since the instruction below was initially provided. Please see https://pki.fedoraproject.org/wiki/PKI_10.5_Installation_with_CMC for newer examples on making system cert requests

Note:
1. It is highly recommended that you read the "Certificate Issuance User Workflow" section above first before following the examples in this section."
2. It is important to note that all of the system cert requests need to be signed by a CA agent.

This section gives examples on how to procure PKI system certificates via CMC.

Getting a Subordinate CA Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=subCA Signing Certificate,OU=pki-tomcat,O=mySecurityDomain" -o ca_pkcs10.req
PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 192bda1e7f8f2105e070df51d4fc928b6b3a15e9

-----BEGIN CERTIFICATE REQUEST-----
MIICmTCCAYECAQAwVDEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWNhdDEiMCAGA1UEAwwZc3ViQ0EgU2lnbmluZyBDZXJ0aWZpY2F0ZTCCASIwDQYJKo<s
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_subca_pkcs10.req
  • Edit the CMCRequest cfg file to make sure that
    • the nickname contains the agent cert that will sign the request
    • see CMCRequest cfg file example: CMC.sys_subca_pkcs10.cfg
  • Generate the cmc request
CMCRequest cmc.sys_subca_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM3gYJKoZIhvcNAQcCoIIMzzCCDMsCAQMxDzANBglghkgBZQMEAgEFADCCAsQG
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_subca_pkcs10.req.

  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullCACert
    • example: HttpClient_sys_ca.cfg
HttpClient HttpClient_sys_ca.cfg

Total number of bytes read = 3298
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2598
MIIKIgYJKoZIhvcNAQcCoIIKEzCCCg8CAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.sys_subca_pkcs10.resp
  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_subca_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x42
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, July 5, 2017 4:28:14 PM PDT America/Los_Angeles
                Not  After: Sunday, July 5, 2037 4:28:14 PM PDT America/Los_Angeles
            Subject: CN=subCA Signing Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Getting an OCSP Signing Certificate

  • Generate a PKCS10 Request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=OCSP Signing Certificate,OU=pki-tomcat,O=mySecurityDomain" -o sys_ocsp_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: -68c3391989026135bea0bc55df05f6474965ed15

-----BEGIN CERTIFICATE REQUEST-----
MIICmDCCAYACAQAwUzEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWNhdDEhMB8GA1UEAwwYT0NTUCBTaWduaW5nIENlcnRpZmljYXRlMIIBI
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_ocsp_pkcs10.req
  • Edit the CMCRequest cfg file to make sure that
    • the nickname contains the agent cert that will sign the request
    • see CMCRequest cfg file example: cmc.sys_ocsp_pkcs10.cfg
  • Generate the cmc request
CMCRequest cmc.sys_ocsp_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM3QYJKoZIhvcNAQcCoIIMzjCCDMoCAQMxDzANBglghkgBZQMEAgEFADCCAsMG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_ocsp_pkcs10.req.
  • submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullOCSPCert
    • example: HttpClient_sys_ocsp.cfg
HttpClient HttpClient_sys_ocsp.cfg

Total number of bytes read = 3297
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2571
MIIKBwYJKoZIhvcNAQcCoIIJ+DCCCfQCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.sys_ocsp_pkcs10.resp

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_ocsp_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x43
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, July 5, 2017 5:41:44 PM PDT America/Los_Angeles
                Not  After: Tuesday, June 25, 2019 5:41:44 PM PDT America/Los_Angeles
            Subject: CN=OCSP Signing Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Getting an SSL Server Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=host.example.com,OU=pki-tomcat,O=mySecurityDomain" -o sys_server_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: -2f64455a8b417897d6c5e02f3612ed073e83f2ae

-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWNh
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_server_pkcs10.req

  • Edit the CMCRequest cfg file to make sure that
  • Generate the cmc request
CMCRequest cmc.sys_server_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM1QYJKoZIhvcNAQcCoIIMxjCCDMICAQMxDzANBglghkgBZQMEAgEFADCCArsG
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_server_pkcs10.req.
  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullServerCert
    • example: HttpClient_sys_server.cfg
HttpClient HttpClient_sys_server.cfg

Total number of bytes read = 3289
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2601
MIIKJQYJKoZIhvcNAQcCoIIKFjCCChICAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>

The response in data format is stored in /root/cfu/test/cmc/cmc.sys_server_pkcs10.resp
  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_server_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x44
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Wednesday, July 5, 2017 6:03:31 PM PDT America/Los_Angeles
                Not  After: Tuesday, June 25, 2019 6:03:31 PM PDT America/Los_Angeles
            Subject: CN=host.example.com,OU=pki-tomcat,O=mySecurityDomain
<snip>

Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Getting a Subsystem Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=Subsystem Certificate,OU=pki-tomcat,O=mySecurityDomain" -o sys_subsystem_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 2b49b42471ea7d42153bdb06344a8786cedd3169

-----BEGIN CERTIFICATE REQUEST-----
MIIClTCCAX0CAQAwUDEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWNh
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_subsystem_pkcs10.req

  • Edit the CMCRequest cfg file to make sure that
  • Generate the cmc request
CMCRequest cmc.sys_subsystem_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM2gYJKoZIhvcNAQcCoIIMyzCCDMcCAQMxDzANBglghkgBZQMEAgEFADCCAsAG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_subsystem_pkcs10.req.

  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullSubsystemCert
    • example: HttpClient_sys_subsystem.cfg
HttpClient HttpClient_sys_subsystem.cfg

Total number of bytes read = 3294
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2567
MIIKAwYJKoZIhvcNAQcCoIIJ9DCCCfACAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.sys_subsystem_pkcs10.resp

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_subsystem_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x46
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Thursday, July 6, 2017 11:04:48 AM PDT America/Los_Angeles
                Not  After: Wednesday, June 26, 2019 11:04:48 AM PDT America/Los_Angeles
            Subject: CN=Subsystem Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS


Getting an Audit Signing Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=Audit Signing Certificate,OU=pki-tomcat,O=mySecurityDomain" -o sys_auditSigning_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 88815e873f82115b43dab2aba00b6876ef8945c

-----BEGIN CERTIFICATE REQUEST-----
MIICmTCCAYECAQAwVDEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWNh
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_auditSigning_pkcs10.req
  • Edit the CMCRequest cfg file to make sure that
  • Generate the cmc request
CMCRequest cmc.sys_auditSigning_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM3gYJKoZIhvcNAQcCoIIMzzCCDMsCAQMxDzANBglghkgBZQMEAgEFADCCAsQG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_auditSigning_pkcs10.req.
  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullAuditSigningCert
    • example: HttpClient_sys_auditSigning.cfg
HttpClient HttpClient_sys_auditSigning.cfg

Total number of bytes read = 3298
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2548
MIIJ8AYJKoZIhvcNAQcCoIIJ4TCCCd0CAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>
The response in data format is stored in /root/cfu/test/cmc/cmc.sys_auditSigning_pkcs10.resp

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_auditSigning_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x45
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Thursday, July 6, 2017 9:51:09 AM PDT America/Los_Angeles
                Not  After: Wednesday, June 26, 2019 9:51:09 AM PDT America/Los_Angeles
            Subject: CN=Audit Signing Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>
Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Getting a KRA Transport Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=KRA Transport Certificate,OU=pki-tomcat,O=mySecurityDomain" -o sys_transport_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: 24afd2357220ce1e8f126624bbcc8ac0c9c7c6fd

-----BEGIN CERTIFICATE REQUEST-----
MIICmTCCAYECAQAwVDEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWN
<snip>
-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_transport_pkcs10.req

  • Edit the CMCRequest cfg file to make sure that
CMCRequest cmc.sys_transport_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM3gYJKoZIhvcNAQcCoIIMzzCCDMsCAQMxDzANBglghkgBZQMEAgEFADCCAsQG
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_transport_pkcs10.req
  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullKRAtransportCert
    • example: HttpClient_sys_transport.cfg
HttpClient HttpClient_sys_transport.cfg

Total number of bytes read = 3298
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2571
MIIKBwYJKoZIhvcNAQcCoIIJ+DCCCfQCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>

The response in data format is stored in /root/cfu/test/cmc/cmc.sys_transport_pkcs10.resp

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_transport_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x47
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Thursday, July 6, 2017 3:27:06 PM PDT America/Los_Angeles
                Not  After: Wednesday, June 26, 2019 3:27:06 PM PDT America/Los_Angeles
            Subject: CN=KRA Transport Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>

Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Getting a KRA Storage Certificate

  • Generate a PKCS10 request
    • Note: make sure the subject name is as intended.
PKCS10Client -d . -p netscape -n "CN=KRA Storage Certificate,OU=pki-tomcat,O=mySecurityDomain" -o sys_kraStorage_pkcs10.req

PKCS10Client: Debug: got token.
PKCS10Client: Debug: thread token set.
PKCS10Client: token Internal Key Storage Token logged in...
PKCS10Client: key pair generated.
PKCS10Client: CertificationRequest created.
PKCS10Client: b64encode completes.
Keypair private key id: -6de18c720dbf86cb283b253126e2529609261278

-----BEGIN CERTIFICATE REQUEST-----
MIIClzCCAX8CAQAwUjEZMBcGA1UECgwQbXlTZWN1cml0eURvbWFpbjETMBEGA1UECwwKcGtpLXRvbWN
<snip>

-----END CERTIFICATE REQUEST-----
PKCS10Client: done. Request written to file: sys_kraStorage_pkcs10.req
  • Edit the CMCRequest cfg file to make sure that
  • Generate the cmc request
CMCRequest cmc.sys_kraStorage_pkcs10.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for unknown00262DFC6A5E
createPKIData: begins
k=0
createPKIData:  format: pkcs10
PKCS10: PKCS10: begins
PKCS10: PKCS10: ends
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIM3AYJKoZIhvcNAQcCoIIMzTCCDMkCAQMxDzANBglghkgBZQMEAgEFADCCAsIG
<snip>
The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.sys_kraStorage_pkcs10.req

  • Submit the CMC request
    • make sure the nickname contains the signing agent's certificate nickname
    • make sure secure=true and clientmode=true
    • make sure servlet=/ca/ee/ca/profileSubmitCMCFullKRAstorageCert
    • example: HttpClient_sys_kraStorage.cfg
HttpClient HttpClient_sys_kraStorage.cfg

Total number of bytes read = 3296
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2569
MIIKBQYJKoZIhvcNAQcCoIIJ9jCCCfICAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>

The response in data format is stored in /root/cfu/test/cmc/cmc.sys_kraStorage_pkcs10.resp

  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
CMCResponse -d . -i /root/cfu/test/cmc/cmc.sys_kraStorage_pkcs10.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0x48
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=unknown00262DFC6A5E Security Domain
            Validity: 
                Not Before: Thursday, July 6, 2017 4:06:40 PM PDT America/Los_Angeles
                Not  After: Wednesday, June 26, 2019 4:06:40 PM PDT America/Los_Angeles
            Subject: CN=KRA Storage Certificate,OU=pki-tomcat,O=mySecurityDomain
<snip>

Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS

Example - Getting a Role user (Administrator, Agent, or Auditor) Certificate

A user's role status is determined by one's group membership within the certificate authority groups database. This section only demonstrates how a role user's certificate can be obtained via a CMC request. Once the certificate is obtained successfully, the administrator of the certificate authority should follow documented instruction to add the user and his/her certificate into the proper group membership.

Note: This procedure differs from the "User-signed" procedure above in that it requires a CA agent to sign the CMC request.
   Please pay special attention to the "servlet" parameter value in the HttpClient config file.

Agent-signed CMC requests Example

This example demonstrates a cmc request signed by an existing CA agent. It can often be used for getting a role user certificate.

First, the user that wishes to obtain a certificate performs the following:

  • Generate a cert request (pkcs10 or crmf)
    • Note: the following CRMFPopClient example assumes that kra.transport contains the KRA's transport certificate in PEM format to achieve key archival.
    • also note that HSM is assumed to be used by KRA, hence the additional of the option -w "AES/CBC/PKCS5Padding"
> CRMFPopClient -d . -p netscape -n "cn=admin cfu, uid=admincfu" -q POP_SUCCESS -b kra.transport  -w  "AES/CBC/PKCS5Padding" -v -o crmf.req
Initializing security database: .
Loading transport certificate
Parsing subject DN
RDN: UID=admincfu
RDN: CN=admin cfu
Generating key pair
Keypair private key id: -7b9321c5a247d4877683b9a0e110167c0b604034
Using key wrap algorithm: AES KeyWrap/Padding
Creating certificate request
Creating signer
Creating POP
Creating CRMF request
Storing CRMF requrest into crmf.req
  • Hand the CSR to a CA agent

Now, a CA agent should perform the following:

  • take the CSR that the user generated from the above step and store in a file. The CSR should be in BER data format as was directly output by the either of the Dogtag tools (CRMFPopClient and PKCS10Client) depicted above.
  • Edit CMCRequest cfg file so that
    • the nickname contains the CA agent signing cert
    • the format matches the csr format in the above step
    • the input points to the CSR file
    • the output points to where you intend the output to go
    • see cmc config file: cmc.role_crmf.cfg
CMCRequest cmc.role_crmf.cfg

cert/key prefix = 
path = /root/cfu/test/cmc/
CryptoManger initialized
token internal logged in...
got signerCert: PKI Administrator for Example.com
createPKIData: begins
k=0
createPKIData:  format: crmf
selfSign is false...
signData: begins: 
getPrivateKey: got signing cert
signData:  got signer privKey
createSignedData: begins
getSigningAlgFromPrivate: begins.
getSigningAlgFromPrivate: found signingKeyType=RSA
getSigningAlgFromPrivate: using SignatureAlgorithm: RSASignatureWithSHA256Digest
createSignedData: digest created for pkidata
createSignedData: digest algorithm =RSA
createSignedData: building cert chain
signData: signed request generated.
getCMCBlob: begins
getCMCBlob: generating signed data

The CMC enrollment request in base-64 encoded format:

MIIOvAYJKoZIhvcNAQcCoIIOrTCCDqkCAQMxDzANBglghkgBZQMEAgEFADCCCK4G
<snip>

The CMC enrollment request in data format is stored in /root/cfu/test/cmc/cmc.role_crmf.req
  • submit the cmc request
    • make sure clientmode=true
    • make sure nicname=<the agent certificate that signs the cmc request>
    • make sure the HttpClient config file "servlet" points to servlet=/ca/ee/ca/profileSubmitCMCFull?profileId=caCMCUserCert
    • see HttpClient config file: HttpClient_role_crmf.cfg
HttpClient HttpClient_role_crmf.cfg
Total number of bytes read = 3776
after SSLSocket created, thread token is Internal Key Storage Token
client cert is not null
handshake happened
writing to socket
Total number of bytes read = 2523
MIIJ1wYJKoZIhvcNAQcCoIIJyDCCCcQCAQMxDzANBglghkgBZQMEAgEFADAxBggr
<snip>

The response in data format is stored in /root/cfu/test/cmc/cmc.role_crmf.resp
  • Check the result: (note that the response is a pkcs#7 cert chain in the success case)
    • At the end of the CMCResponse call below, observe that
      • the CMCResponse has a SUCCESS status
      • the new cert was really issued
      • the certificate bears the subject name as intended
      • If key archival is set up, check that key is archived (only available if the underlying request is CRMF)
      • Check relevant audit messages in audit log (e.g.) TBD
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=10.14.72.96][ServerIP=10.14.72.96][SubjectID=CN=PKI Administrator,E=caadmin@Example.com,OU=pki-tomcat,O=Example.com Security Domain][Outcome=Success] access session establish success
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=CMC_SIGNED_REQUEST_SIG_VERIFY][SubjectID=$NonRoleUser$][Outcome=Success][ReqType=enrollment][CertSubject=, CN=admin cfu][SignerInfo=PKI Administrator] agent pre-approved CMC request signature verification
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=AUTH_SUCCESS][SubjectID=caadmin][Outcome=Success][AuthMgr=CMCAuth] authentication success
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=AUTHZ_SUCCESS][SubjectID=caadmin][Outcome=Success][aclResource=certServer.ee.profile][Op=submit] authorization success
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=ROLE_ASSUME][SubjectID=caadmin][Outcome=Success][Role=Certificate Manager Agents, Administrators, Security Domain Administrators, Enterprise CA Administrators, Enterprise KRA Administrators, Enterprise OCSP Administrators, Enterprise TKS Administrators, Enterprise RA Administrators, Enterprise TPS Administrators] assume privileged role
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=PROOF_OF_POSSESSION][SubjectID=caadmin][Outcome=Success][Info=method=EnrollProfile: verifyPOP: ] proof of possession
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=PROFILE_CERT_REQUEST][SubjectID=caadmin][Outcome=Success][ReqID=14][ProfileID=caFullCMCUserCert][CertSubject=CN=admin cfu,UID=admincfu] certificate request made with certificate profiles
0.http-bio-8443-exec-3 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_ESTABLISH_SUCCESS][ClientIP=10.14.72.96][ServerIP=10.14.72.96][SubjectID=CN=Subsystem Certificate,OU=pki-tomcat,O=Example.com Security Domain][Outcome=Success] access session establish success
0.http-bio-8443-exec-3 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=10.14.72.96][ServerIP=10.14.72.96][SubjectID=CN=Subsystem Certificate,OU=pki-tomcat,O=Example.com Security Domain][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=SECURITY_DATA_ARCHIVAL_REQUEST][SubjectID=caadmin][Outcome=Success][ArchivalRequestID=14][RequestId=14][ClientKeyID=null] security data archival request made
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=CERT_REQUEST_PROCESSED][SubjectID=caadmin][Outcome=Success][ReqID=14][CertSerialNum=14] certificate request processed
0.http-bio-8443-exec-2 - [21/Jul/2017:12:06:50 PDT] [14] [6] [AuditEvent=ACCESS_SESSION_TERMINATED][ClientIP=10.14.72.96][ServerIP=10.14.72.96][SubjectID=CN=PKI Administrator,E=caadmin@Example.com,OU=pki-tomcat,O=Example.com Security Domain][Outcome=Success][Info=CLOSE_NOTIFY] access session terminated

> CMCResponse -d . -i /root/cfu/test/cmc/cmc.role_crmf.resp
Certificates: 
    Certificate: 
        Data: 
            Version:  v3
            Serial Number: 0xE
            Signature Algorithm: SHA256withRSA - 1.2.840.113549.1.1.11
            Issuer: CN=CA Signing Certificate,OU=pki-tomcat,O=sjc.redhat.com Security Domain
            Validity: 
                Not Before: Friday, July 21, 2017 12:06:50 PM PDT America/Los_Angeles
                Not  After: Wednesday, January 17, 2018 12:06:50 PM PST America/Los_Angeles
            Subject: CN=admin cfu,UID=admincfu
<snip>

Number of controls is 1
Control #0: CMCStatusInfoV2
   OID: {1 3 6 1 5 5 7 7 25}
   BodyList: 1 
   Status: SUCCESS
  • Hand the resulting certificate to the user
  • add the user certificate to user record and add the user to the appropriate role group member per instruction.

Once the certificate is received, the user would want to import the certificate:

  • import the new certificate
certutil -d . -A -t "u,u,u" -n "new lady cfu administrator cert" -i cmc.role_crmf.resp