diff -rNU 50 ../httpd-2.2.12-o/docs/conf/extra/httpd-ssl.conf.in ./docs/conf/extra/httpd-ssl.conf.in
--- ../httpd-2.2.12-o/docs/conf/extra/httpd-ssl.conf.in	2008-02-05 00:00:07.000000000 +0100
+++ ./docs/conf/extra/httpd-ssl.conf.in	2014-01-22 16:56:00.000000000 +0100
@@ -40,119 +40,128 @@
 ##  SSL Global Context
 ##
 ##  All SSL configuration in this context applies both to
 ##  the main server and all SSL-enabled virtual hosts.
 ##
 
 #
 #   Some MIME-types for downloading Certificates and CRLs
 #
 AddType application/x-x509-ca-cert .crt
 AddType application/x-pkcs7-crl    .crl
 
 #   Pass Phrase Dialog:
 #   Configure the pass phrase gathering process.
 #   The filtering dialog program (`builtin' is a internal
 #   terminal dialog) has to provide the pass phrase on stdout.
 SSLPassPhraseDialog  builtin
 
 #   Inter-Process Session Cache:
 #   Configure the SSL Session Cache: First the mechanism 
 #   to use and second the expiring timeout (in seconds).
 #SSLSessionCache         "dbm:@exp_runtimedir@/ssl_scache"
 SSLSessionCache        "shmcb:@exp_runtimedir@/ssl_scache(512000)"
 SSLSessionCacheTimeout  300
 
 #   Semaphore:
 #   Configure the path to the mutual exclusion semaphore the
 #   SSL engine uses internally for inter-process synchronization. 
 SSLMutex  "file:@exp_runtimedir@/ssl_mutex"
 
 ##
 ## SSL Virtual Host Context
 ##
 
 <VirtualHost _default_:@@SSLPort@@>
 
 #   General setup for the virtual host
 DocumentRoot "@exp_htdocsdir@"
 ServerName www.example.com:@@SSLPort@@
 ServerAdmin you@example.com
 ErrorLog "@exp_logfiledir@/error_log"
 TransferLog "@exp_logfiledir@/access_log"
 
 #   SSL Engine Switch:
 #   Enable/Disable SSL for this virtual host.
 SSLEngine on
 
 #   SSL Cipher Suite:
 #   List the ciphers that the client is permitted to negotiate.
 #   See the mod_ssl documentation for a complete list.
+#   Recent OpenSSL snapshots include Elliptic Curve Cryptograhpy (ECC) 
+#   cipher suites (see RFC 4492) as part of "ALL". Edit this line
+#   if you need to disable any of those ciphers.
 SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
 
 #   Server Certificate:
 #   Point SSLCertificateFile at a PEM encoded certificate.  If
 #   the certificate is encrypted, then you will be prompted for a
 #   pass phrase.  Note that a kill -HUP will prompt again.  Keep
 #   in mind that if you have both an RSA and a DSA certificate you
 #   can configure both in parallel (to also allow the use of DSA
 #   ciphers, etc.)
+#   Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt)
+#   require an ECC certificate which can also be configured in
+#   parallel.
 SSLCertificateFile "@exp_sysconfdir@/server.crt"
 #SSLCertificateFile "@exp_sysconfdir@/server-dsa.crt"
+#SSLCertificateFile "@exp_sysconfdir@/server-ecc.crt"
 
 #   Server Private Key:
 #   If the key is not combined with the certificate, use this
 #   directive to point at the key file.  Keep in mind that if
 #   you've both a RSA and a DSA private key you can configure
 #   both in parallel (to also allow the use of DSA ciphers, etc.)
+#   ECC keys, when in use, can also be configured in parallel
 SSLCertificateKeyFile "@exp_sysconfdir@/server.key"
 #SSLCertificateKeyFile "@exp_sysconfdir@/server-dsa.key"
+#SSLCertificateKeyFile "@exp_sysconfdir@/server-ecc.key"
 
 #   Server Certificate Chain:
 #   Point SSLCertificateChainFile at a file containing the
 #   concatenation of PEM encoded CA certificates which form the
 #   certificate chain for the server certificate. Alternatively
 #   the referenced file can be the same as SSLCertificateFile
 #   when the CA certificates are directly appended to the server
 #   certificate for convinience.
 #SSLCertificateChainFile "@exp_sysconfdir@/server-ca.crt"
 
 #   Certificate Authority (CA):
 #   Set the CA certificate verification path where to find CA
 #   certificates for client authentication or alternatively one
 #   huge file containing all of them (file must be PEM encoded)
 #   Note: Inside SSLCACertificatePath you need hash symlinks
 #         to point to the certificate files. Use the provided
 #         Makefile to update the hash symlinks after changes.
 #SSLCACertificatePath "@exp_sysconfdir@/ssl.crt"
 #SSLCACertificateFile "@exp_sysconfdir@/ssl.crt/ca-bundle.crt"
 
 #   Certificate Revocation Lists (CRL):
 #   Set the CA revocation path where to find CA CRLs for client
 #   authentication or alternatively one huge file containing all
 #   of them (file must be PEM encoded)
 #   Note: Inside SSLCARevocationPath you need hash symlinks
 #         to point to the certificate files. Use the provided
 #         Makefile to update the hash symlinks after changes.
 #SSLCARevocationPath "@exp_sysconfdir@/ssl.crl"
 #SSLCARevocationFile "@exp_sysconfdir@/ssl.crl/ca-bundle.crl"
 
 #   Client Authentication (Type):
 #   Client certificate verification type and depth.  Types are
 #   none, optional, require and optional_no_ca.  Depth is a
 #   number which specifies how deeply to verify the certificate
 #   issuer chain before deciding the certificate is not valid.
 #SSLVerifyClient require
 #SSLVerifyDepth  10
 
 #   Access Control:
 #   With SSLRequire you can do per-directory access control based
 #   on arbitrary complex boolean expressions containing server
 #   variable checks and other lookup directives.  The syntax is a
 #   mixture between C and Perl.  See the mod_ssl documentation
 #   for more details.
 #<Location />
 #SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
 #            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
 #            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
 #            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
 #            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/mod_ssl.c ./modules/ssl/mod_ssl.c
