Certificate authority module in CzechIdM, part1 – the overview
Many companies use an on-premise certificate authority (CA) for their internal purposes. Without a doubt, one specific function of the certificate authority in a company is handling users’ certificates. Those certificates are bound to physical persons and as such, they fit neatly into the identity management problematics.
For this reason, CzechIdM implements the CA functionality in the form of a module. In this short series of posts, we will describe basic workings of our CA implementation and how it can be fit into the company’s infrastructure.
The whole certificate authority, strictly speaking, consists of three parts – the registration authority, the certificate authority and the validation authority. Some of those parts, depending on the implementation, may be coupled together.
- Registration authority (RA) – Takes care of the entity (i.e. person, domain owner, …) verification and all the processes around it. This part takes care of person’s ID validation or domain ownership validation, etc.
- Certificate authority (CA) – Signs certificate requests and issues certificates. When necessary, it revokes certificates too.
- Validation authority (VA) – A service that validates certificates. Basically anyone can query it about the particular certificate’s status. Nowadays, validation is performed by means of CSR files and OCSP responders.
First, we will be implementing the execution engine – the CA part.
Certificate authority in a company
The certificate authority can have multiple levels. In case of a small company, the one-level CA may be completely fine but when the company is bigger, implementing multi-level CA hierarchy is necessary. We deem the two-level CA to be sufficient for most companies, unless they are really huge or their organizational structure is somewhat special.
In the infrastructure, there are multiple places where we need (or have to) use certificates:
- Certificates for users – Those are mainly for authentication and mail/document signing.
- Certificates for infrastructure services – For example directory services (LDAPS protocol) and encrypted database connections, for mail servers (SMTPS).
- Certificates for user services – The mail servers’ certificate, various website HTTPS certificates and so on.
From this point of view, we have at least three “classes” of certificates which will definitely differ in some of their attributes (i.e. KeyUsage). It would be very nice to have preconfigured CA that just gives out the certificates with correct attributes automatically. This brings us to multi-level CA (actually two-level) which looks like this:
- Root CA – This CA signs other “issuing” authorities, nothing else. Certificate of a Root CA lasts for a very long time (usually about 15-20 years). The private key is stored offline in a safe and is used only to (re)issue a certificate of a Issuing CA.
- Issuing CA 1, …, Issuing CA n – These authorities issue end certificates (for users, servers, you name it). Their validity is usually about 5 years. Their private keys are kept on-hand in the CA software.
This setup is handy not only because we can configure each CA to give out specific certificates. We can also appoint separate administrator to manage particular CA. When things go south and the CA is breached, we have to revoke certificates for only the part of our infrastructure (say, only for servers) which is definitely better than “revoke everything”. The list goes on.
Ordinary user friendliness
To be absolutely correct (security-wise), each of us should generate his/hers own private key, create the corresponding CSR and then let the CA sign it. Sadly, we cannot expect this from ordinary users. For them, the CA should do the job, although it is a security problem – at some point in time, CA holds the unencrypted private key of a user and we must trust it not to make a copy and then not to use it for doing shenanigans in user’s name.
Some certificate authorities, mainly those that do serious business, use crypto token for storing the CA’s private key. Such a token can look like an USB Flash Disk, for example. Point of the token is that private key stored therein cannot be gotten out in any way possible, even if it would mean physically disassembling the token. All crypto operations that are needed are sent to the token which does the actual computation (like signing,…).
Crypto tokens usually come with a library which provides the PKCS#11 interface. In the operating system, we install a library (.so, .dll) which provides the PKCS#11 interface to the crypto software on one side, and which translates calls to token-specific call on the other. On Linux, we can give a simple example with OpenSSL and SoftHSM. (Please note the SoftHSM is just a software emulation of the HW device.) Using libsofthsm2.so we will dynamically link it with openssl command like this (CentOS7):
[root@ca ~]# openssl engine -t dynamic -pre SO_PATH:/usr/lib64/openssl/engines/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so -pre VERBOSE (dynamic) Dynamic engine loading support Success: SO_PATH:/usr/lib64/openssl/engines/pkcs11.so Success: ID:pkcs11 Success: LIST_ADD:1 Success: LOAD Success: MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so Loaded: (pkcs11) pkcs11 engine [ available ]
Certificate authority SW requirements
So far, we have been brainstorming a bit – about an architecture of the CA, about the users, about the private key security. It is time to wrap it up in functional and non-functional requirements which we will use in the next part of our series where we will actually implement the CA software. Given a bit more time, the requirements turned out to be:
User can generate private key and certificate using the CA.
User can supply CSR which the CA then signs.
User/admin can revoke a certificate.
User/admin can prolong a valid certificate
User can search through certificates.
User/anyone can validate a certificate.
User can download his own certificate and private key (in a bundle).
User can download his own certificate.
User can download his own certificate and private key, with CA chain (in a bundle).
User can download his own certificate with CA chain.
- User/admin can search through issued certificates.
- RESTful API which the Registration Authority will use.
- User authentication, privileges handling.
- It is possible to disable some REST endpoints of the CA (e.g. to prevent CA from issuing new certificates).
- When generating private key, the user must supply the private key passphrase. CA then encrypts the private key with the passphrase. This allows us to generate user’s private key and store it in the authority, but the key is inaccessible to anyone but the user. When downloading the private key, the user must supply the passphrase again. If he doesn’t, the CA will refuse to give him the bundle.
Private key of the authority can (will) be stored in the HSM.
CA offers the Validation Authority function by at least providing the CSR.
- There can be multiple CAs on the machine, each one separated from the other.
- CA validates user info and CSRs in terms of SubjectDN components and signature algorithms.
CA will issue certificates with SHA-256 signature or stronger. CSRs with weaker signature than SHA-256 will no be signed.
CA supports validation of supplied CRT.
In this post, we presented some of the architecture and security hints and requirements we had in mind when we were designing our certificate authority implementation. In the next post, we will already get our hands dirty – we will implement the CAW, our execution engine.
If you have any questions about certificate authorities, certificates or our particular implementation, please let me know on firstname.lastname@example.org. Also join our google group to keep in touch with CzechIdM news or comment on redmine, github. Also you can join our meetup group.