Many newer versions of browsers, including Firefox v69 and up, as well as Chrome, have removed the functionality to generate PKI keys and the support for CRMF for key archival. While CLIs such as CRMFPopClient (see "CRMFPopClient --help") or pki (see "pki client-cert-request --help") could be used as a workaround on the Fedora or RHEL platforms, clients on other platforms have been largely left out.
Server-Side Keygen enrollment has been around for a long time since the introduction of Token Key Management System (TMS), where keys could be generated on KRA instead of locally on smart cards. Starting from PKI v.10.5, we adopt a similar mechanism to resolve the browser keygen deficiency issue. Keys are generated on the server (KRA to be specific) and then transferred securely back to the client in PKCS#12.
Note
|
It is highly recommended that the Server-Side Keygen mechanism only being employed for encryption certificates. |
-
Certificate request keys are generated on KRA (Note: KRA must be installed to work with the CA)
-
The profile default plugin, serverKeygenUserKeyDefaultImpl, provides selection to enable or disable key archival (i.e. the “enableArchival” parameter)
-
Support for both RSA and EC keys
-
Support for both manual (agent) approval and automatic approval (e.g. directory password-based)
Note
|
A KRA instance is required in addition to the CA for setting up Server-Side Keygen. |
Note
|
In the case when the CA and KRA are sharing a Tomcat instance, there is no need to execute the below step to import the transport certificate. |
After installing CA and KRA instances, in the case of stand-alone Tomcat web server instances, you’d need to add the KRA’s transport cert to the CA’s nssdb.
First, shut down CA
Systemctl stop pki-tomcatd@<ca_instance_name>.service e.g. # Systemctl stop pki-tomcatd@pki-ca.service
Export KRA’s transport certificate into a file
-
Find and export KRA transport cert:
grep "kra.transport.cert=" /var/lib/pki/<kra_instance_name>/kra/conf/CS.cfg | sed 's/kra.transport.cert=//' > <kra transport cert file> e.g. # grep "kra.transport.cert=" /var/lib/pki/pki-kra/kra/conf/CS.cfg | sed 's/kra.transport.cert=//' > /tmp/kraTransport.cert
Import KRA’s transport cert into CA’s nssdb, using the nickname specified in CA’s CS.cfg
-
List the transport cert nickname:
grep "ca.connector.KRA.transportCertNickname" /var/lib/pki/<ca_instance_name>/ca/conf/CS.cfg e.g. # grep "ca.connector.KRA.transportCertNickname" /var/lib/pki/pki-ca/ca/conf/CS.cfg ca.connector.KRA.transportCertNickname=KRA transport cert
-
Import using the nickname listed from above step:
certutil -d /var/lib/pki/<ca_instance_name>/alias -A -t “,,” -n <transportNickName> -i <kra transport cert file> e.g. # certutil -d /var/lib/pki/pki-ca/alias -A -t “,,” -n "KRA transport cert" -i /tmp/kraTransport.cert
Start CA
systemctl start pki-tomcatd@<ca_instance_name>.service e.g. # Systemctl start pki-tomcatd@pki-ca.service
Two default profiles, caServerKeygen_UserCert and caServerKeygen_DirUserCert, are provided by default to allow for certificate enrollments where keys are generated on the server side. However, any profile with the right input, output, and policy set could be turned into a server-side keygen profile.
A Server-Side Keygen profile must contain the following components.
Password for the generated PKCS12 can be enforced with the following policy:
policyset.userCertSet.11.constraint.class_id=p12ExportPasswordConstraintImpl policyset.userCertSet.11.constraint.name=PKCS12 Password Constraint policyset.userCertSet.11.constraint.params.password.minSize=20 policyset.userCertSet.11.constraint.params.password.minUpperLetter=2 policyset.userCertSet.11.constraint.params.password.minLowerLetter=2 policyset.userCertSet.11.constraint.params.password.minNumber=2 policyset.userCertSet.11.constraint.params.password.minSpecialChar=2 policyset.userCertSet.11.constraint.params.password.seqLength=6 policyset.userCertSet.11.constraint.params.password.maxRepeatedChar=3 policyset.userCertSet.11.constraint.params.password.cracklibCheck=false policyset.userCertSet.11.default.class_id=noDefaultImpl policyset.userCertSet.11.default.name=No Default
This policy allows to set:
-
password.minSize
- the minimum size for the passwor`d; -
password.minUpperLetter
- the minimum number of capital letters; -
password.minLowerLetter
- the minimum number of lower letters; -
password.minNumber
- the minimum number of digits; -
password.minSpecialChar
- the minimum number of punctuation characters; -
password.seqLength
- the size of substring sequence which cannot be repeated; -
password.maxRepeatedChar
- maximum number of repeating for each character; -
password.cracklibCheck
- a boolean to request an additional check with cracklib (it has to be installed if not present).If the constraint does not include specific configuration it will read the options from the `CS.cfg`. In the case the name is different, the prefix `password.*` is replaced by `passwordChecker.*`. The configuration in `CS.cfg` are used for all the passwords but each profile can overwrite to allow stronger or weaker passwords.
Key type and key size parameters can be configured as exemplified below:
policyset.userCertSet.3.constraint.class_id=keyConstraintImpl policyset.userCertSet.3.constraint.name=Key Constraint policyset.userCertSet.3.constraint.params.keyType=- policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521 policyset.userCertSet.3.default.class_id=serverKeygenUserKeyDefaultImpl policyset.userCertSet.3.default.name=Server-Side Keygen Default policyset.userCertSet.3.default.params.keyType=RSA policyset.userCertSet.3.default.params.keySize=2048 policyset.userCertSet.3.default.params.enableArchival=true
The two default server-side keygen enrollment profiles different in the authentication mechanism, where
- caServerKeygen_UserCert.cfg
-
contains empty value to "auth.class_id=", meaning that enrollment requests through this profile will require approval from a CA agent.
- caServerKeygen_DirUserCert.cfg
-
contains "auth.instance_id=UserDirEnrollment", meaning that the user is required to pass LDAP uid/password authentication; Such authentication mechanism is considered as an automatic certificate issuance as it does not require per-request approval from a CA agent.
Automatic approval could be configured by setting the auth.instance_id directive to any compatible authentication plugin class, as examplified in the caServerKeygen_DirUserCert.cfg profile mentioned above. Here is an example of such configuration in CS.cfg:
auths.instance.UserDirEnrollment.dnpattern= auths.instance.UserDirEnrollment.ldap.basedn=ou=People,dc=example,dc=com auths.instance.UserDirEnrollment.ldap.ldapconn.host=host.example.com auths.instance.UserDirEnrollment.ldap.ldapconn.port=389 auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn=false auths.instance.UserDirEnrollment.ldap.maxConns= auths.instance.UserDirEnrollment.ldap.minConns= auths.instance.UserDirEnrollment.ldapByteAttributes= auths.instance.UserDirEnrollment.ldapStringAttributes=mail auths.instance.UserDirEnrollment.pluginName=UidPwdDirAuth
The default Sever-Side Keygen enrollment profile can be found on the EE page, under the “List Certificate Profiles” tab:
Regardless of how the request is approved, the Server-Side Keygen Enrollment mechanism requires the End Entity user to enter a password for the PKCS#12 package which will contain the issued certificate as well as the encrypted private key generated by the server once issued.
Important
|
Users should not share their passwords with anyone. Not even the CA or KRA agents. |
When the enrollment request is approved, the PKCS#12 package will be generated and,
-
In case of manual approval, the PKCS#12 file will be returned to the CA agent that approves the request; The agent is then expected to forward the PKCS#12 file to the user.
-
In case of automatic approval, the PKCS#12 file will be returned to the user who submitted the request
Once the PKCS#12 is received, the user could use cli such as pkcs12util to import the PKCS#12 file into her/her own user internal cert/key database for each application. E.g. the user’s Firefox nss database.
If the enableArchival parameter is set to true in the certificate enrollment profile, then the private keys are archived at the time of Server-Side Keygen enrollment. The archived private keys could then be recovered by the authorized KRA agents.
Note
|
due to the nature of this mechanism, in case when enableArchival parameter is set to true in the profile, there are two KRA requests records per Server-Side keygen request: |
-
One for request type “asymkeyGenRequest”
-
This request type cannot be filtered at “List Requests” on KRA agent page; One could select “Show All Requests” to see them listed.
-
-
One for request type “recovery”