--- ../httpd-2.2.12-o/modules/ssl/mod_ssl.c	2009-05-19 13:44:59.000000000 +0200
+++ ./modules/ssl/mod_ssl.c	2014-01-22 16:56:00.000000000 +0100
@@ -372,100 +372,103 @@
     sc = mySrvConfig(server);
 
     /*
      * Seed the Pseudo Random Number Generator (PRNG)
      */
     ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
 
     mctx = sslconn->is_proxy ? sc->proxy : sc->server;
 
     /*
      * Create a new SSL connection with the configured server SSL context and
      * attach this to the socket. Additionally we register this attachment
      * so we can detach later.
      */
     if (!(ssl = SSL_new(mctx->ssl_ctx))) {
         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
                       "Unable to create a new SSL connection from the SSL "
                       "context");
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
 
         c->aborted = 1;
 
         return DECLINED; /* XXX */
     }
 
     vhost_md5 = ap_md5_binary(c->pool, (unsigned char *)sc->vhost_id,
                               sc->vhost_id_len);
 
     if (!SSL_set_session_id_context(ssl, (unsigned char *)vhost_md5,
                                     APR_MD5_DIGESTSIZE*2))
     {
         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
                       "Unable to set session id context to `%s'", vhost_md5);
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
 
         c->aborted = 1;
 
         return DECLINED; /* XXX */
     }
 
     SSL_set_app_data(ssl, c);
     SSL_set_app_data2(ssl, NULL); /* will be request_rec */
 
     sslconn->ssl = ssl;
 
     /*
      *  Configure callbacks for SSL connection
      */
     SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
     SSL_set_tmp_dh_callback(ssl,  ssl_callback_TmpDH);
