-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:
$ 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.
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]]