Apache with Elliptic Curve Cryptography

This document describes how to build an Apache 2.2.2 web server with support for Elliptic Curve Cryptography cipher suites (RFC 4492) using OpenSSL 0.9.9-dev.

Step 1: Building ECC-enabled OpenSSL

  1. Create an installation root directory and set an environment variable $MY_INSTALL_ROOT to point to it. The declaration of $MY_INSTALL_ROOT varies among shells. This example works for bash shells:
          % export MY_INSTALL_ROOT=absolute_path_to_installation_directory
          % mkdir $MY_INSTALL_ROOT
        
  2. Download openssl-SNAP-20060724.tar.gz (or similar) from the OpenSSL snapshot page. Save it to $MY_INSTALL_ROOT and set an environment variable to point to the OpenSSL directory.
          % cd $MY_INSTALL_ROOT
          % gunzip openssl-SNAP-20040211.tar.gz
          % tar xvf openssl-SNAP-20040211.tar
          % export MY_OPENSSL=$MY_INSTALL_ROOT/openssl-SNAP-20040211
        
  3. Configure and compile OpenSSL and verify the compilation by executing tests.
          % cd $MY_OPENSSL
          % ./config
          % make 
          % make test
        

Step 2: Building Apache 2.2.2 with OpenSSL

  1. Download Apache httpd-2.2.2.tar.gz from the Apache Software Foundation and save it to $MY_INSTALL_ROOT. Also create an installation directory for Apache (e.g., Apache-Install) under $MY_INSTALL_ROOT.
          % cd $MY_INSTALL_ROOT
          % gunzip httpd-2.2.2.tar.gz
          % tar xvf httpd-2.2.2.tar
    
          % mkdir $MY_INSTALL_ROOT/Apache-Install
        
  2. Apache is linked to OpenSSL through the mod_ssl module. This module is included in httpd-2.2.2 but needs to be patched to expose the elliptic curve cryptography capabilities in OpenSSL. This patch can be applied with the GNU patch tool:
          % cd $MY_INSTALL_ROOT/httpd-2.2.2
          % patch -p 0 -i enable-ecc-in-modssl-20060725171010.patch
        
  3. Configure, compile and install Apache.
          % ./configure --prefix=$MY_INSTALL_ROOT/Apache-Install/ --enable-ssl --enable-so --with-ssl=$MY_OPENSSL
          % make
          % make install
        

Step 3: Generate suitable certificates

To test the Apache web server with ECC and RSA cipher suites, RSA and ECC certificates are needed.
  1. An RSA certificate can be generated with OpenSSL and installed into the Apache installation directory as follows:
          % cd $MY_OPENSSL/demos/ssltest-ecc
          % ./RSAcertgen.sh 
          % cp Certs/rsa1024TestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-rsa.crt
          % cp Certs/rsa1024TestServer.key.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-rsa.key
        
  2. Likewise, ECC certificates can be generated and installed. To change the elliptic curves used in the certificate from the default "secp160r1" and "secp160r2", open file $MY_OPENSSL/demos/ssltest-ecc/ECCcertgen.sh in an editor and replace "secp160r1" and "secp160r2" with the desired curves. We highly recommend using secp256r1 since that curve is also supported in the version of Internet Explorer that will be included in Windows vista). You should also edit the "distinguished name" field in the certificate appropriately, e.g. insert the server's hostname in the CN component.
          % ./ECCcertgen.sh     # Produces ECDSA-signed ECC certs
          % cp Certs/secp160r2TestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
          % cp Certs/secp160r2TestServer.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. Alternatively, if you need an RSA-signed ECC certificate for use in ECDH-RSA ciphers, do the following:
          % ./ECC-RSAcertgen.sh  # Produces RSA-signed ECC certs
          % cp Certs/sect163r1-rsaTestServer.cert.pem $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
          % cp Certs/sect163r1-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 certs simultaneously.