+#ifndef OPENSSL_NO_EC
+    SSL_set_tmp_ecdh_callback(ssl, ssl_callback_TmpECDH);
+#endif
 
     SSL_set_verify_result(ssl, X509_V_OK);
 
     ssl_io_filter_init(c, ssl);
 
     return APR_SUCCESS;
 }
 
 static const char *ssl_hook_http_scheme(const request_rec *r)
 {
     SSLSrvConfigRec *sc = mySrvConfig(r->server);
 
     if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
         return NULL;
     }
 
     return "https";
 }
 
 static apr_port_t ssl_hook_default_port(const request_rec *r)
 {
     SSLSrvConfigRec *sc = mySrvConfig(r->server);
 
     if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
         return 0;
     }
 
     return 443;
 }
 
 static int ssl_hook_pre_connection(conn_rec *c, void *csd)
 {
     SSLSrvConfigRec *sc;
     SSLConnRec *sslconn = myConnConfig(c);
 
     if (sslconn) {
         sc = mySrvConfig(sslconn->server);
     }
     else {
         sc = mySrvConfig(c->base_server);
     }
     /*
      * Immediately stop processing if SSL is disabled for this connection
      */
     if (!(sc && (sc->enabled == SSL_ENABLED_TRUE ||
                  (sslconn && sslconn->is_proxy))))
     {
         return DECLINED;
     }
 
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/ssl_engine_init.c ./modules/ssl/ssl_engine_init.c
--- ../httpd-2.2.12-o/modules/ssl/ssl_engine_init.c	2014-01-22 16:54:25.000000000 +0100
+++ ./modules/ssl/ssl_engine_init.c	2014-01-22 16:56:00.000000000 +0100
@@ -304,101 +304,105 @@
     ENGINE *e;
 
     if (mc->szCryptoDevice) {
         if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                          "Init: Failed to load Crypto Device API `%s'",
                          mc->szCryptoDevice);
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
             ssl_die();
         }
 
         if (strEQ(mc->szCryptoDevice, "chil")) {
             ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
         }
 
         if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                          "Init: Failed to enable Crypto Device API `%s'",
                          mc->szCryptoDevice);
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
             ssl_die();
         }
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 
                      "Init: loaded Crypto Device API `%s'", 
                      mc->szCryptoDevice);
 
         ENGINE_free(e);
     }
 }
 #endif
 
 static void ssl_init_server_check(server_rec *s,
                                   apr_pool_t *p,
                                   apr_pool_t *ptemp,
                                   modssl_ctx_t *mctx)
 {
     /*
      * check for important parameters and the
      * possibility that the user forgot to set them.
      */
     if (!mctx->pks->cert_files[0]) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "No SSL Certificate set [hint: SSLCertificateFile]");
         ssl_die();
     }
 
     /*
      *  Check for problematic re-initializations
      */
     if (mctx->pks->certs[SSL_AIDX_RSA] ||
-        mctx->pks->certs[SSL_AIDX_DSA])
+        mctx->pks->certs[SSL_AIDX_DSA]
+#ifndef OPENSSL_NO_EC
+      || mctx->pks->certs[SSL_AIDX_ECC]
+#endif
+        )
     {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "Illegal attempt to re-initialise SSL for server "
                 "(theoretically shouldn't happen!)");
         ssl_die();
     }
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 static void ssl_init_ctx_tls_extensions(server_rec *s,
                                         apr_pool_t *p,
                                         apr_pool_t *ptemp,
                                         modssl_ctx_t *mctx)
 {
     /*
      * Configure TLS extensions support
      */
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "Configuring TLS extension handling");
 
     /*
      * Server name indication (SNI)
      */
     if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
                           ssl_callback_ServerNameIndication) ||
         !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                      "Unable to initialize TLS servername extension "
                      "callback (incompatible OpenSSL version?)");
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         ssl_die();
     }
 }
 #endif
 
 static void ssl_init_ctx_protocol(server_rec *s,
                                   apr_pool_t *p,
                                   apr_pool_t *ptemp,
                                   modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = NULL;
     MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
     char *cp;
     int protocol = mctx->protocol;
 
     /*
      *  Create the new per-server SSL context
      */
     if (protocol == SSL_PROTOCOL_NONE) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
@@ -455,100 +459,103 @@
 #endif
 
     SSL_CTX_set_app_data(ctx, s);
 
     /*
      * Configure additional context ingredients
      */
     SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
 
 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
     /*
      * Disallow a session from being resumed during a renegotiation,
      * so that an acceptable cipher suite can be negotiated.
      */
     SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
 #endif
 }
 
 static void ssl_init_ctx_session_cache(server_rec *s,
                                        apr_pool_t *p,
                                        apr_pool_t *ptemp,
                                        modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
     SSLModConfigRec *mc = myModConfig(s);
     long cache_mode = SSL_SESS_CACHE_OFF;
     if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
         /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
          * to ignore process local-caching and
          * to always get/set/delete sessions using mod_ssl's callbacks.
          */
         cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
     }
 
     SSL_CTX_set_session_cache_mode(ctx, cache_mode);
 
     SSL_CTX_sess_set_new_cb(ctx,    ssl_callback_NewSessionCacheEntry);
     SSL_CTX_sess_set_get_cb(ctx,    ssl_callback_GetSessionCacheEntry);
     SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
 }
 
 static void ssl_init_ctx_callbacks(server_rec *s,
                                    apr_pool_t *p,
                                    apr_pool_t *ptemp,
                                    modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
 
     SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
     SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
+#ifndef OPENSSL_NO_EC
+    SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH);
+#endif
 
     SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
 }
 
 static void ssl_init_ctx_verify(server_rec *s,
                                 apr_pool_t *p,
                                 apr_pool_t *ptemp,
                                 modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
 
     int verify = SSL_VERIFY_NONE;
     STACK_OF(X509_NAME) *ca_list;
 
     if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) {
         mctx->auth.verify_mode = SSL_CVERIFY_NONE;
     }
 
     if (mctx->auth.verify_depth == UNSET) {
         mctx->auth.verify_depth = 1;
     }
 
     /*
      *  Configure callbacks for SSL context
      */
     if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
         verify |= SSL_VERIFY_PEER_STRICT;
     }
 
     if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
         (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
     {
         verify |= SSL_VERIFY_PEER;
     }
 
     SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify);
 
     /*
      * Configure Client Authentication details
      */
     if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                      "Configuring client authentication");
 
         if (!SSL_CTX_load_verify_locations(ctx,
                          MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
                          MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
         {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                     "Unable to configure verify locations "
@@ -722,103 +729,110 @@
     }
 }
 
 static int ssl_server_import_cert(server_rec *s,
                                   modssl_ctx_t *mctx,
                                   const char *id,
                                   int idx)
 {
     SSLModConfigRec *mc = myModConfig(s);
     ssl_asn1_t *asn1;
     MODSSL_D2I_X509_CONST unsigned char *ptr;
     const char *type = ssl_asn1_keystr(idx);
     X509 *cert;
 
     if (!(asn1 = ssl_asn1_table_get(mc->tPublicCert, id))) {
         return FALSE;
     }
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "Configuring %s server certificate", type);
 
     ptr = asn1->cpData;
     if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "Unable to import %s server certificate", type);
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         ssl_die();
     }
 
     if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "Unable to configure %s server certificate", type);
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         ssl_die();
     }
 
     mctx->pks->certs[idx] = cert;
 
     return TRUE;
 }
 
 static int ssl_server_import_key(server_rec *s,
                                  modssl_ctx_t *mctx,
                                  const char *id,
                                  int idx)
 {
     SSLModConfigRec *mc = myModConfig(s);
     ssl_asn1_t *asn1;
     MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
     const char *type = ssl_asn1_keystr(idx);
-    int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+    int pkey_type;
     EVP_PKEY *pkey;
 
+#ifndef OPENSSL_NO_EC
+    if (idx == SSL_AIDX_ECC)
+      pkey_type = EVP_PKEY_EC;
+    else
+#endif /* SSL_LIBRARY_VERSION */
+    pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+
     if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
         return FALSE;
     }
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "Configuring %s server private key", type);
 
     ptr = asn1->cpData;
     if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData)))
     {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "Unable to import %s server private key", type);
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         ssl_die();
     }
 
     if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "Unable to configure %s server private key", type);
         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
         ssl_die();
     }
 
     /*
      * XXX: wonder if this is still needed, this is old todo doc.
      * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html)
      */
     if ((pkey_type == EVP_PKEY_DSA) && mctx->pks->certs[idx]) {
         EVP_PKEY *pubkey = X509_get_pubkey(mctx->pks->certs[idx]);
 
         if (pubkey && EVP_PKEY_missing_parameters(pubkey)) {
             EVP_PKEY_copy_parameters(pubkey, pkey);
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                     "Copying DSA parameters from private key to certificate");
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
             EVP_PKEY_free(pubkey);
         }
     }
 
     mctx->pks->keys[idx] = pkey;
 
     return TRUE;
 }
 
 static void ssl_check_public_cert(server_rec *s,
                                   apr_pool_t *ptemp,
                                   X509 *cert,
                                   int type)
 {
     int is_ca, pathlen;
@@ -834,128 +848,153 @@
 
     if (SSL_X509_isSGC(cert)) {
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
                      "%s server certificate enables "
                      "Server Gated Cryptography (SGC)",
                      ssl_asn1_keystr(type));
     }
 
     if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
         if (is_ca) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                          "%s server certificate is a CA certificate "
                          "(BasicConstraints: CA == TRUE !?)",
                          ssl_asn1_keystr(type));
         }
 
         if (pathlen > 0) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                          "%s server certificate is not a leaf certificate "
                          "(BasicConstraints: pathlen == %d > 0 !?)",
                          ssl_asn1_keystr(type), pathlen);
         }
     }
 
     if (SSL_X509_getCN(ptemp, cert, &cn)) {
         int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
 
         if (apr_fnmatch_test(cn)) {
             if (apr_fnmatch(cn, s->server_hostname,
                             fnm_flags) == APR_FNM_NOMATCH) {
                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                              "%s server certificate wildcard CommonName "
                              "(CN) `%s' does NOT match server name!?",
                              ssl_asn1_keystr(type), cn);
             }
         }
         else if (strNE(s->server_hostname, cn)) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                          "%s server certificate CommonName (CN) `%s' "
                          "does NOT match server name!?",
                          ssl_asn1_keystr(type), cn);
         }
     }
 }
 
 static void ssl_init_server_certs(server_rec *s,
                                   apr_pool_t *p,
                                   apr_pool_t *ptemp,
                                   modssl_ctx_t *mctx)
 {
-    const char *rsa_id, *dsa_id;
+    const char *rsa_id, *dsa_id, *ecc_id;
     const char *vhost_id = mctx->sc->vhost_id;
     int i;
-    int have_rsa, have_dsa;
+    int have_rsa, have_dsa, have_ecc;
 
     rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
     dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+    ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
+#endif
 
     have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
     have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+    have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
 
-    if (!(have_rsa || have_dsa)) {
+    if (!(have_rsa || have_dsa
+#ifndef OPENSSL_NO_EC
+        || have_ecc
+#endif
+)) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+#ifndef OPENSSL_NO_EC
+                "Oops, no RSA, DSA or ECC server certificate found "
+#else
                 "Oops, no RSA or DSA server certificate found "
+#endif
                 "for '%s:%d'?!", s->server_hostname, s->port);
         ssl_die();
     }
 
     for (i = 0; i < SSL_AIDX_MAX; i++) {
         ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i);
     }
 
     have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
     have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
