Certification authority [ca]
CA module was designed to handle a certificate authority implementation. The goal is to support various CA implementations through the specific "drivers".
Currently, there is only one driver implemented - the CAW driver ( add public url).
Conceptually the certificate authority consists of three parts:
Registration Authority (RA) - handles identity validation, processes for certificate issuance,
GUI
Certificate Authority (CA) - issues certificates and CRLs
Validation Authority (VA) - handles validation requests, in our solution implemented together with CA by means of Certificate Revocation Lists
Certificate Authority module features
Certificate authority
GUI is built atop the CzechIdM web interface.
User can request a certificate for himself only if he has a role which allows it. A role can be granted to users automatically or the users can request it through standard fucntionality of the identity manager.
Certificate authority can work with supplied CSRs and it can also generate private key and certificate for ordinary users. When generating the certificate, a user must supply a passphrase. User's private key is encrypted with this passphrase when stored in the certificate authority - nobody, even admin, can acces it without the passphrase.
User can download his certificate as many times as he wishes. If he chooses to download certificate bundled with private key, he must supply the same passphrase as he did when he was generating the key.
User must fill out a request form (with request reason) when requesting a certificate.
User can prolong his certificate. This functionality can be disabled. Expired and revoked certificates cannot be prolonged.
User can revoke his certificate.
User can validate any certificate.
User's request for a certificate has to be approved first (i.e. by his manager). Configurable.
Administrator can reqest a certificate in the name of an user.
Administrator can revoke any certificate.
Administrator can download any certificate.
User's certificates are automatically revoked upon user's contract termination.
CA module notifies user/administrator/both if the certificate is about to expire.
CA module notifies user/administrator/both if a certificate was revoked.
CA module notifies user/administrator/both if a new certificate was issued.
CA module automatically handles issuing CRLs.
CA module issues certificates signed by its private key.
User can download a certificate in PKCS#12 format, with or without bundled certificate chain.
CA module has a RESTful
API.
Validation authority enables everybody to check if a certificate is valid. It is realized by CRL which is downloadable on a web
URL.
Third-party applications using CRLs has to refresh their CRL copy on a regular basis. OSCP support is not guaranteed.
Building the module
The CA module is now only for private access and it isn't possible to download the module from the CzechIdM repository directly.
Go to your module folder:
cd Realization/backend/ca
And just execute the build process with maven:
mvn clean install
After the build process completes, the resulting JAR file will be placed in target folder and also in the local maven repository (by default ~/.m2).
Development
For easy development, import all projects from github repository (core, acc, parent, app, …) and then import the CA module. Insert this dependency into app pom.xml file (into your active spring profile, for example dev):
<dependencies>
...
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>idm-ca</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
Installing the CA module
After successful build of the CA module, it is necessary to copy resulting JAR file into CzechIdM WAR file (folder: <warfileroot>/WEB-INF/lib/).
CA settings
Setting the CA up is done by configuration properties. Every instance of the driver (= every instance of the CA which is to be managed) has its own unique identifier (<CA_INSTANCE>). Unique identifier cannot contain dot .
character - is used as internal configuration separator.
Property file:
# identifier
idm.sec.ca.authority.<CA_INSTANCE>.identifier=<CA_INSTANCE>
# DN for CAW
idm.sec.ca.authority.<CA_INSTANCE>.dn
# Complete path to CAW implementation
idm.sec.ca.authority.<CA_INSTANCE>.script.path
Suppose we have two CAW-managed certificate authorities "CA1_users", which we alias "users" in the module, and "CA2_web_servers" which we alias "web". Those names are then used in the RESTful API.
The configuration is as follows:
# CA1_users
idm.sec.ca.authority.users.identifier=users
idm.sec.ca.authority.users.dn="C=CZ, ST=Czech Republic, L=Prague, O=BCV, OU=TEST, CN=CA1_users"
idm.sec.ca.authority.users.script.path="/path/to/users/ca/caw"
# CA2_web_servers
idm.sec.ca.authority.web.identifier=web
idm.sec.ca.authority.web.dn="C=CZ, ST=Czech Republic, L=Prague, O=BCV, OU=TEST, CN=CA2_web_servers"
idm.sec.ca.authority.web.script.path="/path/to/web/servers/ca/caw"
REST api
method | ENDPOINT | description |
GET | /ca/authorities | All available certification authorities |
GET | /ca/authorities/<CA_INSTANCE>/search/quick | List of all certificate by given certification authority |
DELETE | /ca/authorities/<CA_INSTANCE>/certs/<CERT-SERIAL-NUMBER> | Revoke given certificate by serial number |
POST | /ca/authorities/<CA_INSTANCE>/certs/<CERT-SERIAL-NUMBER>/get | Return certificate as PEM |
GET | /ca/authorities/<CA_INSTANCE>/certs/<CERT-SERIAL-NUMBER>/renew | Renew given certificate by serial number |
GET | /ca/authorities/<CA_INSTANCE>/certs/<CERT-SERIAL-NUMBER>/status | Get status for certificate by serial number |
POST | /ca/authorities/<CA_INSTANCE>/generatePair | Generate certificate by given information in DTO, return serial number |
POST | /ca/authorities/<CA_INSTANCE>/signCSR | Sign given certificate CSR, return serial number |
POST | /ca/authorities/<CA_INSTANCE>/validateCert | Validate given certificate |
More information about CA module REST can be found in swagger documentation.
In next version there will be FE configuration implemented (every driver will have its own configuration properties).
The CAW driver
The CAW driver is our native certificate authority driver. In essence, it is a shell script encompassing ordinary OpenSSL certificate authority. This has many pros:
If you can do it in openssl.cnf, you can do it in CAW too.
Supported on any Linux/UNIX platform which has openssl, bash and coreutils.
Readable script that is easy to debug and fix. Anyone can do it.
You can migrate almost any existing CA into the CAW.
Migrate certificates, keys and CSRs. Each of those files have to be named by serial number of the corresponding certificate.
Construct openssl certificate db (plain text file of given format). If you have the data, this can be done with a few hours of scripting.
Native support for PKCS#11 crypto tokens.
Also, we give out almost totally preconfigured CAW instance and installation instructions.
Also, the deployment is simply unpacking CAW into a folder. Need another CA instance? Unpack CAW into another folder.
It also has some cons:
There are plenty of bad openssl.cnf tutorials on the internet. Seriously. We are fighting it by heavily commenting the CAW-supplied configuration but that is basically all we can do about it.
OpenSSL integration with PKCS#11 tokens is not something that "just works". It may be version-, token- or distribution-dependent. But if you make it work with plain openssl, you can easily integrate it into CAW.
The CA is not concurrent. The CAW handles it by pessimistic locking.
The CAW script
CAW is a shell wrapper above the OpenSSL-based certificate authority (abbreviated: OSSL CA). It allows you to use the OSSL CA in a similar way the EasyRSA does.
CAW is primarily created as a CA backend for the CzechIdM Certificate Authority module but it is possible to extend/incorporate it somewhere else. It also provides an user-friendly CA implementation which can be used right away from the command line.
For the list of capabilities and input/output formats, please refer to the CAW shell script. Simply run CAW to get the usage screen where you can find everything you will ever need. :)
./caw
Unknown command '' specified.
Usage: ./caw command [--param1 value1 --param2 value2 ...]
...
COMMAND create-key-and-cert - generates new private key, CSR and signs a certificate
OUTPUT
Success: Serial number of the issued certificate written onto STDOUT. Return code 0.
Error: Error message on STDERR. Return code 1.
PARAMETERS
--country countryName. Mandatory.
--state stateOrProvinceName. Mandatory.
--locality localityName. Mandatory.
--org organizationName. Mandatory.
--ou organizationalUnitName. Mandatory.
--cn commonName. Mandatory.
--mail emailAddress. Mandatory.
--pass private key passphrase. Mandatory.
... and so on ...
In its core, CAW uses a well-known OSSL CA all with its openssl.cnf file and such. Therefore every configuration which can be specified in openssl.cnf can be made available in the CAW. CAW makes use of openssl.cnf as often as possible (i.e. with defaults for the openssl req command) and very often invokes openssl using -batch argument.
But beware, CAW has also its own configuration file caw_settings.source. This file contains some options that need to be in sync with options in openssl.cnf. So if you are fiddling with openssl.cnf, always also check caw_settings.source.
Additional information can be found in one of those three places:
In the CAW usage page. Simply invoke ./caw.
As a comment in the caw_settings.source file.
As a comment in the CAW script itself (i. e. authors, changelog, TODOs).
Core functions
Self-contained CA
CAW does not depend on the global /etc/openssl.cnf, it brings its own openssl.cnf along. That means, your CA is completely separated from others.
You can run different CAs just by giving each its own folder.
Installation is merely unpacking a tarball and generating CA certificate and starting serial number.
Handling concurrency problems
Private key and CSR private storage
Support for hardware tokens using PKCS11
Unix-like style of invocation
Everything that goes into the CAW is a command line argument. Everything that goes out of the CAW is either a output of successful operation (on STDOUT) or an error (on STDERR).
Return code for successful operation is 0, for error it is 1.
All information going to/from CAW is in printable form, large data mainly as PEM or base64-encoded.
Usable as a root or intermediary CA
Private key and certificate creation
CSR signing
Certificate prolongation
Because CAW stores CSRs, it is possible to prolong certificate by reissuing it with new validity period. All that is needed is certificate's serial number.
CAW will not allow the expired/revoked certificate to be reissued.
This is not a big security risk because for access the CSRs, an attacker must have access to the machine running the CA. If he does, you have much bigger problem than some accessible CSR.
Certificate revocation
Certificate database querying
Certificate bundling
When the issued certificate is requested for download, user can specify if he wants it to be bundled with private key and/or whole certificate chain.
When requesting the bundle with private key, user must specify the password he has given during the certificate creation.
CRL issuing and publishing
Housekeeping tasks
Installation
Create separate user for your authority.
Ensure that no other user can read the home directory. This happens for example on the (open)SuSE where each home is granted to the
users group which encompasses all users.
[root@ca ~]# useradd -r -m -s /bin/bash authority1
Move the CAW directory to the user's home.
[root@ca ~]# mv caw.tgz /home/authority1/
[root@ca authority1]# tar xzf caw.tgz
[root@ca authority1]# ll
total 28
drwxr-xr-x 4 1000 users 4096 Aug 24 14:36 caw
-rw-r--r-- 1 root root 24563 Aug 24 15:16 caw.tgz
[root@ca authority1]# chown -Rf authority1:authority1 caw/
[root@ca authority1]# chmod 750 caw
Ensure that
caw script is runnable.
[root@ca authority1]# cd caw/
[root@ca caw]# chmod 750 caw
Create new starting serial number. This number can be, say,
01 but there is a caveat attached to this - OpenSSL then works with 8bit serial mode (
this is potentially dangerous). Better way is to create truly random 128bit serial number as the example shows.
[root@ca caw]# cd ca/
[root@ca ca]# openssl rand -hex 16 > serial
If you want to use serial number prefixes, now it is the time to set it up. If you don't know what it is, you can safely skip this step. Suppose the random serial was b1676557ad077ef7144c227d16a55025. Then we simply edit the starting serial to have our desired prefix (say, aaaccc000). Total length of the serial number must remain 128b, so our new serial will be aaaccc000d077ef7144c227d16a55025. Write it into the serial file. We can, possibly, overflow to the prefix aaaccc001 so be aware of it - our "prefix" is not a real prefix. It is merely a cleverly chosen starting number.
Generate your CA certificate the usual way. For how to set it up with PKCS11 crypto token, see the end of this document.
Select the appropriate private key size. Also, there are x509v3 certificate extensions which are handy to have in the authority's certificate. Default are in
ca_crt.extensions file. Edit them (and command line parameters in the example below) according to your needs.
[root@ca ca]# su - authority1
[authority1@ca ~]$ cd caw/ca/
[authority1@ca ca]$ pwd
/home/authority1/caw/ca
[authority1@ca ca]$ openssl genrsa -out private/ca.key 2048
[authority1@ca ca]$ chmod 400 private/ca.key
[authority1@ca ca]$ openssl req -new -in private/ca.key -out ca.csr -key private/ca.key
[authority1@ca ca]$ openssl x509 -req -in ca.csr -signkey private/ca.key -days 1000 -out ca.crt -sha256 -extfile ../ca_crt.extensions
[authority1@ca ca]$ rm ca.csr
CAW folder comes with a number of empty directories. Although needless now, they are automatically used by the caw script for managing the authority. Do not delete them.
Check the ca_openssl.cnf configuration file and configure your authority. This file is an ordinary openssl.cnf, but is realized in local variant. This enables multiple caw-based CAs to coexist one along the other just by separating their directories. The ca_openssl.cnf contains preconfigured CA so only small adjustments should be necessary. Follow the comments in the file itself. The most important things to set up are:
Enable (configure) the PKCS11 engine or disable it entirely (comment it out).
Configure default_days and default_crl_days and other certificate-related settings.
Configure parameters in the req stanza - those are used for generating new keys and requests.
Configure certificate extensions in the issued_cert_ext stanza. Do not forget to set up the crlDistributionPoints correctly.
Check the caw_settings.source configuration file and configure it accordingly. The tricky part there is that some settings have to have the same values as in ca_openssl.cnf. Again, the comments in the file will help you. The most important things to set up are:
Configure CA_OSSL_ENGINE_PARAM if you want to use PKCS11 token. Set it to an empty string if you store the CA's private key in the file.
Configure the CA_OSSL_ROOT_CHAIN if your CAW authority is not the root authority.
Configure the SubjectDN and CSR validation prefixes. This also lets you set a basic policy for user's passphrase complexity. Also, set allowed signature algorithms.
Generate the empty CRL file.
[authority1@ca caw]$ ./caw create-crl
You should be good to go. Follow the examples and try to obtain your first certificate.
Examples
Create private key and certificate
[root@ca ~]# ./caw create-key-and-cert --country CZ --state "Czech Republic" --locality Prague --org BCV --ou TEST --cn user.test.bcv --pass demodemo
0C0774BACDF2CA2A52BEEF68A0F1D411
Prolong certificate
[root@ca ~]# ./caw prolong-cert --serial 0C0774BACDF2CA2A52BEEF68A0F1D411
0C0774BACDF2CA2A52BEEF68A0F1D412
Download (private key,certificate,certificate chain) bundle from the CA
[root@ca ~]# ./caw get-cert --serial 0C0774BACDF2CA2A52BEEF68A0F1D411 --with-pkey --pass demodemo --with-chain
MIIKoQIBAzCCCmcGCSqGSIb3DQEHAaCCClgEggpUMIIKUDCCBQcGCSqGSIb3DQEHBqCCBPgwggT0
...
FbAM6nS5jJYQ4s4VKDElMCMGCSqGSIb3DQEJFTEWBBRGj5/LUBZtcz/k+N96L7RzdleanDAxMCEw
CQYFKw4DAhoFAAQUCqImx0Un2qmtSACpEWD4i2ivunMECFJnEuzDIEtHAgIIAA==
Revoke a certificate
[root@ca ~]# ./caw revoke-cert --serial 0C0774BACDF2CA2A52BEEF68A0F1D411 --reason keyCompromise
Refresh the CRL
[root@ca ~]# ./caw create-crl