ServiceEncryptionWithSSL

From HerzbubeWiki

Jump to: navigation, search

Contents

References

Provides a good overview over SSL/TLS, and also gives some details how to create your own SSL certificates:

http://httpd.apache.org/docs-2.0/ssl/ssl_faq.html

Another interesting article/FAQ that is OpenLDAP-centric:

http://www.openldap.org/faq/data/cache/185.html

And, of course, the helpful Wikipedia article:

http://en.wikipedia.org/wiki/Transport_Layer_Security

A Debian article that describes how to become your own root CA and sign your own certificates:

http://www.debian-administration.org/articles/284


Basics on SSL/TLS

Q: What is SSL/TLS?

A: A protocol to encrypt communication over a computer network. The protocol runs on top of the TCP and UDP protocols, but below any application protocols such as HTTP or FTP. In other words, it runs between the transport and the application network layers.


Q: What is the difference between SSL and TLS?

A: TLS is the successor to SSL. The SSL 3.0 specification was the last version of SSL to be published in 1996 by Netscape. The first version of TLS was TLS 1.0, it was published in 1999 in RFC 2246. The latest version of TLS as of writing this document is TLS 1.1, published in 2006 in RFC4346.


Q: Implementations?

A: Probably most popular is the OpenSSL library, which is basically free but has a license that is not compatible with the GPL. An alternative was therefore created by the GNU project in the form of the GnuTLS, which uses the LGPL.


Basics on certificates

Network communication occurs between 2 hosts. Throughout this document one of these hosts will always be called "the client", the other host will be called "the server".

SSL/TLS relies on the concept of public key cryptography. The server has the public/private key pair. Communication between server and client is encrypted using the server's public key. The server hands out its public key in the form of a certificate, which may contain additional information that the client uses to make sure that the server really is whom it claims to be.

Overview of certificates involved in client/server communication:

  • client side
    • a public server certificate that the client uses to encrypt messages it sends to the server
    • the client gets this public certificate from the server
    • the public certificate provided by the server is, in itself, not trustworthy; to make it trustworthy for the client, the public certificate must be signed by a third party, a so-called Certificate Authority (CA) that the client knows and trusts
      • an example for a commercial CA is VeriSign
      • an example for a community CA is cacert.org
    • the client needs the public certificate of the CA in order to be able to check the public server certificate's signature and therefore its authenticity
  • server side
    • a private RSA key that the server uses to decrypt messages from the client
    • a public certificate that the server hands out to the client so that the client can encrypt its messages
    • if the public certificate is signed by a CA, that CA's public certificate is also required


Generic procedure for signing a certificate

  • the private RSA key is generated by the operator of the server
  • the public unsigned certificate is generated by the operator of the server
  • to let the CA sign the certificate, the server operator must contact the CA
    • first the operator creates a Certificate Signing Request (CSR)
      • the CSR contains various information about the person or organisation
      • if the signed certificate should be used by a server process (e.g. HTTP server, LDAP server), it is vital that the attribute "common name" is set to the FQDN under which the server is going to operate
    • the operator sends his or her CSR to the CA
  • the CA signs the CSR with its private key; the result is the public signed certificate which the CA sends back to the server operator for usage


System installation

The following Debian packages need to be installed:

openssl


The Certificate Authority (CA)

CAcert.org

Get root certificates

The public root certificates of CAcert.org can be obtained from this page (use the PEM variants):

https://www.cacert.org/index.php?id=3

At the time of writing there are 2 root certificates available:

  • a class 1 root certificate
  • a class 3 root certificate; this one is signed by the class 1 root certificate

At the time of writing, the Debian package ca-certificates provides those two certificates in /etc/ssl/certs so it should not be necessary to manually store them there. These are the package-provided files:

lrwxrwxrwx 1 root root     48 Sep 25 19:32 class3.pem -> /usr/share/ca-certificates/cacert.org/class3.crt
lrwxrwxrwx 1 root root     46 Sep 25 19:32 root.pem -> /usr/share/ca-certificates/cacert.org/root.crt


Certificate chain file

Create a so-called certificate chain file in the following way:

cd /etc/ssl/certs
rm cacert.org.certchain
cat class3.crt >>cacert.org.certchain
cat root.crt >>cacert.org.certchain