+#if SSL_LIBRARY_VERSION >= 0x00908000
+    have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
 
-    if (!(have_rsa || have_dsa)) {
+    if (!(have_rsa || have_dsa
+#if SSL_LIBRARY_VERSION >= 0x00908000
+        || have_ecc
+#endif
+          )) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+#if SSL_LIBRARY_VERSION >= 0x00908000
+                "Oops, no RSA, DSA or ECC server private key found?!");
+#else
                 "Oops, no RSA or DSA server private key found?!");
+#endif
         ssl_die();
     }
 }
 
 static void ssl_init_proxy_certs(server_rec *s,
                                  apr_pool_t *p,
                                  apr_pool_t *ptemp,
                                  modssl_ctx_t *mctx)
 {
     int n, ncerts = 0;
     STACK_OF(X509_INFO) *sk;
     modssl_pk_proxy_t *pkp = mctx->pkp;
 
     SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
                                ssl_callback_proxy_cert);
 
     if (!(pkp->cert_file || pkp->cert_path)) {
         return;
     }
 
     sk = sk_X509_INFO_new_null();
 
     if (pkp->cert_file) {
         SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
     }
 
     if (pkp->cert_path) {
         SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
     }
 
     if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
         sk_X509_INFO_free(sk);
         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                      "no client certs found for SSL proxy");
         return;
     }
 
     /* Check that all client certs have got certificates and private
      * keys. */
     for (n = 0; n < ncerts; n++) {
         X509_INFO *inf = sk_X509_INFO_value(sk, n);
 
         if (!inf->x509 || !inf->x_pkey) {
             sk_X509_INFO_free(sk);
             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
                          "incomplete client cert configured for SSL proxy "
                          "(missing or encrypted private key?)");
             ssl_die();
             return;
         }
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/ssl_engine_kernel.c ./modules/ssl/ssl_engine_kernel.c
--- ../httpd-2.2.12-o/modules/ssl/ssl_engine_kernel.c	2014-01-22 16:54:25.000000000 +0100
+++ ./modules/ssl/ssl_engine_kernel.c	2014-01-22 16:56:00.000000000 +0100
@@ -1278,100 +1278,127 @@
     int idx;
 
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
                   "handing out temporary %d bit RSA key", keylen);
 
     /* doesn't matter if export flag is on,
      * we won't be asked for keylen > 512 in that case.
      * if we are asked for a keylen > 1024, it is too expensive
      * to generate on the fly.
      * XXX: any reason not to generate 2048 bit keys at startup?
      */
 
     switch (keylen) {
       case 512:
         idx = SSL_TMP_KEY_RSA_512;
         break;
 
       case 1024:
       default:
         idx = SSL_TMP_KEY_RSA_1024;
     }
 
     return (RSA *)mc->pTmpKeys[idx];
 }
 
 /*
  * Hand out the already generated DH parameters...
  */
 DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
 {
     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
     SSLModConfigRec *mc = myModConfigFromConn(c);
     int idx;
 
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
                   "handing out temporary %d bit DH key", keylen);
 
     switch (keylen) {
       case 512:
         idx = SSL_TMP_KEY_DH_512;
         break;
 
       case 1024:
       default:
         idx = SSL_TMP_KEY_DH_1024;
     }
 
     return (DH *)mc->pTmpKeys[idx];
 }
 