Edit Apache config files

  1. Apache can either be run on regular HTTP port 80, which requires superuser rights, or it can be run by any user on higher port numbers, e.g. 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
        
    Finally, uncomment the following line in httpd.conf
          #Include conf/extra/httpd-ssl.conf
        
  2. Likewise, Apache can accept secure connections on regular HTTPS port 443, which requires superuser rights, or it can use an unprivileged port, e.g., 8443. The following lines in $MY_INSTALL_ROOT/Apache-Install/conf/extra/httpd-ssl.conf may have to be modified (replace 443 with 8443 and _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 to contain the cipher suites you wish to enable.
        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
        
    NOTE: In recent development versions of OpenSSL, ECC cipher suites are part of "ALL" and "ECCdraft" is no longer a valid cipher suite descriptor.

  3. To enable the generated ECC and RSA certificates, the following lines in $MY_INSTALL_ROOT/Apache-Install/conf/extra/httpd-ssl.conf have to be added or uncommented:
        SSLCertificateFile $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.crt
    
        SSLCertificateKeyFile $MY_INSTALL_ROOT/Apache-Install/conf/server-ecc.key
        

Testing Apache

  1. Start up the Apache web server:
          % $MY_INSTALL_ROOT/Apache-Install/bin/apachectl start
        
  2. Connect to it via the OpenSSL s_client application:
          % $MY_OPENSSL/apps/openssl s_client -connect [server_name]:8443 -cipher ECDH-ECDSA-AES128-SHA
        
  3. Upon successful installation, this command should show an output similar to the following:
    CONNECTED(00000004)
    depth=0 /C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)
    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 Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)
    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 Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)
    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 Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)
       i:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (Elliptic curve secp160r1)
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIICCDCCAcgCAQMwCQYHKoZIzj0EATCBqDELMAkGA1UEBhMCVVMxCzAJBgNVBAgT
    AkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MR8wHQYDVQQKExZTdW4gTWljcm9z
    eXN0ZW1zLCBJbmMuMSYwJAYDVQQLEx1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRv
    cmllczErMCkGA1UEAxMiVGVzdCBDQSAoRWxsaXB0aWMgY3VydmUgc2VjcDE2MHIx
    KTAeFw0wMzA0MjgyMTEwMTJaFw0wNzA2MDYyMTEwMTJaMIGsMQswCQYDVQQGEwJV
    UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHzAdBgNVBAoT
    FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsTHVN1biBNaWNyb3N5c3Rl
    bXMgTGFib3JhdG9yaWVzMS8wLQYDVQQDEyZUZXN0IFNlcnZlciAoRWxsaXB0aWMg
    Y3VydmUgc2VjcDE2MHIyKTA+MBAGByqGSM49AgEGBSuBBAAeAyoABIA2acNvLS/r
    ttA4Yi815YJk/tpjRJ2jH9NOEPK4L6S6kPFk/EEDqi8wCQYHKoZIzj0EAQMvADAs
    AhQ1FpYNGvLCK/u6KIKp9e1Cu/2g3wIUdi3Ko8fSl8VdpkeV9wnpm7+r8Xk=
    -----END CERTIFICATE-----
    subject=/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)
    issuer=/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (Elliptic curve secp160r1)
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 686 bytes and written 156 bytes
    ---
    New, TLSv1/SSLv3, Cipher is ECDH-ECDSA-AES128-SHA
    Server public key is 161 bit
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : ECDH-ECDSA-AES128-SHA
        Session-ID: 9D975718F660A2DC90A55141CE4904AE93BD4EBF32DC67AAE797DEA7CB4A3310
        Session-ID-ctx: 
        Master-Key: 76F7775835F6094D552AF13E37DADF0911151C0C7481D4C3E033138BAABCACB9E9D61FEBE893691B86476B258A157814
        Key-Arg   : None
        Start Time: 1051566707
        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  [ENTER] [ENTER]