vendredi 9 avril 2010

tutorial mutual authentication - trusted platform module (TPM) - apache2 - openssl

The administrator of an Apache2 Server can restrict the access to a part of his website to authenticated users. This article is dealing with mutual authentication (strong authentication) with X509 certificates, between an Apache2 server and a client. In addition, the client's certificate is protected in the trusted platform module (TPM) of his computer.
With this solution, only granted computers gain access to the site. Also, it becomes more complicated for a hacker to access to the private key of a compromised computer. Indeed, this key is difficult to copy or extract, as it is kept in hardware TPM.
French version available on http://infond.blogspot.com

introduction

Our network will be composed of a server and a client. The server will provide a web server and a certification authority.

The certification authority will only be used to sign the keys of client and server. Indeed, any client  that has a certificate signed by the authority will be allowed to connect to the web server. And, the server will be authenticated by the clients because of its certificate signed by the authority.

First, we will create a certificate for the server, and another for the client. Both of them will be certified by a third certificate that belongs to the authority.
Then, we will configure the Apache2 server to grant access only to clients certified by the authority.
Finally, we will test the access to the server with openSSL s_client command. We will see that Firefox can't use for now the TPM through trousers library.

prerequisites

The client, under Linux, has an activated and not initialized TPM. The libraries libengine-tpm-openssl and libtspi-dev have been installed (cf tutoriel infond [1]). The client and the server are configurated as described in labo of basics 1 tutorial - construcion of a VMWare laboratory [4].
Client's IP is 192.168.0.10
Server's IP is 192.168.0.2

construction of public key infrastructure

We will successively create:
- an authority certificate to sign the client certificate, and the server one,
- a server certificate, signed by the authority,
- a pair of client keys (the private key will be kept in the TPM), and a certification request for it,
- a client certificate signed by the authority (obtained from the certification request). The private part of this certificate will be kept in the TPM.

self-signed authority certificate generation

On the server, create an ssl directory
serveur~$ sudo mkdir /etc/apache2/ssl
serveur~$ cd /etc/apache2/ssl
create a self-signed certificate for the authority
serveur:/etc/apache2/ssl$ sudo openssl req -x509 -newkey rsa:1024 -out authority.crt -keyout authority.key

generation of the server certificate, signed by the authority

create the server certificate, signed with the authority certificate
serveur:/etc/apache2/ssl$ sudo openssl req -x509 -newkey rsa:1024 -in authority.crt -out server.crt -keyout server.key
serveur:/etc/apache2/ssl$ sudo chmod 440 *.key

generation of a  pair of keys and the certificate request for the client

Remember: we use a virtualized TPM [1].