+#ifndef OPENSSL_NO_EC
+EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen)
+{
+    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+    SSLModConfigRec *mc = myModConfig(c->base_server);
+    int idx;
+    static EC_KEY *ecdh = NULL;
+    static init = 0;
+
+    /* XXX Uses 256-bit key for now. TODO: support other sizes. */
+    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                  "handing out temporary 256 bit ECC key");
+
+    if (init == 0) {
+        ecdh = EC_KEY_new();
+        if (ecdh != NULL) {
+            /* ecdh->group = EC_GROUP_new_by_nid(NID_secp160r2); */
+            EC_KEY_set_group(ecdh, 
+              EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+        }
+        init = 1;
+    }
+    
+    return ecdh;
+}
+#endif
+
 /*
  * This OpenSSL callback function is called when OpenSSL
  * does client authentication and verifies the certificate chain.
  */
 int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
 {
     /* Get Apache context back through OpenSSL context */
     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
                                           SSL_get_ex_data_X509_STORE_CTX_idx());
     conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
     request_rec *r      = (request_rec *)SSL_get_app_data2(ssl);
     server_rec *s       = r ? r->server : mySrvFromConn(conn);
 
     SSLSrvConfigRec *sc = mySrvConfig(s);
     SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
     SSLConnRec *sslconn = myConnConfig(conn);
     modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);
 
     /* Get verify ingredients */
     int errnum   = X509_STORE_CTX_get_error(ctx);
     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
     int depth, verify;
 
     /*
      * Log verification information
      */
     if (s->loglevel >= APLOG_DEBUG) {
         X509 *cert  = X509_STORE_CTX_get_current_cert(ctx);
         char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
         char *iname = X509_NAME_oneline(X509_get_issuer_name(cert),  NULL, 0);
 
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn,
                       "Certificate Verification: "
                       "depth: %d, subject: %s, issuer: %s",
                       errdepth,
                       sname ? sname : "-unknown-",
                       iname ? iname : "-unknown-");
 
         if (sname) {
             modssl_free(sname);
         }
 
         if (iname) {
             modssl_free(iname);
         }
     }
 
     /*
      * Check for optionally acceptable non-verifiable issuer situation
      */
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/ssl_private.h ./modules/ssl/ssl_private.h
--- ../httpd-2.2.12-o/modules/ssl/ssl_private.h	2014-01-22 16:54:25.000000000 +0100
+++ ./modules/ssl/ssl_private.h	2014-01-22 16:56:00.000000000 +0100
@@ -134,105 +134,115 @@
 #define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
 #define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
 
 #define myCtxVarSet(mc,num,val)  mc->rCtx.pV##num = val
 #define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num)
 
 /**
  * Defaults for the configuration
  */
 #ifndef SSL_SESSION_CACHE_TIMEOUT
 #define SSL_SESSION_CACHE_TIMEOUT  300
 #endif
 
 /* Default setting for per-dir reneg buffer. */
 #ifndef DEFAULT_RENEG_BUFFER_SIZE
 #define DEFAULT_RENEG_BUFFER_SIZE (128 * 1024)
 #endif
 
 /**
  * Support for MM library
  */
 #define SSL_MM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
 
 /**
  * Support for DBM library
  */
 #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
 
 #if !defined(SSL_DBM_FILE_SUFFIX_DIR) && !defined(SSL_DBM_FILE_SUFFIX_PAG)
 #if defined(DBM_SUFFIX)
 #define SSL_DBM_FILE_SUFFIX_DIR DBM_SUFFIX
 #define SSL_DBM_FILE_SUFFIX_PAG DBM_SUFFIX
 #elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
 #define SSL_DBM_FILE_SUFFIX_DIR ".db"
 #define SSL_DBM_FILE_SUFFIX_PAG ".db"
 #else
 #define SSL_DBM_FILE_SUFFIX_DIR ".dir"
 #define SSL_DBM_FILE_SUFFIX_PAG ".pag"
 #endif
 #endif
 
 /**
  * Define the certificate algorithm types
  */
 
 typedef int ssl_algo_t;
 
 #define SSL_ALGO_UNKNOWN (0)
 #define SSL_ALGO_RSA     (1<<0)
 #define SSL_ALGO_DSA     (1<<1)
