This repo contains helpful and easy to use utilities for managing the public key infrastructure (PKI) at your organization, or for yourself. You can do a lot here:
- Generate a Root Certificate Authority
- Create Intermediate CAs, like a TLS, Code-signing, or Email CA
- Sign and issue web server certificates for your domains
- Create personal email and browser PKCS-12 certificates for email and web-based authentication
This project heavily utilizes OpenSSL and requires Bash.
- Introduction
- Creating a Root Certificate Authority
- Creating Intermediate Certificate Authorities
- Creating a Web SSL Certificate for a Domain
- Creating a Client SSL Certificate
- Final Notes
All of the utilities are in the bin directory. These files use the config
files in the etc directory. There's no reason to ever edit any thing in these
two folders.
When you run the tools, they will create the folders ca, certs, and crl.
These will contain your generated certificates, private keys, certificate
signing requests, certificate revocation lists, database, and serial files that
OpenSSL generates.
The first thing you'll want to do is create the Root CA. This is the master certificate and key that will sign all of the Intermediate CAs. Intermediate CAs are the TLS CA for signing both web server and web client certificates, the Software CA for signing software packages, and the Email CA for signing S/MIME certificates.
Structuring your PKI hierarchy this way allows the Root key to stay private or behind multiple layers of security. The Intermediate keys, if ever exposed, could be revoked without putting the entire system in jeopardy. This is a best practice that we'll adhere to in these utilities.
Update the config file in this directory to have the correct names and info.
These names will be embedded into the certificates.
To generate the Root CA:
$> ./bin/root-ca.sh
This will guide you through the set-up process. It will create the following files and folders:
/caCertificate Authority files/root-caRoot CA files, certificates and signing requests/dbRoot CA database and serial files/privateKey files, this is untracked in gitRootCA.keyPrivate key file for Root CA
RootCA.crtCertificate fileRootCA.csrSigning request file
/crlCeritificate revocation listsRootCA.crlPublic revocation list file, this should ultimately go on your webserver. The URL will be embedded into certificates.
Now that we have the Root CA, we'll create all of the Intermediate CAs. The only required one to finish this guide is the TLS CA but it's simple to generate them all.
3.1 Run Utilities
To generate the TLS CA:
$> ./bin/tls-ca.sh
This will guide you through the set-up process. It will create the following files and folders:
/ca/tls-caTLS CA files, certificates and signing requests/dbTLS CA database and serial files/privateKey files, this is untracked in gitTLSCA.keyPrivate key file for Root CA
TLSCA.crtCertificate fileTLSCA.csrSigning request fileTLSCAChain.pemChained certificate file containing the Root and TLS CA certificates.
/crlTLSCA.crlPublic revocation list file, this should ultimately go on your webserver. The URL will be embedded into certificates.
Similar files are created for the other two Intermediate CAs. To generate the Software CA:
$> ./bin/software-ca.sh
To generate the Email CA:
$> ./bin/email-ca.sh
The TLS CA is used to sign web server certificates, which is the most common application and use-case for PKI and probably why you're here :P
Creating a new server certificate is simple, and you can just follow the on-screen instructions. Just make sure to read the few instructions included. Please remember these three things:
- The fully qualified domain name (FQDN) is usually of the form www.domain.com.
- When adding FQDNs at the beginning, add both the www and non-www domains. For example, both www.example.org and example.org. The script will prompt you to add as many as you'd like. You can probably even do a wildcard but I haven't tested that yet.
- When adding the
Organization Nameduring the CSR questions, make sure it's the same "Company Name" you have in yourconfigfile. Otherwise, the process will halt and you will have to start over! This is an OpenSSL quirk.
To generate a new web server certificate:
$> ./bin/server.sh
This will create the following files and folders:
/certsServer and client files/tls-caTLS CA signed files/privateKey files, this is untracked in gitexample.org.keyPrivate key file for your web domain. Your web server will need this file.
example.org.crtWeb domain certificate fileexample.org.csrSigning request fileexample.org.bundle.pemCertificate bundle containing the server's signed and issued certificate, the Intermediate TLS CA's certificate, and the Root CA's certificate. Your web server will need this file.
An often unused, but very powerful security mechanism is PKCS-12 client
certificate authentication. These are certificates issued to people or devices
that are signed by the Intermediate CA and grant that person or device access to
the web server. In nginx, this is done by using ssl_client_certificate and
pointing that config optionto the TLSCAChain.pem file copied to your web
server.
This utility will generate a password protected .p12 file that the user can
import into their web browser. You can then set up your web server to optionally
require a client certificate for access. This client certificate replaces the
need for the user to keep a password and provides greater security to any
application.
To generate a client certificate:
$> ./bin/client.sh
Here are some helpful notes:
- This will prompt you to create a password for the client's private key. Make sure you enter one at least 4 characters long or the script will halt.
- During the CSR process, it will ask your for the "Organization Name". Make
sure this is the same as the "Company Name" in the
configfile. - During the CSR process, enter the user's name into the "Common Name" field, and enter their email address into the "Email Address" field.
- You will need the TLS CA private key password to sign this client certificate.
The following files are generated:
/certs/tls-ca/privatestallman_richard.keyPrivate key file for the client.stallman_richard.p12P12 browser bundle file. This needs to be imported into the browser along with the trusted Root CA certificate file.
stallman_richard.crtClient certificate filestallman_richard.csrSigning request file
At the end of the script, you are asked if you want to generate a "client
certificate bundle". This is the .p12 file from earlier. If you do this, you
will be prompted for a name to embed into the file. This name will display to
the user when they are asked by their browser to select a certificate.
You do not need to enter an export password but it is strongly recommended that
you do. The .p12 files should be treated like private keys since they contain
both the public and private key parts.
Always make sure .key and .p12 files remain untracked. This is automatically
done for you through .gitignore files but it's important that you know this.
These files should also be chmod 400 to protect them on the web server.
Your web server will want the example.org.key and example.org.bundle.pem
files for it to load the SSL correctly. If you're using client certificates,
also copy over the TLSCAChain.pem file.
Once you create a server certificate, your browser will not immediately trust
it. To do this automatically for all server certificates that you create, add
your Root CA certificate file to your browser's list of trusted authorities.
This is the file RootCA.crt (or similarly named) in the ca folder.
If you're on MacOS, double click this file and make sure you open it again in KeyChain, expand the Trust tab, and ensure that everything is always trusted.
For Chrome, go to Settings -> Show Advanced Settings -> Manage Certificates. This will prompt KeyChain in MacOS or show you a window with an Authorites tab. If you see the Chrome Certificates window, then go to the Authorities tab and click "Import" and select the Root CA certificate file. Make sure you trust this authority.
For Firefox, go to Preferences -> Advanced -> Certificates and click "View Certificates". Click the Authorities tab and then click "Import" and select the Root CA certificate file. Make sure you trust this authority.
You may need to restart your browser for this to take effect, since SSL is often cached.
Here is a list of the current limitations and planned updates:
- There's no way to revoke certificates really. This is needed to be added as as a command in some of the scripts.
- CRLs would then need to be inspected to see if they're working with the revokations. CRLs are also difficult to get onto a public web server. This problem, if solved, should be documented here.
At this point, it's still somewhat unclear to me what the databases and serial files are that get generated. I think I need to spend more time with revokations to understand that.