The Apache web server is one of the applications that requires this chain file (it is specified by the directive SSLCertificateChainFile): When a client requests a server certificate such as for www.herzbube.ch (which is signed by the class 3 CAcert.org root certificate), the server not only hands out the server certificate, but also provides the root certificates in the chain file. If the client trusts one of the CAcert.org root certificates, it will thereby automatically trust the server certificate, too.

Note: The certificates in the chain file should appear in the order of the certificate chain order, i.e. the root certificate that was used to sign the server certificate should appear first. I have not tested what happens if this is not the case, but it may affect browsers on the client side.


Manually add root certificates to browser

As per Wikipedia:

  • class 1 root certificate is for email
  • class 3 root certificate is for server certificates and software signing

If the browser supports it (e.g. Firefox does), also add the CRLs (certificate revocation list) for both root certificates.


Manually add root certificates to system (Mac OS X)

The following procedure works for me on Mac OS X 10.5.4:

  • Download the class 1 and class 3 certificates to the desktop (use the files in the DER format)
  • Import the class 1 certificate into the system keychain
    • Double-click on root.crt; this will open "Keychain Access.app" ("Schlüsselbundverwaltung" in German)
    • Select the keychain "System" (refers to /Library/Keychains/System.keychain)
    • Authenticate by specifying your administrator user's name and password
    • Confirm that you want to trust the certificate
  • Repeat the procedure by double-clicking on class3.crt (the class 3 certificate)
    • The certificate is automatically trusted because the root cert was already imported


Creating your own Certificate Authority (CA)

In order to act as your own CA, two things are needed

  • a private key
  • a certificate

In theory, the certificate can be obtained in 2 ways:

  • either create a self-signed public certificate
  • or create a CSR and convince a third party to issue the certificate for you

In practice, you will only use a self-signed certificate, because no other CA will issue a certificate to you that is capable of doing CA things. The reason is obvious: The other CA would lose control over the certificate issuing process, which is exactly what must never happen to a CA.


Private key

The following command creates a new private key with the following attributes:

  • the key is an RSA key
  • the key is protected by a passphrase that you must specify; the encryption algorithm/cipher used is Triple-DES
  • the key is formatted for PEM
openssl genrsa -des3 -out ca.herzbube.ch.key 1024

Example key file content:

osgiliath:~/ssltest# cat ca.herzbube.ch.key 
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,D238054F2ED5C62B

hRy60/LS02UiWCtxJ5exSCX4nc1/bjSTfkR02PQhyrieAZjWK05YC5cYl17nobho
2evuG8QXCfEn4u6F/ckG9KcVD4LSpEPNOFijd/7lZjE7g07aP7Z11Bhqed03Orzh
UTUwCPUXm9lxE+zypUmfY4F5r0MVSS3v5ULA4ckZMfkuCX4Ed0WNZjmqfyjLbwOr
FA8TMDj7pb/HLiUt74TQyw58nENdNRG2NP/IAapMZvrj0+izxPD9LSmdFAAexAbY
IcACNR4Ou5FypJE5d05PUVAPtBKYJQWdWW3lbOGovpQOdgLW7M13q/7doHYS0IHl
sETcibGidhA6Nt4BI3XQ/LJgGV8v7ravmi7wj7ZvQ0l8INR5208E8rBQ6+QtoBsf
A2nzZrd3L9k3GE05Tll8xp+vjkTkr38Kn31AGDz/W47bQfErYlbUutq4TvGIyFHl
o6+MwqnsLHw88u9CneGprd6UNo49dLbcOrEX7CCnWSfRJR6oTb17yBbtCi2+yfBi
1Q+an7t3jTwDews3OAraSqCt/W5I8IHT4VLsDd+4T7TDXMWXYkqGv8rs+HlsMvGV
YjOpwhFMk0ITJy8CkqP72TrsqRDBlhI7Rif2nT3kPOfJKwK6uc6F0S/Y0EuamhQu
BqzPym4Nn35NmnWp7kI0C8ro9eu2i3shDUyW1GJdNvbzgiO3NVkvwq55LZA7YRQT
tD0UIlEYmG8rD6BpQX3rwmU7utaE3jMuuW/G8BLHsRwo4F1IhbFQ0rmfXNKGBy+l
NNx2zhpA44Hh+KR5RYcyl13nKsgmkevdt365XvGeQNrvrS8xHlGzLA==
-----END RSA PRIVATE KEY-----