+#ifndef OPENSSL_NO_EC
+#define SSL_ALGO_ECC     (1<<2)
+#define SSL_ALGO_ALL     (SSL_ALGO_RSA|SSL_ALGO_DSA|SSL_ALGO_ECC)
+#else
 #define SSL_ALGO_ALL     (SSL_ALGO_RSA|SSL_ALGO_DSA)
+#endif /* SSL_LIBRARY_VERSION */
 
 #define SSL_AIDX_RSA     (0)
 #define SSL_AIDX_DSA     (1)
+#ifndef OPENSSL_NO_EC
+#define SSL_AIDX_ECC     (2)
+#define SSL_AIDX_MAX     (3)
+#else
 #define SSL_AIDX_MAX     (2)
+#endif /* SSL_LIBRARY_VERSION */
 
 
 /**
  * Define IDs for the temporary RSA keys and DH params
  */
 
 #define SSL_TMP_KEY_RSA_512  (0)
 #define SSL_TMP_KEY_RSA_1024 (1)
 #define SSL_TMP_KEY_DH_512   (2)
 #define SSL_TMP_KEY_DH_1024  (3)
 #define SSL_TMP_KEY_MAX      (4)
 
 /**
  * Define the SSL options
  */
 #define SSL_OPT_NONE           (0)
 #define SSL_OPT_RELSET         (1<<0)
 #define SSL_OPT_STDENVVARS     (1<<1)
 #define SSL_OPT_EXPORTCERTDATA (1<<3)
 #define SSL_OPT_FAKEBASICAUTH  (1<<4)
 #define SSL_OPT_STRICTREQUIRE  (1<<5)
 #define SSL_OPT_OPTRENEGOTIATE (1<<6)
 #define SSL_OPT_ALL            (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE)
 typedef int ssl_opt_t;
 
 /**
  * Define the SSL Protocol options
  */
 #define SSL_PROTOCOL_NONE  (0)
 #define SSL_PROTOCOL_SSLV2 (1<<0)
 #define SSL_PROTOCOL_SSLV3 (1<<1)
 #define SSL_PROTOCOL_TLSV1 (1<<2)
 #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
 typedef int ssl_proto_t;
 
 /**
  * Define the SSL verify levels
  */
 typedef enum {
     SSL_CVERIFY_UNSET           = UNSET,
     SSL_CVERIFY_NONE            = 0,
     SSL_CVERIFY_OPTIONAL        = 1,
     SSL_CVERIFY_REQUIRE         = 2,
     SSL_CVERIFY_OPTIONAL_NO_CA  = 3
 } ssl_verify_t;
 
 #define SSL_VERIFY_PEER_STRICT \
      (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
 
 #ifndef X509_V_ERR_CERT_UNTRUSTED
@@ -535,100 +545,103 @@
 const char  *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
 const char  *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProtocol(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLOptions(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRequireSSL(cmd_parms *, void *);
 const char  *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg);
 const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);
 
 const char  *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
 const char  *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyVerify(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag);
 const char  *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
 
 /**  module initialization  */
 int          ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
 void         ssl_init_Engine(server_rec *, apr_pool_t *);
 void         ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *);
 void         ssl_init_CheckServers(server_rec *, apr_pool_t *);
 STACK_OF(X509_NAME) 
             *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *);
 void         ssl_init_Child(apr_pool_t *, server_rec *);
 apr_status_t ssl_init_ModuleKill(void *data);
 
 /**  Apache API hooks  */
 int          ssl_hook_Auth(request_rec *);
 int          ssl_hook_UserCheck(request_rec *);
 int          ssl_hook_Access(request_rec *);
 int          ssl_hook_Fixup(request_rec *);
 int          ssl_hook_ReadReq(request_rec *);
 int          ssl_hook_Upgrade(request_rec *);
 void         ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
 
 /**  OpenSSL callbacks */
 RSA         *ssl_callback_TmpRSA(SSL *, int, int);
 DH          *ssl_callback_TmpDH(SSL *, int, int);
