1 If you're running your own server, you're probably not shelling out
2 $400 to get an “official” Certificate Authority (CA) to sign your key.
3 Here's a quick note to myself about how to create, sign, and install
4 your own CA and key. Depending on your application, you can use
5 either the [[GnuTLS]] or [OpenSSL][] toolchain.
10 Following the [GnuTLS manual][gnutls-manual], create a certificate
11 authority with [certtool][], adjusting the `cn` as you see fit:
13 $ certtool --generate-privkey --outfile x509-ca-key.pem
14 $ echo 'cn = GnuTLS test CA' > ca.tmpl
15 $ echo 'ca' >> ca.tmpl
16 $ echo 'cert_signing_key' >> ca.tmpl
17 $ certtool --generate-self-signed --load-privkey x509-ca-key.pem \
18 --template ca.tmpl --outfile x509-ca.pem
20 Now generate the *unencrypted* server key.
22 $ certtool --generate-privkey --outfile x509-server-key.pem
24 And sign the key with your CA, adjusting the `cn` as you see fit, and
25 changing `dns_name` to match your fully qualified host name.
27 $ echo 'organization = GnuTLS test server' > server.tmpl
28 $ echo 'cn = test.gnutls.org' >> server.tmpl
29 $ echo 'tls_www_server' >> server.tmpl
30 $ echo 'encryption_key' >> server.tmpl
31 $ echo 'signing_key' >> server.tmpl
32 $ echo 'dns_name = test.gnutls.org' >> server.tmpl
33 $ certtool --generate-certificate --load-privkey x509-server-key.pem \
34 --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
35 --template server.tmpl --outfile x509-server.pem
37 You can also print certificates with [certtool][].
39 $ certtool --infile x509-server.pem --certificate-info
41 You can add alternate hostnames using [subject alternative
42 names][SAN]. Just add more `dns_name` entries to your template:
44 $ echo 'dns_name = other.gnutls.org' >> server.tmpl
45 $ certtool --generate-certificate …
47 You can verify a certificate if you can supply the whole certificate
50 $ certtool --verify-chain --infile x509-server.pem --infile x509-ca.pem
52 With versions of GnuTLS since 2.99.0 (released 2011-04-09), you can
53 verify against the global list of trusted CAs.
55 $ certtool --verify --load-ca-certificate /etc/ssl/certs/ca-certificates.crt --infile x509-server.pem
60 Use [openssl][]'s [genpkey][] to generate an *unencrypted* key.
62 $ openssl genpkey -algorithm RSA -out key.pem
64 An unencrypted key is less secure, but it allows the web server to be
65 restarted (e.g. after rebooting) without you being there to enter the
66 decryption key. Make sure `key.pem` is only readable by `root`.
68 Use [req][] to generate certificate signing request.
70 $ openssl req -new -key key.pem -out req.pem
72 `-new` prompts you for new relevant field values. You can also
73 specify the values on the command line or in an configuration file
74 (override the default with `-config filename`).
76 Use [x509][] to sign the certificate.
78 $ openssl x509 -req -days 365 -in req.pem -signkey key.pem -out cert.pem
80 You should keep your certificate signing request around so you can
81 re-sign your key later on (since your initial signature will
84 You can add subject alternative names to the request using
85 the `openssl.cnf` [config file][x509v3_config]:
87 $ cp /etc/ssl/openssl.cnf openssl.cnf
93 req_extensions = v3_req
97 subjectAltName = DNS:test.gnutls.org,DNS:other.gnutls.org
99 $ openssl req -new -config openssl.cnf -key key.pem -out req.pem
101 You can also print certificates with [x509][].
103 $ openssl x509 -in cert.pem -noout -text
105 You can verify a certificate if you can supply the whole certificate
106 chain with [verify][].
108 $ openssl verify cert.pem
113 We've been throwing around a lot of files with a [.pem][] extension.
114 These files contain [Base64][] encoded [DER][] certificates enclosed
115 between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`.
116 The `.crt` files requested by `update-ca-certificates` (discussed
117 below) are generally binary DER files, but can also be base64 encoded.
119 Downloading certificates
120 ========================
122 You can download certificates from remote servers using [[OpenSSL's
123 simple client|Simple_servers]]:
125 $ openssl s_client -showcerts -connect host:port
127 The PEM certificates will be printed to your terminal.
129 System wide certificates
130 ========================
132 The situation is confusing because there is currently no standardized
133 way to track trusted certificates. Here are some things to keep in
139 [[Gentoo]] uses [Debian][]'s [ca-certificates][] package to manage
140 trusted CAs. The certificates are stored under `/etc/ssl/certs` in
143 1. As a `<filename>.pem` symlink to the external certificate (if it
144 was already base64 encoded) or an encoded version (if the external
145 certificate is binary).
146 2. As a symlink to 1 named with the certificate's hashed subject name,
147 key identifier (if present), and serial number.
148 3. As an entry in `ca-certificates.crt`, which is a concatenated list
149 of all the trusted certificates.
151 You can update these system certificates using
152 `update-ca-certificates`, from the the `ca-certificates` package:
154 # update-ca-certificates
156 On Fedora-based systems, `update-ca-certificates` also [updates the
157 system NSS storage][fedora] at `/etc/pki/nssdb` (more on NSS in a
160 `update-ca-certificates` looks in a number of places to find trusted
161 CAs. To add a new CA, place the certificate in
162 `/usr/local/share/ca-certificates/` as a single file ending in `.crt`
163 and run `update-ca-certificates`.
167 In [[GnuTLS]], you set the list of trusted CAs using
168 [gnutls_certificate_set_x509_trust_file][]. By convention this
169 function is pointed to the `/etc/ssl/certs/ca-certificates.crt` file
174 OpenSSL loads trusted CAs with [SSL_CTX_load_verify_locations][],
175 which loads certificates from a file (like
176 `gnutls_certificate_set_x509_trust_file`) or from a directory (usually
177 `/etc/ssl/certs/`). For efficiency, many applications prefer the
178 directory approach, as certificates can then be loaded on an as-needed
179 basis using their hashed subject name, key identifier (if present),
180 and serial number. If you place a new CA this directory, you'll want
181 to run `c_rehash` to generate the hashed symlinks:
183 # c_rehash /etc/ssl/certs
185 OpenSSL doesn't currently provide a man page for `c_rehash`, but
186 there's one attached to [Debian bug 215618][215618].
188 `update-ca-certificates` (mentioned above) uses `c_rehash` internally
189 to generate hashed symlinks for OpenSSL.
194 [NSS][] is the crypto library used by [Firefox][] and [Chromium][]
195 that *doesn't* use the `/etc/ssl/certs` framework discussed above. It
196 [looks in a number of places][nss-places] depending on the package
197 type, but the system-wide `sql:/etc/pki/nssdb`. User applications
198 will also look in `sql:~/.pki/nssdb`. You manage the databases with
199 [certutil][]. You can install `certutil` on Gentoo by emerging
200 `dev-libs/nss` with the `utils` `USE` flag enabled. Add your
201 certificate with something like:
203 $ certutil -A -n jdoe -t "C,," -d "sql:${HOME}/.pki/nssdb" -i /etc/ssl/certs/cacert.org.pem
205 This adds a certicate (`-A`) to the `sql:${HOME}/.pki/nssdb` database
206 (`-d`). The certificate is named `jdoe` (`-n`), and you can use this
207 name to manage the certificate later (e.g. to delete it). `-t "C,,"`
208 sets SSL trust to `C`, but does not grant email or object signing
209 trust. `C` means you trust this certificate to issue SSL server
210 certificates (but not client certificates, which would be `T`), and
211 that you don't trust it for direct SSL authentication or email signing
212 (which would be `u`).
214 Unfortunately, many applications using NSS have a [compiled-in
215 list][certdata.txt] of trusted CAs, so you don't have complete control
216 from a sysadmin perspective unless you tweak that file at compile
220 [gnutls-manual]: http://www.gnu.org/software/gnutls/manual/html_node/Invoking-gnutls_002dserv.html
221 [certtool]: http://www.gnu.org/software/gnutls/manual/html_node/Invoking-certtool.html#Invoking-certtool
222 [SAN]: http://tools.ietf.org/html/rfc4985
223 [OpenSSL]: http://www.openssl.org/docs/apps/openssl.html
224 [genpkey]: http://www.openssl.org/docs/apps/genpkey.html
225 [req]: http://www.openssl.org/docs/apps/req.html
226 [x509v3_config]: http://www.openssl.org/docs/apps/x509v3_config.html#Subject_Alternative_Name_
227 [x509]: http://www.openssl.org/docs/apps/x509.html
228 [verify]: http://www.openssl.org/docs/apps/verify.html
229 [Debian]: http://debian.org/
230 [ca-certificates]: http://packages.debian.org/sid/ca-certificates
231 [.pem]: http://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions
232 [base64]: http://en.wikipedia.org/wiki/Base64
233 [DER]: http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules
234 [fedora]: https://fedorahosted.org/update-ca-certificates/browser/update-ca-certificates.8
235 [gnutls_certificate_set_x509_trust_file]: http://www.gnu.org/software/gnutls/manual/gnutls.html#gnutls_certificate_set_x509_trust_file
236 [SSL_CTX_load_verify_locations]: http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html
237 [215618]: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=215618
238 [NSS]: http://www.mozilla.org/projects/security/pki/nss/
239 [Firefox]: https://bugs.gentoo.org/325723
240 [Chromium]: http://code.google.com/p/chromium/wiki/LinuxCertManagement
241 [nss-places]: https://wiki.mozilla.org/NSS_Shared_DB_And_LINUX
242 [certutil]: http://www.mozilla.org/projects/security/pki/nss/tools/certutil.html
243 [certdata.txt]: http://comments.gmane.org/gmane.comp.mozilla.crypto/16347