Add subj. alt. names and certificate installation to X.509 post.
authorW. Trevor King <wking@tremily.us>
Sat, 12 May 2012 18:13:39 +0000 (14:13 -0400)
committerW. Trevor King <wking@tremily.us>
Sat, 12 May 2012 18:14:50 +0000 (14:14 -0400)
posts/X.509_certificates.mdwn

index f683df2974be7906ad29b00160e096e85ae89932..9ef76b2936d68858a50a69f1f8b9358e1b363892 100644 (file)
@@ -1,11 +1,11 @@
-If you're running your own server, your probably not shelling out $400
-to get an "official" Certificate Authority to sign your key.  Here's a
-quick not to myself about how to create and sign your own key.
-Depending on your application, you can use either the [[GnuTLS]] or
-[OpenSSL][] toolchain.
+If you're running your own server, you're probably not shelling out
+$400 to get an “official” Certificate Authority (CA) to sign your key.
+Here's a quick note to myself about how to create, sign, and install
+your own CA and key.  Depending on your application, you can use
+either the [[GnuTLS]] or [OpenSSL][] toolchain.
 
 GnuTLS
-------
+======
 
 Following the [GnuTLS manual][gnutls-manual], create a certificate
 authority with [certtool][], adjusting the `cn` as you see fit:
@@ -38,8 +38,14 @@ You can also print certificates with [certtool][].
 
     $ certtool --infile x509-server.pem --certificate-info
 
+You can add alternate hostnames using [subject alternative
+names][SAN].  Just add more `dns_name` entries to your template:
+
+    $ echo 'dns_name = other.gnutls.org' >> server.tmpl
+    $ certtool --generate-certificate …
+
 OpenSSL
--------
+=======
 
 Use [openssl][]'s [genpkey][] to generate an *unencrypted* key.
 
@@ -65,16 +71,151 @@ You should keep your certificate signing request around so you can
 re-sign your key later on (since your initial signature will
 eventually expire).
 
+You can add subject alternative names to the request using
+the `openssl.cnf` [config file][x509v3_config]:
+
+    $ cp /etc/ssl/openssl.cnf openssl.cnf
+    $ emacs openssl.cnf
+    $ cat openssl.cnf
+    …
+    [ req ]
+    …
+    req_extensions = v3_req
+    …
+    [ v3_req ]
+    …
+    subjectAltName = DNS:test.gnutls.org,DNS:other.gnutls.org
+    …
+    $ openssl req -new -config openssl.cnf -key key.pem -out req.pem
+
 You can also print certificates with [x509][].
 
     $ openssl x509 -in cert.pem -noout -text
 