+#ifndef OPENSSL_NO_EC
+EC_KEY      *ssl_callback_TmpECDH(SSL *, int, int);
+#endif /* SSL_LIBRARY_VERSION */
 int          ssl_callback_SSLVerify(int, X509_STORE_CTX *);
 int          ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *);
 int          ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey);
 int          ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *);
 SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
 void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
 void         ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int);
 #ifndef OPENSSL_NO_TLSEXT
 int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
 #endif
 
 /**  Session Cache Support  */
 void         ssl_scache_init(server_rec *, apr_pool_t *);
 void         ssl_scache_status_register(apr_pool_t *p);
 void         ssl_scache_kill(server_rec *);
 BOOL         ssl_scache_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
 SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int);
 void         ssl_scache_remove(server_rec *, UCHAR *, int);
 
 char        *ssl_scache_id2sz(UCHAR *, int);
 void         ssl_scache_dbm_init(server_rec *, apr_pool_t *);
 void         ssl_scache_dbm_kill(server_rec *);
 BOOL         ssl_scache_dbm_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
 SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *, UCHAR *, int);
 void         ssl_scache_dbm_remove(server_rec *, UCHAR *, int);
 void         ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *pool);
 
 void         ssl_scache_shmcb_init(server_rec *, apr_pool_t *);
 void         ssl_scache_shmcb_kill(server_rec *);
 BOOL         ssl_scache_shmcb_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
 SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *, UCHAR *, int);
 void         ssl_scache_shmcb_remove(server_rec *, UCHAR *, int);
 void         ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *pool);
 
 void         ssl_scache_dc_init(server_rec *, apr_pool_t *);
 void         ssl_scache_dc_kill(server_rec *);
 BOOL         ssl_scache_dc_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
 SSL_SESSION *ssl_scache_dc_retrieve(server_rec *, UCHAR *, int);
 void         ssl_scache_dc_remove(server_rec *, UCHAR *, int);
 void         ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool);
 
 /** Proxy Support */
 int ssl_proxy_enable(conn_rec *c);
 int ssl_engine_disable(conn_rec *c);
 
 /**  I/O  */
 void         ssl_io_filter_init(conn_rec *, SSL *);
 void         ssl_io_filter_register(apr_pool_t *);
 long         ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long);
 
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/ssl_toolkit_compat.h ./modules/ssl/ssl_toolkit_compat.h
--- ../httpd-2.2.12-o/modules/ssl/ssl_toolkit_compat.h	2009-05-19 13:44:59.000000000 +0200
+++ ./modules/ssl/ssl_toolkit_compat.h	2014-01-22 16:55:32.000000000 +0100
@@ -1,90 +1,98 @@
 /* Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef SSL_TOOLKIT_COMPAT_H
 #define SSL_TOOLKIT_COMPAT_H
 
 /**
  * @file ssl_toolkit_compat.h 
  * @brief this header file provides a compatiblity layer
  *        between OpenSSL and RSA sslc
  *
  * @defgroup MOD_SSL_TOOLKIT Toolkit
  * @ingroup  MOD_SSL
  * @{
  */
 
 #ifdef HAVE_OPENSSL
 
 /** OpenSSL headers */
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
+
+/* ECC support came along in OpenSSL 0.9.8 */
+#if (OPENSSL_VERSION_NUMBER < 0x00908000)
+#define OPENSSL_NO_EC
+#endif
+
+
+
 /** Avoid tripping over an engine build installed globally and detected
  * when the user points at an explicit non-engine flavor of OpenSSL
  */
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
 #include <openssl/engine.h>
 #endif
 
 /**
  * rsa sslc uses incomplete types for most structures
  * so we macroize for OpenSSL those which cannot be dereferenced
  * using the same sames as the sslc functions
  */
 
 #define EVP_PKEY_key_type(k)              (EVP_PKEY_type(k->type))
 
 #define X509_NAME_get_entries(xs)         (xs->entries)
 #define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber)
 
 #define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm)
 #define X509_get_key_algorithm(xs)       (xs->cert_info->key->algor->algorithm)
 
 #define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data)
 #define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length)
 
 #define SSL_CTX_get_extra_certs(ctx)       (ctx->extra_certs)
 #define SSL_CTX_set_extra_certs(ctx,value) {ctx->extra_certs = value;}
 
 #define SSL_CIPHER_get_name(s)             (s->name)
 #define SSL_CIPHER_get_valid(s)            (s->valid)
 
 #define SSL_SESSION_get_session_id(s)      (s->session_id)
 #define SSL_SESSION_get_session_id_length(s) (s->session_id_length)
 
 /**
  * Support for retrieving/overriding states
  */
 #ifndef SSL_get_state
 #define SSL_get_state(ssl) SSL_state(ssl)
 #endif
 
 #define SSL_set_state(ssl,val) (ssl)->state = val
 
 #define MODSSL_BIO_CB_ARG_TYPE const char
 #define MODSSL_CRYPTO_CB_ARG_TYPE const char
 #if (OPENSSL_VERSION_NUMBER < 0x00907000)
 # define MODSSL_INFO_CB_ARG_TYPE SSL*
 #else
 # define MODSSL_INFO_CB_ARG_TYPE const SSL*
 #endif
 #define MODSSL_CLIENT_CERT_CB_ARG_TYPE X509
