- Elliptic Curve Cryptography
|
Using Elliptic Curve Cryptography with Apache
This document describes how to build an Apache 2.2.11 web server
with support for
Elliptic Curve Cryptography (ECC) cipher suites (RFC 4492)
using OpenSSL 1.0.0-beta2.
These instructions were tested on a MacBook Pro
(Intel processor) running Mac OS X 10.5.6 but should apply to
other flavors of UNIX with little or no modification.
You should also be able to use a subsequent release of
OpenSSL available from the daily
snapshot repository.
Step 1: Initial Setup
Create an installation directory and set an environment variable
$MY_INSTALL_ROOT to point to it. The syntax of the declaration is
shell specific and following example works for bash:
% mkdir absolute_path_to_installation_directory
% export MY_INSTALL_ROOT=absolute_path_to_installation_directory
Step 2: Building OpenSSL
-
Download openssl-1.0.0-beta2 (or similar) from
the OpenSSL
Tarballs page. Unpack it inside $MY_INSTALL_ROOT and set
an environment variable to point to the OpenSSL directory.
% cd $MY_INSTALL_ROOT
% gunzip openssl-1.0.0-beta2.tar.gz
% tar xvf openssl-1.0.0-beta2.tar
% export MY_OPENSSL=$MY_INSTALL_ROOT/openssl-1.0.0-beta2
-
Build and test OpenSSL
% cd $MY_OPENSSL
% ./config
% make
% make test
OpenSSL versions 0.9.8 and later include ECC code
contributed by
Sun Labs. This functionality is enabled by default which
is why we didn't need to do anything special.
Step 3: Building Apache 2.2.11 with OpenSSL
-
Download Apache httpd-2.2.11.tar.gz from the
Apache
Software Foundation, save it to $MY_INSTALL_ROOT
and create an installation directory for Apache.
% cd $MY_INSTALL_ROOT
% gunzip httpd-2.2.11.tar.gz
% tar xvf httpd-2.2.11.tar
% mkdir $MY_INSTALL_ROOT/Apache-Install
-
[NOTE: This step may not be necessary if you are using a
version of Apache released after Mar 2, 2009. Apache 2.2.11 was
released in Dec 2008 before this patch had been checked in.]
Download and apply the
patch
posted for Apache Issue#
45521.
Without this patch, attempts to build Apache with OpenSSL 0.9.9
or later result in compile time errors (error: 'STACK'
undeclared). Here we assume the patch was saved in
$MY_INSTALL_ROOT/modssl_openssl_099.diff.txt. It can be
applied using the
GNU
patch tool:
% cd $MY_INSTALL_ROOT/httpd-2.2.11
% patch -p 0 -i $MY_INSTALL_ROOT/modssl_openssl_099.diff.txt
-
Apache is linked to OpenSSL through the mod_ssl module. This
module is included in httpd-2.2.11 but needs to be patched to
expose the elliptic curve cryptography capabilities in OpenSSL.
Download and apply the
patch
posted for Apache Issue#
40132.
Here, we assume the patch was saved in
$MY_INSTALL_ROOT/enable-ecc-apache2.2.11-with-openssl-1.0.0-beta2-20090505121706.txt
% cd $MY_INSTALL_ROOT/httpd-2.2.11
% patch -p 1 -i $MY_INSTALL_ROOT/enable-ecc-apache2.2.11-with-openssl-1.0.0-beta2-20090505121706.txt
-
Configure, compile and install Apache.
% ./configure --prefix=$MY_INSTALL_ROOT/Apache-Install/ --enable-ssl --enable-so --with-ssl=$MY_OPENSSL
% make
% make install
NOTE: I encountered 'undefined symbol' errors during the
'make' step on my MacBook Pro because the
linker was unable to find ECC-enabled versions of libcrypto.a
and libssl.a. I got around the problem by adding the full path
corresponding to $MY_INSTALL_ROOT/openssl-1.0.0-beta2 to the
definition of my LD_LIBRARY_PATH environment variable, copying
libcrypto.a and libssl.a from openssl-1.0.0-beta2 to a new
subfolder under it called lib and making sure that there were
no other versions of libcrypto and libssl in other paths
passed to the linker via the -L option.
Step 4: Generating Certificates
We need appropriate digital certificates to test the Apache web server
with ECC and RSA cipher suites,
-
These can be generated using scripts in the demos/ssltest-ecc
subdirectory of an OpenSSL distribution. We recommend modifying
those scripts as follows before use:
-
In RSAcertgen.sh, ECC-RSAcertgen.sh and ECCcertgen.sh, edit
the "distinguished name" (DN) field to insert the server's
hostname in the CN component. Otherwise, the browser will
complain of a certificate name mismatch error during the
SSL handshake.
-
Replace occurrences of 'sect163r1', 'secp160r1' and
'secp160r2' in ECC-RSAcertgen.sh and ECCcertgen.sh
with 'secp256r1' because both Firefox (version 2.0 or
later) and Internet Explorer (version 7.0 or later)
support this elliptic curve.
-
An RSA certificate can be generated with OpenSSL and installed
as follows:
% cd $MY_OPENSSL/demos/ssltest-ecc
% ./RSAcertgen.sh
% cp Certs/rsa1024TestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server.crt
% cp Certs/rsa1024TestServer.key.pem $MY_INSTALL_ROOT/Apache-Install/conf/server.key
-
Likewise, ECC certificates can be generated and installed.
% ./ECCcertgen.sh
% cp Certs/secp256r1TestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
% cp Certs/secp256r1TestServer.key.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.key
This creates an ECDSA-signed ECC certificate which can be used
for ECDH-ECDSA ciphers (see RFC 4492).
Alternatively, you can create an RSA-signed ECC certificate for use
with ECDH-RSA ciphers:
% ./ECC-RSAcertgen.sh
% cp Certs/secp256r1-rsaTestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
% cp Certs/secp256r1-rsaTestServer.key.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.key
NOTE: OpenSSL does not currently allow a server to be
configured with multiple ECC certificates simultaneously.
Step 5: Configuring Apache
-
Running Apache on the default HTTP port (80) requires superuser
privileges so you may wish to run it on an unprivileged port
like 8080. The following lines in
$MY_INSTALL_ROOT/Apache-Install/conf/httpd.conf may
have to be modified (replace 80 with 8080 and www.example.com
with the server's name):
Listen 80
ServerName www.example.com:80
Uncomment the following line in httpd.conf
#Include conf/extra/httpd-ssl.conf
-
The default HTTPS port (443) also requires special
privileges so you may wish to run it on an unprivileged port
8443 (say). The following lines in
$MY_INSTALL_ROOT/Apache-Install/conf/extra/httpd-ssl.conf
may have to be modified (replace 443 with 8443,
_default_ and www.example.com with the server's name):
Listen 443
<VirtualHost _default_:443>
ServerName www.example.com:443
Edit the line beginning with SSLCipherSuite if you wish to
disable any ECC ciphers. Here, we leave it unchanged.
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
NOTE: ECC cipher suites are now part of ALL and
ECCdraft is no longer a valid cipher suite descriptor.
-
Uncomment the following lines in
$MY_INSTALL_ROOT/Apache-Install/conf/extra/httpd-ssl.conf
to enable the newly generated ECC certificate (these lines
should have been added by the ECC patch)
#SSLCertificateFile $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
#SSLCertificateKeyFile $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.key
Step 6: Testing Apache
-
Start up the Apache web server:
% $MY_INSTALL_ROOT/Apache-Install/bin/apachectl start
-
Connect to it via the OpenSSL s_client application:
% $MY_OPENSSL/apps/openssl s_client -connect <server's name>:8443 -cipher
ECDH-ECDSA-AES128-SHA
-
Upon successful installation, this command should show an
output similar to the following:
% openssl s_client -connect localhost:8443 -cipher ECDH-ECDSA-AES128-SHA
CONNECTED(00000003)
depth=0 /C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=localhost
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=localhost
verify error:num=27:certificate not trusted
verify return:1
depth=0 /C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=localhost
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=localhost
i:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=Test
CA (Elliptic curve secp256r1)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIB/DCCAaMCCQD2f6mKkn+reTAJBgcqhkjOPQQBMIGTMQswCQYDVQQGEwJVUzEL
MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoMFlN1
biBNaWNyb3N5c3RlbXMsIEluYy4xETAPBgNVBAsMCFN1biBMYWJzMSswKQYDVQQD
DCJUZXN0IENBIChFbGxpcHRpYyBjdXJ2ZSBzZWNwMjU2cjEpMB4XDTA5MDUwNjA0
MTQ1OFoXDTEzMDYxNDA0MTQ1OFowejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB
MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQKDBZTdW4gTWljcm9zeXN0
ZW1zLCBJbmMuMREwDwYDVQQLDAhTdW4gTGFiczESMBAGA1UEAwwJbG9jYWxob3N0
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER22G9my4gSiUDOtzPRLS2NupE+bL
ixozwjYblT3eHQpyoKOcAVOuBwdJGYGQ6SoYXJLraPelt+hm3KZOzlcCbTAJBgcq
hkjOPQQBA0gAMEUCIHn7pSs203XFEdUxl3yCvXAVKYeFyqpoaDSgFOXtJbcaAiEA
xbxlnIbxJD1CPWUK+DIqhoiJQrsot2N/dXoUkfpD4qg=
-----END CERTIFICATE-----
subject=/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=localhost
issuer=/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Labs/CN=Test
CA (Elliptic curve secp256r1)
---
No client certificate CA names sent
---
SSL handshake has read 863 bytes and written 254 bytes
---
New, TLSv1/SSLv3, Cipher is ECDH-ECDSA-AES128-SHA
Server public key is 256 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : ECDH-ECDSA-AES128-SHA
Session-ID:
Session-ID-ctx:
Master-Key: AAEFD525FBE4186520FDC783F175F928C66FF045B843A35FB29DD06F48F45D54
7BD0D7C1904BFFAFAE91537D0DA77718
Key-Arg : None
PSK identity: None
PSK identity hint: None
TLS session ticket:
0000 - cf f6 a4 73 e9 f2 4a 1f-fb 12 b0 45 80 e6 ea 11 ...s..J....E....
0010 - 3d bd b4 f4 d0 7e 47 bf-e3 a8 a4 20 f6 00 8b d6 =....~G.... ....
0020 - 33 73 65 1f 36 a9 d9 cf-41 40 e6 d5 95 65 9c 76 3se.6...A@...e.v
0030 - 10 9c 50 09 11 a1 fd a6-81 74 4a 70 e5 15 2b bb ..P......tJp..+.
0040 - e3 4e 5c 7e 18 dc 5b ba-6a 91 d6 43 8c be 91 91 .N\~..[.j..C....
0050 - fb 65 06 1d f8 e0 bc b6-c1 55 b5 1c a3 61 4f cc .e.......U...aO.
0060 - 5a 08 ea 43 de 94 ec 9e-a3 c5 2e 6e 9d f6 9d 9a Z..C.......n....
0070 - a6 f7 4f b7 fd 9a 88 4e-f4 5f ef 5c 3a 41 04 e6 ..O....N._.\:A..
0080 - d7 52 51 fa f1 1a c3 e1-62 27 9f 37 f3 11 2c d4 .RQ.....b'.7..,.
0090 - 83 f8 a5 a8 2a 24 db b7-73 6d 3f c0 ff aa 95 8b ....*$..sm?.....
00a0 - 7a 59 e6 45 75 e9 2c 8f-74 0e b3 4a 2a 72 0f 9f zY.Eu.,.t..J*r..
00b0 - 6a 14 b0 52 a0 e9 5b c4-7b 02 16 05 5b f8 94 ca j..R..[.{...[...
Start Time: 1241583503
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
In addition, a test page can be retrieved by typing
GET / HTTP/1.0
and hitting the Enter key twice
-
You can also connect to the Apache server from Firefox by
pointing it to https://<server's name>:8443/.
Our Apache server is configured with a certificate from a
made-up certificate authority. Firefox will recognize this
fact and complain (Error code: sec_error_unknown_issuer). You
can add an exception for your server to allow the connection
to proceed. If all goes well, you should eventually see
"It works!" in the browser window. Choose
Tools->Page Info, select the
"Security" tab, click on "View Certificate" followed by
"Details" to look at the certificate fields.
For example, scroll down and look at the Algorithm Identifier
and Algorithm Identifier under Subject Public Key Info. You
should see "Elliptic Curve Public Key" and "ANSI X9.62
elliptic curve prime256v1 (aka secp256r1, NIST P-256)"
respectively indicating that the connection used an ECC
ciphersuite.
The truly adventurous can point Firefox to
the URL about:config and type security.ssl3.ec
in the Filter field to list all supported ECC cipher suites.
Each cipher suite can then be individually enabled/disabled
by double clicking its name.
|