+PEM
+===
+
+We've been throwing around a lot of files with a [.pem][] extension.
+These files contain [Base64][] encoded [DER][] certificates enclosed
+between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`.
+The `.crt` files requested by `update-ca-certificates` (discussed
+below) are generally binary DER files, but can also be base64 encoded.
+
+System wide certificates
+========================
+
+The situation is confusing because there is currently no standardized
+way to track trusted certificates.  Here are some things to keep in
+mind:
+
+ca-certificates
+---------------
+
+[[Gentoo]] uses [Debian][]'s [ca-certificates][] package to manage
+trusted CAs.  The certificates are stored under `/etc/ssl/certs` in
+three forms:
+
+1. As a `<filename>.pem` symlink to the external certificate (if it
+   was already base64 encoded) or an encoded version (if the external
+   certificate is binary).
+2. As a symlink to 1 named with the certificate's hashed subject name,
+   key identifier (if present), and serial number.
+3. As an entry in `ca-certificates.crt`, which is a concatenated list
+   of all the trusted certificates.
+
+You can update these system certificates using
+`update-ca-certificates`, from the the `ca-certificates` package:
+
+    # update-ca-certificates
+
+On Fedora-based systems, `update-ca-certificates` also [updates the
+system NSS storage][fedora] at `/etc/pki/nssdb` (more on NSS in a
+second).
+
+`update-ca-certificates` looks in a number of places to find trusted
+CAs.  To add a new CA, place the certificate in
+`/usr/local/share/ca-certificates/` as a single file ending in `.crt`
+and run `update-ca-certificates`.
+
+### GnuTLS
+
+In [[GnuTLS]], you set the list of trusted CAs using
+[gnutls_certificate_set_x509_trust_file][].  By convention this
+function is pointed to the `/etc/ssl/certs/ca-certificates.crt` file
+mentioned above.
+
+### OpenSSL
+
+OpenSSL loads trusted CAs with [SSL_CTX_load_verify_locations][],
+which loads certificates from a file (like
+`gnutls_certificate_set_x509_trust_file`) or from a directory (usually
+`/etc/ssl/certs/`).  For efficiency, many applications prefer the
+directory approach, as certificates can then be loaded on an as-needed
+basis using their hashed subject name, key identifier (if present),
+and serial number.  If you place a new CA this directoy, you'll want
+to run `c_rehash` to generate the hashed symlinks:
+
+    # c_rehash /etc/ssl/certs
+
+OpenSSL doesn't currently provide a man page for `c_rehash`, but
+there's one attached to [Debian bug 215618][215618].
+
+`update-ca-certificates` (mentioned above) uses `c_rehash` internally
+to generate hashed symlinks for OpenSSL.
+
+NSS
+---
+
+[NSS][] is the crypto library used by [Firefox][] and [Chromium][]
+that *doesn't* use the `/etc/ssl/certs` framework discussed above.  It
+[looks in a number of places][nss-places] depending on the package
+type, but the system-wide `sql:/etc/pki/nssdb`.  User applications
+will also look in `sql:~/.pki/nssdb`.  You manage the databases with
+[certutil][].  You can install `certutil` on Gentoo by emerging
+`dev-libs/nss` with the `utils` `USE` flag enabled.  Add your
+certificate with something like:
+
+    $ certutil -A -n jdoe -t "C,," -d "sql:${HOME}/.pki/nssdb" -i /etc/ssl/certs/cacert.org.pem
+
+This adds a certicate (`-A`) to the `sql:${HOME}/.pki/nssdb` database
+(`-d`).  The certificate is named `jdoe` (`-n`), and you can use this
+name to manage the certificate later (e.g. to delete it).  `-t "C,,"`
+sets SSL trust to `C`, but does not grant email or object signing
+trust.  `C` means you trust this certificate to issue SSL server
+certificates (but not client certificates, which would be `T`), and
+that you don't trust it for direct SSL authentication or email signing
+(which would be `u`).
+
+Unfortunately, many applications using NSS have a [compiled-in
+list][certdata.txt] of trusted CAs, so you don't have complete control
+from a sysadmin perspective unless you tweak that file at compile
+time.
+
+
 [gnutls-manual]: http://www.gnu.org/software/gnutls/manual/html_node/Invoking-gnutls_002dserv.html
 [certtool]: http://www.gnu.org/software/gnutls/manual/html_node/Invoking-certtool.html#Invoking-certtool
+[SAN]: http://tools.ietf.org/html/rfc4985
 [OpenSSL]: http://www.openssl.org/docs/apps/openssl.html
 [genpkey]: http://www.openssl.org/docs/apps/genpkey.html
 [req]: http://www.openssl.org/docs/apps/req.html
+[x509v3_config]: http://www.openssl.org/docs/apps/x509v3_config.html#Subject_Alternative_Name_
 [x509]: http://www.openssl.org/docs/apps/x509.html
+[Debian]: http://debian.org/
+[ca-certificates]: http://packages.debian.org/sid/ca-certificates
+[.pem]: http://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions
+[base64]: http://en.wikipedia.org/wiki/Base64
+[DER]: http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules
+[fedora]: https://fedorahosted.org/update-ca-certificates/browser/update-ca-certificates.8
+[gnutls_certificate_set_x509_trust_file]: www.gnu.org/software/gnutls/manual/gnutls.html#gnutls_certificate_set_x509_trust_file
+[SSL_CTX_load_verify_locations]: http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html
+[215618]: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=215618
+[NSS]: http://www.mozilla.org/projects/security/pki/nss/
+[Firefox]: https://bugs.gentoo.org/325723
+[Chromium]: http://code.google.com/p/chromium/wiki/LinuxCertManagement
+[nss-places]: https://wiki.mozilla.org/NSS_Shared_DB_And_LINUX
+[certutil]: http://www.mozilla.org/projects/security/pki/nss/tools/certutil.html
+[certdata.txt]: http://comments.gmane.org/gmane.comp.mozilla.crypto/16347
 
 [[!tag tags/linux]]
 [[!tag tags/tools]]
+[[!tag tags/web]]