diff -rNU 50 ../httpd-2.2.12-o/modules/ssl/ssl_util.c ./modules/ssl/ssl_util.c
--- ../httpd-2.2.12-o/modules/ssl/ssl_util.c	2008-09-18 16:34:51.000000000 +0200
+++ ./modules/ssl/ssl_util.c	2014-01-22 16:56:00.000000000 +0100
@@ -103,196 +103,210 @@
 
     if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
         return NULL;
     /* XXX: we are reading 1 byte at a time here */
     for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
                 && nbytes == 1 && (k < MAX_STRING_LEN-1)     ; ) {
         if (c == '\n' || c == '\r')
             break;
         buf[k++] = c;
     }
     buf[k] = NUL;
     ssl_util_ppclose(s, p, fp);
 
     return buf;
 }
 
 BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
 {
     apr_finfo_t finfo;
 
     if (path == NULL)
         return FALSE;
     if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
                                 APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
         return FALSE;
     if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
         return FALSE;
     if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
         return FALSE;
     if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
         return FALSE;
     return TRUE;
 }
 
 ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
 {
     ssl_algo_t t;
     EVP_PKEY *pFreeKey = NULL;
 
     t = SSL_ALGO_UNKNOWN;
     if (pCert != NULL)
         pFreeKey = pKey = X509_get_pubkey(pCert);
     if (pKey != NULL) {
         switch (EVP_PKEY_key_type(pKey)) {
             case EVP_PKEY_RSA:
                 t = SSL_ALGO_RSA;
                 break;
             case EVP_PKEY_DSA:
                 t = SSL_ALGO_DSA;
                 break;
+#ifndef OPENSSL_NO_EC
+            case EVP_PKEY_EC:
+                t = SSL_ALGO_ECC;
+                break;
+#endif 
             default:
                 break;
         }
     }
 #ifdef OPENSSL_VERSION_NUMBER
     /* Only refcounted in OpenSSL */
     if (pFreeKey != NULL)
         EVP_PKEY_free(pFreeKey);
 #endif
     return t;
 }
 
 char *ssl_util_algotypestr(ssl_algo_t t)
 {
     char *cp;
 
     cp = "UNKNOWN";
     switch (t) {
         case SSL_ALGO_RSA:
             cp = "RSA";
             break;
         case SSL_ALGO_DSA:
             cp = "DSA";
             break;
+#ifndef OPENSSL_NO_EC
+        case SSL_ALGO_ECC:
+            cp = "ECC";
+            break;
+#endif
         default:
             break;
     }
     return cp;
 }
 
 /*
  * certain key and cert data needs to survive restarts,
  * which are stored in the user data table of s->process->pool.
  * to prevent "leaking" of this data, we use malloc/free
  * rather than apr_palloc and these wrappers to help make sure
  * we do not leak the malloc-ed data.
  */
 unsigned char *ssl_asn1_table_set(apr_hash_t *table,
                                   const char *key,
                                   long int length)
 {
     apr_ssize_t klen = strlen(key);
     ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
 
     /*
      * if a value for this key already exists,
      * reuse as much of the already malloc-ed data
      * as possible.
      */
     if (asn1) {
         if (asn1->nData != length) {
             free(asn1->cpData); /* XXX: realloc? */
             asn1->cpData = NULL;
         }
     }
     else {
         asn1 = malloc(sizeof(*asn1));
         asn1->source_mtime = 0; /* used as a note for encrypted private keys */
         asn1->cpData = NULL;
     }
 
     asn1->nData = length;
     if (!asn1->cpData) {
         asn1->cpData = malloc(length);
     }
 
     apr_hash_set(table, key, klen, asn1);
 
     return asn1->cpData; /* caller will assign a value to this */
 }
 
 ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
                                const char *key)
 {
     return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
 }
 
 void ssl_asn1_table_unset(apr_hash_t *table,
                           const char *key)
 {
     apr_ssize_t klen = strlen(key);
     ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
 
     if (!asn1) {
         return;
     }
 
     if (asn1->cpData) {
         free(asn1->cpData);
     }
     free(asn1);
 
     apr_hash_set(table, key, klen, NULL);
 }
 
+#ifndef OPENSSL_NO_EC
+static const char *ssl_asn1_key_types[] = {"RSA", "DSA", "ECC"};
+#else
 static const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
+#endif
 
 const char *ssl_asn1_keystr(int keytype)
 {
     if (keytype >= SSL_AIDX_MAX) {
         return NULL;
     }
 
     return ssl_asn1_key_types[keytype];
 }
 
 const char *ssl_asn1_table_keyfmt(apr_pool_t *p,
                                   const char *id,
                                   int keytype)
 {
     const char *keystr = ssl_asn1_keystr(keytype);
 
     return apr_pstrcat(p, id, ":", keystr, NULL);
 }
 
 
 #if APR_HAS_THREADS
 /*
  * To ensure thread-safetyness in OpenSSL - work in progress
  */
 
 static apr_thread_mutex_t **lock_cs;
 static int                  lock_num_locks;
 
 #ifdef HAVE_SSLC
 #if SSLC_VERSION_NUMBER >= 0x2000
 static int ssl_util_thr_lock(int mode, int type,
                              char *file, int line)
 #else
 static void ssl_util_thr_lock(int mode, int type,
                               char *file, int line)
 #endif
 #else
 static void ssl_util_thr_lock(int mode, int type,
                               const char *file, int line)
 #endif
 {
     if (type < lock_num_locks) {
         if (mode & CRYPTO_LOCK) {
             apr_thread_mutex_lock(lock_cs[type]);
         }
         else {
             apr_thread_mutex_unlock(lock_cs[type]);
         }
 #ifdef HAVE_SSLC
 #if SSLC_VERSION_NUMBER >= 0x2000
