
sctemme at apache
Nov 6, 2009, 4:41 PM
Post #1 of 1
(254 views)
Permalink
|
|
[PATCH] Enable Elliptic Curve Keys and ciphers
|
|
Folks, This is Vipul Gupta's patch (Bugzilla 40132) against today's trunk. This compiles and works under some manual testing. Looks like OpenSSL 1.0 and Safari know about ECC, but Firefox doesn't. I have not been successful in getting the perl-framework to exercise this. Opinions? S. Index: docs/conf/extra/httpd-ssl.conf.in =================================================================== --- docs/conf/extra/httpd-ssl.conf.in (revision 833615) +++ docs/conf/extra/httpd-ssl.conf.in (working copy) @@ -81,6 +81,9 @@ # 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: @@ -90,16 +93,22 @@ # 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 Index: modules/ssl/ssl_private.h =================================================================== --- modules/ssl/ssl_private.h (revision 833615) +++ modules/ssl/ssl_private.h (working copy) @@ -172,11 +172,21 @@ #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 */ /** @@ -626,6 +636,9 @@ /** 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); Index: modules/ssl/ssl_engine_init.c =================================================================== --- modules/ssl/ssl_engine_init.c (revision 833615) +++ modules/ssl/ssl_engine_init.c (working copy) @@ -356,7 +356,11 @@ * 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 " @@ -519,6 +523,9 @@ 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); } @@ -810,9 +817,16 @@ 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; } @@ -922,20 +936,34 @@ 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(); } @@ -946,10 +974,21 @@ 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(); } } Index: modules/ssl/ssl_engine_kernel.c =================================================================== --- modules/ssl/ssl_engine_kernel.c (revision 833615) +++ modules/ssl/ssl_engine_kernel.c (working copy) @@ -1244,6 +1244,33 @@ 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. Index: modules/ssl/ssl_util.c =================================================================== --- modules/ssl/ssl_util.c (revision 833615) +++ modules/ssl/ssl_util.c (working copy) @@ -150,6 +150,11 @@ 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; } @@ -174,6 +179,11 @@ case SSL_ALGO_DSA: cp = "DSA"; break; +#ifndef OPENSSL_NO_EC + case SSL_ALGO_ECC: + cp = "ECC"; + break; +#endif default: break; } @@ -245,7 +255,11 @@ 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) { Index: modules/ssl/mod_ssl.c =================================================================== --- modules/ssl/mod_ssl.c (revision 833615) +++ modules/ssl/mod_ssl.c (working copy) @@ -440,6 +440,9 @@ */ 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); Index: modules/ssl/ssl_toolkit_compat.h =================================================================== --- modules/ssl/ssl_toolkit_compat.h (revision 833615) +++ modules/ssl/ssl_toolkit_compat.h (working copy) @@ -48,6 +48,11 @@ #include <openssl/ocsp.h> #endif +/* 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 */ -- Sander Temme sctemme [at] apache PGP FP: 51B4 8727 466A 0BC3 69F4 B7B8 B2BE BC40 1529 24AF
|