After heartbleed I had the opportunity to redo all of my certificates; while I was at it I decided to try to be a CA the right way (or at least righter).
A lot of information that I found was lacking, or incomplete, dated, or just wrong. I am documenting this mostly for my benefit for when I need/want to do this again.
Step 1 is obviously creating the CA itself. To do that you need to edit the openssl.cnf file to make some changes.
- Set your HOME this is where the CA client stores a bunch of “stuff”
- in CA_default set the dir to an absolute path where your CA will store its files
- set copy_extensions to “copy”. It says you need to be careful with this because this means that anyone (you?… its your CA isn’t it?) can add x509 extensions to the CSR and you’ll sign them (if you don’t check carefully, it still shows them to you before verifying the signing). Normally a CSR is stripped down to just the subject before signing, and the CA adds any extensions that you specify, but its messy to always be specifying that on the CA (especially for things like SubjectAltNames), and it really does belong where the CSR originates. Just be careful, and don’t be dumb.
- set default_days.. I like not having to deal with this for long periods of time.. so I have mine at 3650
- Update your policy_match as you like it. levels are match, supplied, and optional; and probably something for ‘not supplied’.. but I am not going to look it up
- set default_bits. Again, I like not needing to deal with this for long periods of time, so 4096!
- set the req_distinguished_name to provide convenient defaults for you
- big one, in usr_cert add the following, this is where you’re a real CA (well, kinda)
authorityInfoAccess = @ocsp_info crlDistributionPoints = @crl_info
- Create the referenced sections above
[ ocsp_info ] caIssuers;URI.0 = http://ca.dcrosstech.com/cacert.pem OCSP;URI.0 = http://ca.dcrosstech.com/ocsp
[ crl_info ] URI.0 = http://ca.dcrosstech.com/crl.pem
- in v3_req set (these should be set on the clients where you generate keys)
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth
- in v3_ca
authorityKeyIdentifier=keyid:always,issuer:always basicConstraints = critical,CA:true keyUsage = critical,digitalSignature,cRLSign, keyCertSign subjectAltName=email:copy issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always
This is your basic CA conf. Now before you make your CA cert you need to make a one-time edit (to be undone when your CA is setup
in [ req ] set x509_extensions = v3_ca, and comment out req_extensions
Now make your CA cert:
First you need to create the directories for the openssl CA program to work in, remember to set modes appropriately.
These directories are:
Create db files for the CA to work with
- touch $BASE/index.txt
- echo 1000 > $BASE/serial
Make your CA private keyfile
openssl genrsa -aes256 -out $BASE/private/cakey.pem 4096
Make the CA!
openssl req -new -x509 -days 7305 -extensions v3_ca -key private/cakey.pem -out cacert.pem -config YOUR_OPENSSL_CA.cnf
edit your openssl.cnf file to put those extension lines back (remove the v3_ca and add the v3_req)
openssl ca -config YOUR_OPENSSL_CA.cnf -in REQFILE -out CERTFILE