This is part of a series on Digital Certificates.
I’ve casually mentioned a “Certificate Authority” earlier. What does this mean?
A “Certificate Authority” is the issuer in the “Public Key Infrastructure” (PKIX) system. It is actually composed of three components: a Registration Authority, a Certificate Authority and a Repository.
(Yes, one components has the same name as the whole. It’s usually not a problem since CA almost always refers to the whole.)
Casual implementations will put the three components in a single webapp but they have very different purposes and needs and should usually be split. At a minimum the architecture should reflect the internal structure.
The Registration Authority is the component responsible for collecting information about the subject, vetting it, deciding on the appropriate policy and making the final approval. If successful it tells the Certificate Authority to produce the certificate.
Departmental and small enterprise CAs have an easy job – they can hook into the employee or student registrar systems. Is the person known? What is their job description? Done.
Issuing certs for servers is a little more complex but the RA can require any request for a server cert be vouched for by an employee’s cert.
Public CAs need to vet people and organizations from public information. A minimal cert for a person may link an email address to a certificate by requiring the user respond to an email sent to the provided address. This gives you reasonable confidence that this is the right person but you have no confidence that any name associated with the email address is valid.
A stronger requirement is that the person provides a credit card for a token payment. In essence you’re asking the credit card company to vouch for the person. If the charge goes through you have reasonable confidence that you have the correct name and address for the subject.
Really strong authentication requires the subject come into an office, in person, and provide strong ID like a driver’s license or passport.
The subject’s public key is provided by a self-signed cert or (Netscape and possibly other browsers) a signed ‘request’. The subject demonstrates he knows the public key by signing the cert or request.
Businesses can usually be authenticated by checking public business records. This can’t be easily automated and that’s why server certs cost more than individual certs. Open source projects are weird entities since they often don’t have business records and I don’t know if there’s a good way to authenticate them. You can’t just say “go to their mailing list” since anyone can create a rogue mailing list. Fortunately most open source projects have their own websites and it’s possible to put up a document containing a RA-provided value to prove that the subject controls that site. This is one way Google authenticates domain ownership, for example.
The registration authority is also responsible for requests to revoke a certificate from the subject. For instance the subject may realize that its server has been hacked and it can’t guarantee that its private key hasn’t been stolen.
How does the registration authority indicate approval to the certificate authority? One technique is for the RA to issue its own short-lived cert. The certificate authority can then copy all of the information to its own certificate before signing it and passing it on to the repository.
Email accounts are hacked. Credit card information is stolen. Even business identity theft can happen. On a jury I would say there’s a preponderance of evidence but reasonable doubt short of measures like having the subject appear, in person, with a strong ID.
Another vulnerability is an attacker putting unauthorized approvals into the work queue for the certificate authority. This is a strong reason for keeping the certificate authority workqueue in a different database than the repository authority’s database. Fortunately this can be punted – either call the certificate authority directly (e.g., via a REST call) and let it handle it or hand the certificate off to a JMS server.
Finally the repository authority should maintain its own certificates in a secure location like a filesystem-based keystore. Never in the database itself.
The certificate authority is responsible for creating certificates based on the information provided by the registration authority. It can change the extensions based on policies associated with the signing certificate but it will generally create certificates based entirely on what the RA provided it.
There are four broad categories for how certs are signed.
- Low value certs can be signed by an entirely automated process using code similar to what I published in the last post.
- Medium value certs can require that an employee explicitly provide the decryption password for the issuing private key. This often requires the employee to be sitting at a console on the certificate authority.
- High value certs can require that multiple employees explicitly provide decryption passwords. One employee is not enough.
- Alternately high value certs can require the certification be signed by specialized hardware that never exports the private key. The higher the value the better the hardware. The details of how the hardware gets approval to issue the certificate vary by the hardware.
Certificate authorities are also responsible for signing Certificate Revocation Lists (CRLs) and (maybe) OCSP records. These are used to inform others that a certificate has been revoked.
The signed certs are passed on to the repository.
The certificate authority should not be publicly available.
The certificate authority may get unauthorized approvals in the workqueue from the repository. It should consider performing its own sanity checks.
Again the certificate authority should maintain its own certificates in a secure location like a filesystem-based keystore. Never in the database itself.
Tighter security in the workqueue
With a little work it is possible to have much tighter security in the workqueue. Instead of the repository making blind submissions to the workqueue it can use a three-step process.
- Request a random nonce from the certificate authority
- Embed the nonce in the approval certificate, e.g., perhaps as a subject alternate name.
- Put the approval certificate in the workqueue.
The certificate workqueue has a corresponding process.
- Receive a nonce request from the registration authority. Create one and bind it to the subject DN in some way. (Use an HMAC digest of the subject DN as the nonce. This has the benefit of eliminating the need to maintain a local database.)
- Receive the approval certificate in the workqueue.
- Verify that the nonce is in the approval certificate.
This process seems burdensome but should be fairly easy to implement and will dramatically improve the security of the workqueue.
The repository is responsible for publishing the cert. It usually does this by some combination of HTTP, FTP and LDAP. It is also responsible for publishing Certificate Revocation Lists (CRLs) and OCSP.
Another option is providing a REST interface and an implementation of a java.security.cert.CertStore that maintains a local cache and will call the REST service for unfamiliar certs. This has the benefit of being standard and easily tested.
The repository is pretty dumb overall but the database behinds it needs to be very intelligent in order to prevent attackers from seeding it with unauthorized certificates.
If the database behind the repository is compromised than the repository will feed unauthorized certs to users. One countermeasure is to maintain a list of approved root certificates in a local KeyStore and validate all certs before returning them to the caller. This will substantially improve the effort per request but that may be acceptable on lower volume repositories.
The repository may be subjected to denial-of-service attacks.
The repository may be subjected to unintentional denial-of-service attacks with naive use of OCSP requests by clients.
Database security is crucial and in fact it appears to be a high risk factor for my efforts to deploy a prototype to the Google App Engine. (No final determination yet since Google is still working on a mysql-like database interface.)
The wrong way to do things is to extract the different attributes in a certificate and use normal object persistence to write the values to the database.
One right way to do things is to lock down the certificate table to revoke all INSERT, UPDATE and DELETE rights. Instead certificates use stored procedures:
INSERT: extract the cached values and use them to populate the appropriate columns.
UPDATE: certificates are never modified. Ancillary information, e.g., revocation date and reason, can be updated by a stored procedure.
DELETE: again certificates are never modified. A stored procedure can be used for soft deletions.
A variant is to use triggers that overwrite the cached fields on insertions and refuses to change those columns on updates. This has the benefit of allowing us to continue using ORM frameworks.
It’s important to remember that database backups and restorations sidestep stored procedures. You can lock the SQL but still have unauthorized certs put into the repository’s database by rogue administrators.
As always one database user should own the table and stored procedure and a different database user should own the data but have no rights to modify the table or stored procedures.
For More Information
Danger, Danger, Will Robinson!
If you read nothing else in this series, read this!