start tpmd daemon. Start trousers. Then, initialize the TPM (do not chose -u unicode option to let the create_tpm_key command be reconized by the SRK.
client~$ sudo tpmd
client~$ sudo tcsd
client~$ tpm_takeownership -y
Enter SRK password: <- "ENTER"
Confirm password: <- "ENTER"
create client pair of RSA keys, using TPM
client~$ create_tpm_key -a client.key
make certificate request. We will send it later to the server for signing.
~$ sudo openssl req -keyform engine -engine tpm -key client.key -new -out client.csr
engine "tpm" set.
SRK authorization:
TPM Key Password:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Ile de France
Locality Name (eg, city) []:Paris
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Infond
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:client
Email Address []:client@infond.blogspot.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
We have juste created a certificate request, which private key is kept in the TPM.

signature of client certificate by server

Install an openSSH server on the server to allow a secure exchange of the certificate request. The openSSH server should be securely configured, but this is not the purpose of this article.
serveur~$ sudo apt-get install openssh-server
send the certificate request from client to server
client~$ scp client.csr utilisateur@192.168.0.2:~
Server signes client certificate request with authority certificate
serveur~$ sudo openssl x509 -req -in client.csr -CA /etc/apache2/ssl/authority.crt -CAkey /etc/apache2/ssl/authority.key -CAcreateserial -out client.crt
have a look to the resulting certificate
serveur~$ openssl x509 -in client.crt -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            e1:5e:ee:64:7b:d8:6b:67
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=FR, ST=Ile de France, L=Paris, O=Infond, CN=authority/emailAddress=authority@infond.blogspot.com
        Validity
            Not Before: Apr  8 12:01:14 2010 GMT
            Not After : May  8 12:01:14 2010 GMT
        Subject: C=FR, ST=Ile de France, L=Paris, O=Infond, CN=client/emailAddress=client@infond.blogspot.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:e5:85:29:a7:62:69:08:f3:af:35:4b:0e:47:0e:
                    0b:7f:08:77:71:fb:0b:02:01:e6:2b:aa:76:6d:da:
                    1d:41:d3:e0:66:cf:de:2d:1c:b4:ed:92:48:49:59:
                    b8:ef:e2:89:9a:ec:0a:89:2a:c2:c1:28:06:54:87:
                    00:17:0a:e2:d3:d0:82:f7:2a:b8:c9:91:74:e2:89:
                    ea:f6:2b:d9:f2:e6:bc:90:e1:d9:07:a3:26:18:14:
                    e9:eb:66:ab:69:a9:ca:30:32:b9:c3:2a:36:92:f2:
                    02:ce:52:c0:74:f7:e4:c2:71:36:a5:4e:b6:33:34:
                    b0:90:28:c9:bf:67:36:6c:f0:c0:9d:07:7a:f5:96:
                    64:3d:1b:86:12:79:a2:d0:2f:a7:52:a3:69:81:81:
                    3c:7e:d7:86:58:75:82:e4:bf:ab:6a:9f:cf:85:88:
                    30:f7:96:8a:32:9a:f1:28:c9:0e:02:52:a8:21:c8:
                    ec:4c:5e:d2:e8:30:78:f2:7b:ea:c5:da:b4:85:dd:
                    fd:73:8d:ed:cd:22:1e:48:f7:9a:56:2a:08:5e:49:
                    3a:16:51:57:cc:de:24:6a:16:ed:47:28:7d:83:11:
                    63:3a:92:af:8a:8a:e0:93:d8:61:48:b5:41:24:2f:
                    90:15:80:a4:c8:d7:cd:8d:d9:1e:62:4f:f0:be:dd:
                    00:ef
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
        57:f1:e5:24:9b:0d:e3:90:1c:52:6e:85:b5:a0:bd:07:1b:cb:
        f6:a4:34:e3:1a:87:e8:1e:16:6f:8c:b2:01:89:6b:90:bb:20:
        71:66:c8:88:fe:2c:16:b6:e2:cd:69:57:f9:f0:bc:19:c8:0f:
        03:99:48:97:50:03:9b:f8:a5:07:d8:02:41:fd:9b:81:e1:dd:
        5e:33:e8:82:16:9c:65:01:3b:81:84:f4:c3:19:79:1c:6e:50:
        c3:e3:c0:97:c3:d1:9e:15:d2:7e:50:39:61:f5:38:d6:61:39:
        c3:8d:4f:48:39:3e:55:cd:f1:73:59:7f:9a:1b:15:22:17:70:
        c9:f8
from client, download the new certificate
client~$ scp utilisateur@192.168.0.2:~/client.crt ~
Now, the client has a certificate signed by the authority, which private key is kept in TPM.

configuration of Apache2 server

install apache2 server
serveur~$ sudo apt-get install apache2
Install ssl module:
serveur~$ sudo a2enmod ssl
serveur~$ sudo /etc/init.d/apache2 restart
remark: Listen 443 has been automatically added during the ssl mod installation process:
serveur$ cat /etc/apache2/ports.conf

NameVirtualHost *:80
Listen 80


# SSL name based virtual hosts are not yet supported, therefore no
# NameVirtualHost statement here
Listen 443
activate SSL for the website. In this configuration file:
- any request on port 80 is redirected to port 443 (https),
- the main page will be /var/www/index.html,
- server will authenticate itself to client using its authority signed certificate,
- client will authenticate itself to server using its authority signed certificate.
serveur$ sudo cat /etc/apache2/sites-enabled/000-default
NameVirtualHost 192.168.0.2:443


redirect / https://192.168.0.2:443



DocumentRoot /var/www

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCACertificateFile /etc/apache2/ssl/authority.crt
SSLVerifyClient Require
restart server:
serveur$ sudo /etc/init.d/apache2 restart
verify the server is on. Of course, its certificate is self-signed. As a consequence, firefox warns us that connexion is not certified. From client:


Jetons un oeil au détail du certificat:


also, even if the client accepts server certificate, server denies him the access:



Pity! the pkcs #11 API is needed for the installation in Firefox of a client certificate which private key is in a TPM. But the pkcs #11 interface of trousers is not compatible with firefox. Let's see that later...

connexion to Apache2 with openSSL

On the client, openssl is already configured to interact with TPM. Let's connect it to the Apache2 server.

download the authority certificate of the authority
On server:
serveur~$ sudo cp /etc/apache2/ssl/authority.crt ~
On client
client~$ mkdir ~/CAvalides
client~$ scp utilisateur@192.168.0.2:~/authority.crt ~/CAvalides/
Then connect to server. It works!
client~$ openssl s_client -connect 192.168.0.2:443 -keyform engine -engine tpm -key client.key -cert client.crt -CAfile /home/utilisateur/CAvalides/authority.crt

engine "tpm" set.
SRK authorization:
TPM Key Password:
CONNECTED(00000004)
depth=0 /C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
verify return:1
---
Certificate chain
 0 s:/C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
   i:/C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDbzCCAtigAwIBAgIJANpuDO+rjUfaMA0GCSqGSIb3DQEBBQUAMIGCMQswCQYD
VQQGEwJGUjEWMBQGA1UECBMNSWxlIGRlIEZyYW5jZTEOMAwGA1UEBxMFUGFyaXMx
DzANBgNVBAoTBkluZm9uZDEPMA0GA1UEAxMGc2VydmVyMSkwJwYJKoZIhvcNAQkB
FhpzZXJ2ZXJAaW5mb25kLmJsb2dzcG90LmNvbTAeFw0xMDA0MDgxMTI5NTBaFw0x
MDA1MDgxMTI5NTBaMIGCMQswCQYDVQQGEwJGUjEWMBQGA1UECBMNSWxlIGRlIEZy
YW5jZTEOMAwGA1UEBxMFUGFyaXMxDzANBgNVBAoTBkluZm9uZDEPMA0GA1UEAxMG
c2VydmVyMSkwJwYJKoZIhvcNAQkBFhpzZXJ2ZXJAaW5mb25kLmJsb2dzcG90LmNv
bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAot1fyBinTZuuCwM1NkIZultU
XX5LIs3aslESgMwo9uZC/4u1bki4zcd671ozLp4LEcXsMNgxgH/YOfvMt8BmdEpe
3ds/mAsTkWC5cIXP68N1+jk+EaiUYJSRVyF7vuwuLkaBA6Sibct07W3YtKAIxbSv
v+WhRJkPr1UCvvoYv98CAwEAAaOB6jCB5zAdBgNVHQ4EFgQU1l9uOA7reg9eMi2M
3ztKcKjpamEwgbcGA1UdIwSBrzCBrIAU1l9uOA7reg9eMi2M3ztKcKjpamGhgYik
gYUwgYIxCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUgZGUgRnJhbmNlMQ4wDAYD
VQQHEwVQYXJpczEPMA0GA1UEChMGSW5mb25kMQ8wDQYDVQQDEwZzZXJ2ZXIxKTAn
BgkqhkiG9w0BCQEWGnNlcnZlckBpbmZvbmQuYmxvZ3Nwb3QuY29tggkA2m4M76uN
R9owDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAimT51u6DvrhaYvLOG
9NNLbbBDGCN/q5dqWPRqkGjfD1i4FU7v1ll8pY6eWl6gHRERJVDOaVsUy0Itnj11
do0MhPQ9DuUQeeHGMsiWkXvHF6rPdEaCZdWycg3Hw3q9gTjTEiRNl2aKfQR1Hl/h
LzvlBfkjDu+Rf8VEEwrnzneyQg==
-----END CERTIFICATE-----
subject=/C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
issuer=/C=FR/ST=Ile de France/L=Paris/O=Infond/CN=server/emailAddress=server@infond.blogspot.com
---
Acceptable client certificate CA names
/C=FR/ST=Ile de France/L=Paris/O=Infond/CN=authority/emailAddress=authority@infond.blogspot.com
---
SSL handshake has read 1600 bytes and written 2281 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: B51E5ADFCD1D299F05ADE97E2597F183D5792453A8053B148011D148DB4008DB
    Session-ID-ctx:
    Master-Key: 4D1ACC567E193FA5E4A82D8BA69EBF6743916B6729222A012617D9796FA72B2C8005AC63F0D5F81112BE78472BC0BFE6
    Key-Arg   : None
    Start Time: 1270734784
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
^C

until now, we were able to configurate an Apache2 server that accepts only clients which have a certificate signed by the authority and wich have a private key kept in a TPM.

and what about connect Firefox to Apache2 server?

Trousers does not work with Firefox.

Firefox needs a pkcs #11 module to communicate with the TPM. pkcs #11 is a norm that defines an API between the TPM driver and applications.  It is easy to connect Firefox to a pkcs11 module. But the module provided by trousers is not compatible with Firefox. This part of the article shows the procedure.

activate pkcs11 module of trousers

On the client, add utilisateur to pkcs11 group
client~$ sudo usermod -a -G pkcs11 utilisateur
client~$ sudo reboot
start tpmd daemon (if tpm is virualized). Start trousers. Then initialize the TPM. An empty SRK is needed to use Trousers pkcs11.
client~$ sudo tpmd
client~$ sudo tcsd
client~$ tpm_takeownership -y
Enter SRK password: <- "ENTER"
Confirm password: <- "ENTER"
initialize pkcs11 interface of the TPM
utilisateur@TPM:~$ tpmtoken_init
A new TPM security officer password is needed. The password must be between 6 and 127 characters in length.
Enter new password:
Confirm password:
A new TPM user password is needed. The password must be between 6 and 127 characters in length.
Enter new password:
Confirm password:
verify the token is well initialized:
utilisateur@TPM:~$ pkcsconf -t -c 0
Token #0 Info:
    Label: IBM PKCS#11 TPM Token         
    Manufacturer: IBM Corp.                     
    Model: TPM v1.1 Token
    Serial Number: 123           
    Flags: 0x44D (RNG|LOGIN_REQUIRED|USER_PIN_INITIALIZED|CLOCK_ON_TOKEN|TOKEN_INITIALIZED)
    Sessions: -1/-1
    R/W Sessions: -1/-1
    PIN Length: 6-127
    Public Memory: 0xFFFFFFFF/0xFFFFFFFF
    Private Memory: 0xFFFFFFFF/0xFFFFFFFF
    Hardware Version: 1.0
    Firmware Version: 1.0
    Time: 17:05:38
Remark: public and private keys generated during TPM's pkcs11 initialisation are saved on the disk. Private key is encrypted with TPM user password. Public key is encrypted with TPM security officer password.


delete securely both keys with Guttman method
client~$ sudo apt-get install wipe
client~$ sudo wipe -f /var/lib/opencyptoki/tpm/*.pem
Remark: if a token is already (not well) initialised, il could be necessary to delete the token database and follow again the procedure from the begining.
client~$ rm -rf /var/lib/opencryptoki/tpm
Now, pkcs #11 interface of Trousers is working correctly.

add a pkcs #11 module to Firefox


On client, it is easy to add a pkcs #11 module to Firefox. In Firefox go to Tools -> Options -> Advanced -> security peripherics -> load
The module is one of the .so files in  /usr/lib/opencryptoki/ or /usr/lib/pkcs11.



conclusion


In this article, we configured an Apache2 server which uses mutual authentication based on the TPM of its clients. Nevertheless, for the moment, Firefox is not able to use TPM for its certificates.

references

1) infond - tutoriel TPM - http://infond.blogspot.com/2010/03/trusted-platforms-module-tpm-openssl.html
2) ubuntu - tutoriel sécuriser Apache2 - http://doc.ubuntu-fr.org/tutoriel/securiser_apache2_avec_ssl
3) sécuriser par mot de passe les accès à un serveur Apache2 - http://www.linux-france.org/prj/edu/archinet/systeme/ch16s02.html
4) infond - tutoriel mise en place du laboratoire VMWare - http://infond.blogspot.com/2010/03/basics-1-mise-en-place-du-labo.html
5) tutoriel openssl - http://www.herongyang.com/crypto/openssl_verify.html
6) pkcs11 - ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11v2.doc
7) tuto pkcs11 (polonais) - http://blog.4zal.net/2009/06/12/kryptografia-trusted-platform-module-i-ubuntu/
8) doc trousers pkcs11 - http://trousers.sourceforge.net/pkcs11.html
9) authentification mutuelle forte dans apache2 - https://www.ateliers.modernisation.gouv.fr/ministeres/ae/interops/public/documents-annexes/interops-a1/downloadFile/file/Standard%20Interops1.0_GuideMiseEnOeuvre_v1.0.pdf?nocache=1223646135.91

1 commentaire:

  1. Hi mate,
    Thanks for sharing the good informative sites references and nice articles.
    Datastage

    RépondreSupprimer