Self-signed certificate

The following command creates a new self-signed certificate with the following attributes:

  • the certificate has the X.509 structure
  • the certificate is signed with the CA's private RSA key
  • the certificate is formatted for PEM
  • the certificate is valid 30 years (= 10'950 days)
  • the certificate is capable of issuing other certificates (i.e. it is a CA certificate)
openssl req -new -x509 -days 10950 -key ca.herzbube.ch.key -out ca.herzbube.ch.crt

Note: You must specify the passphrase in order to access the private RSA key.

OpenSSL will also ask for some information that will be incorporated into the certificate. The information is also called a "distinguished name" (DN) and consists of multiple fields or attributes. Attributes that you want to leave blank must be entered with a value "." It is advisable to enter at least the "common name" attribute:

Example DN:

  • Country Name (2 letter code) = CH
  • State or Province Name (full name) = .
  • Locality Name (eg, city) = .
  • Organization Name (eg, company) = herzbube.ch Certificate Authority
  • Organizational Unit Name (eg, section) = .
  • Common Name (eg, YOUR name) = ca.herzbube.ch
  • Email Address = ca@herzbube.ch

Example certificate file content:

osgiliath:~/ssltest# cat ca.herzbube.ch.crt 
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJAJS709dIawALMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMDcwMzI3MTkzMzIxWhcNMzcwMzE5MTkzMzIxWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC8TmwotmWgM4mXoBqUOD/BYgwfPQ3Z31uMZnpAE1mvmYuE//pzy2dzTX4Y8wFH
2j6VzNFnqXy0Y5dULLc5kURswCIUSiMVUYWqSc5b+ybv1d0P5CSrypgk4tC0uYAz
L43RAaAp+CJsBjKkesIKzQKfNODD5DoFf2z6SS6pwe52EwIDAQABo4GnMIGkMB0G
A1UdDgQWBBSpWd567nU+3gOlS6b9wquTl3hBljB1BgNVHSMEbjBsgBSpWd567nU+
3gOlS6b9wquTl3hBlqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJS709dI
awALMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAWy/SVVDw1YvorgU3
6yRtqjXBxSDEqTZRfGfGOxGiYhhJ6QyMHjy4b+MHoJRBYKaaq/ZmJbvob4bYskat
X7vqrXO9/71JXSU10ZRRr7kczXNz0bZqeMtvtKi8ook0bdN/JwELp4pKHqWbI5od
7FuhwUSF17elipH/RuLLpalLfhk=
-----END CERTIFICATE-----


Storage

The private key and the certificate (either self-signed or signed by a third party) should be stored in a permanent location. For instance:

Store the private key in:

/etc/ssl/private

Store the certificate in

/etc/ssl/certs

To follow the guidelines of the ca-certificates package (see section below), we also need to create a hash symlink:

cd /etc/ssl/certs
ln -s ca.herzbube.ch.crt "$(openssl x509 -subject_hash -in ca.herzbube.ch.crt | head -1).0"

Last but not least, for those applications that are not able to follow a certificate chain (e.g. Apache, OpenLDAP), a single file with such a chain should be created:

cd /etc/ssl/certs
rm ca.herzbube.ch.certchain
cat ca.herzbube.ch.crt >>ca.herzbube.ch.certchain
cat class3.crt >>ca.herzbube.ch.certchain
cat root.crt >>ca.herzbube.ch.certchain


The server

Create a server key

The following command creates a new private key. It has the same attributes as the key that was created for the CA (see further up).

openssl genrsa -des3 -out foobar.herzbube.ch.key 1024


Create a Certificate Signing Request (CSR)

The following command creates a CSR with the following attributes:

  • the CSR is formatted for PEM
openssl req -new -key foobar.herzbube.ch.key -out foobar.herzbube.ch.csr

Example DN:

  • Country Name (2 letter code) = CH
  • State or Province Name (full name) = .
  • Locality Name (eg, city) = .
  • Organization Name (eg, company) = .
  • Organizational Unit Name (eg, section) = .
  • Common Name (eg, YOUR name) = foobar.herzbube.ch
  • Email Address = herzbube@herzbube.ch
  • Challenge password: .
  • Optional company name: .

Note 1: It is important to set the "common name" attribute = the FQDN (fully qualified domain name) under which the server will operate, otherwise the information in the certificate will not match the information that the server announces to its clients. If a client is picky about this, the client may even refuse to cooperate with the server!!!

Note 2: Specifying the common name *.herzbube.ch will create a wildcard certificate that is valid for all sub-domains of herzbube.ch.


Storage

Store the private key in:

/etc/ssl/private

Store the CSR in:

/etc/ssl/csr


Note: You may wish to store an un-encrypted version of the private key in /etc/ssl/private so that a server process can read the key without user interaction (i.e. the user entering the passphrase) during a system reboot. See the "Useful commands" chapter for an example of how to do this.


The certificate

Sign the CSR through CAcert.org

The form to sign CSRs can be found here

https://www.cacert.org/account.php?id=10

Paste the CSR into the form, then sign it (by the class 3 root certificate, which is selected by default in the Web form) and thereby generate the certificate. The certificate can be copied and pasted into a certificate file. That file should be stored in

/etc/ssl/certs


Sign the CSR through your own CA

Note: I recently discovered /usr/lib/ssl/misc/CA.sh which is provided by the openssl Debian package. Maybe it would be worth to have a look at that.


The first CSR

If this is the first CSR to be signed, I recommend creating a working directory that can be used to sign other CSRs in the future:

mkdir /usr/local/ssl
cd /usr/local/ssl
cp /usr/share/doc/libapache-mod-ssl/examples/sign.sh .
ln -s /etc/ssl/certs/ca.herzbube.ch.crt
ln -s /etc/ssl/private/ca.herzbube.ch.key

Make the following modifications to the script sign.sh:

  • set CA_PREFIX to use ca.herzbube.ch
  • set default_days to a value that you find suitable; the attribute determines how long the signed certificate remains valid


Sign the CSR

The following command uses the script sign.sh discussed in the above chapter to sign the CSR:

cd /usr/local/ssl
./sign.sh foobar.herzbube.ch.csr

Store the file that contains the signed certificate in

/etc/ssl/certs


Other useful commands

Generate an un-encrypted, PEM formatted version of a private RSA key. This is useful if a server process needs to read the key without user interaction (i.e. the user entering the passphrase) during a system reboot. Note: The passphrase is removed because there is no cipher option such as -des3 after the rsa command.

openssl rsa -in foobar.key -out foobar.key.unsecure

Display details about an RSA key:

openssl rsa -noout -text -in foobar.key

Display details about a CSR:

openssl req -noout -text -in foobar.csr

Display details about a certificate:

openssl x509 -noout -text -in foobar.crt

Change the passphrase (requires that you enter the old and the new passphrase). This can also be used to encrypt an unprotected, unencrypted key.

openssl rsa -des3 -in foobar.key -out foobar.key.new

Certificate verification:

openssl verify -CAfile ca.herzbube.ch.crt foobar.crt


Managing certificates with Debian

The package ca-certificates

Overview

From the blurb of the package ca-certificates:

This package includes PEM files of CA certificates to allow SSL-based applications to check for the authenticity of SSL connections. It includes, among others, certificate authorities used by the Debian infrastructure and those shipped with Mozilla's browsers. Please note that certificate authorities whose certificates are included in this package are not in any way audited for trustworthiness and RFC 3647 compliance, and that full responsibility to assess them belongs to the local system administrator.


How certificates are installed

The CA certificates provided by the package are located in

/usr/share/ca-certificates

The following configuration file defines whether a CA certificate in the above directory should be used, or not (in this case the certificate must be listed with a prefix "!"):

/etc/ca-certificates.conf

The configuratin file is read and evaluated by the update program

update-ca-certificates

The update program is invoked when a new version of the package is installed on the system. It installs the certificate files in

/etc/ssl/certs

The update program also generates a single file (bundle) that contains all the certificates

/etc/ssl/certs/ca-certificates.crt


Content of /etc/ssl/certs

When update-ca-certificates is executed, it organizes the content of the directory /etc/ssl/certs in the following way:

  • Creates a symlink for each active certificate that points to the certificate file in /usr/share/ca-certificates
  • Creates another symlink for each active certificate whose name is based on the certificates "subject hash"; see "man c_rehash"; an individual hash can be generated with the command openssl x509 -subject_hash -in foo.pem (see "man x509")
  • Updates the bundle file ca-certificates.crt
  • Symlinks for certificates that have vanished from the Debian package are left and dangling and should be cleaned out periodically

An example:

lrwxrwxrwx 1 root root     48 Sep 25 19:12 class3.pem -> /usr/share/ca-certificates/cacert.org/class3.crt
lrwxrwxrwx 1 root root     10 Sep 25 19:07 e5662767.0 -> class3.pem

Presumably the whole scheme is required so that applications can be provided with a single directory that contains all of the system's trusted certificates. The hash symlinks exist because they make lookup for a specific certificate fast and easy (e.g. for an application that wants to follow a certificate chain). One example that I have found that requires this setup is courier-imap-ssl.


Non-CA certificates

Naturally I have various certificates in /etc/ssl/certs that are not CA certificates (e.g. the one for imap.herzbube.ch). Presumably, these certificates do not require a hash symlink because they are specified with their real names in whatever configuration file requires them, and they never need to be looked up in order to follow a certificate chain.

When the ca-certificates package is upgraded and the upgrade contains new certificates, or some certificates have been deactivated, then update-ca-certificates will cause c_rehash to be run over the /etc/ssl/certs directory, which will lead to hash symlinks being generated even for my non-CA certificates. These symlinks can be removed if detected, but otherwise they do no harm.


Local CA certificates

A CA certificate that is locally installed (i.e. is not part of the ca-certificates package) and that is used in a certificate chain should be symlinked. The following command should (hopefully) work:

ln -s ca.herzbube.ch.crt "$(openssl x509 -subject_hash -in ca.herzbube.ch.crt | head -1).0"


The package ssl-cert

Overview

From the blurb of the package ssl-cert:

This package enables unattended installs of packages that need to create SSL certificates. It is a simple wrapper for OpenSSL's certificate request utility that feeds it with the correct user variables.

Besides this, I have found ssl-cert to be useful because it demonstrates how the different parts of the certificate management process can be protected on the file system level with a sensible user rights concept.


User rights concept

The user rights concept is this:

  • There is a system group ssl-cert
  • This group has some limited rights to the directory /etc/ssl/private
osgiliath:~# ls -ld /etc/ssl/private
drwx--x---   2 root ssl-cert 4096 Nov 29 03:16 /etc/ssl/private
  • This allows users that belong to the group to read files inside the directory
  • Daemons that do not start and/or run as root should have the ssl-cert group assigned as a secondary group
  • Key files within /etc/ssl/private can be "given" to ssl-cert; the read permission needs to be changed accordingly:
osgiliath:~# ls -ld /etc/ssl/private/ldap.herzbube.ch.key.unsecure
-r--r----- 1 root ssl-cert  887 Jan 10  2004 /etc/ssl/private/ldap.herzbube.ch.key.unsecure
  • Unfortunately all daemons that belong to ssl-cert can now read the key file; it is therefore sensible to further restrict the key file's group:
osgiliath:~# ls -ld /etc/ssl/private/ldap.herzbube.ch.key.unsecure
-r--r----- 1 root openldap  887 Jan 10  2004 ldap.herzbube.ch.key.unsecure


OpenSSL vulnerability in Debian

A brief check using the SSL certificate checker on the Heise web site

http://www.heise.de/netze/tools/chksslkey

reveals that all the certificates I created on my system are vulnerable to the infamous weakness in the Debian OpenSSL package. This is bad news, but since I cannot ignore the problem I will try to make the best of it and improve my security infrastructure in the following way:

  • Revoke all certificates signed so far by CAcert
  • Issue a new certificate for ca.herzbube.ch through CAcert, just in case I want to do my own certification business
  • Re-issue all the other server certificates through CAcert
  • Using CAcert to issue certificates has the benefit that certificates are not valid such a long time (i.e. 30 years) and can be managed through a CRL
  • Check out how to manage my own CRL
Personal tools
francesca