mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
enable support for ECC keys and ECDH ciphers. Tested against
OpenSSL 1.0.0b3. [Vipul Gupta vipul.gupta sun.com, Sander Temme] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@834378 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -9,6 +9,9 @@ Changes with Apache 2.3.3
|
|||||||
*) SECURITY: CVE-2009-3094 (cve.mitre.org)
|
*) SECURITY: CVE-2009-3094 (cve.mitre.org)
|
||||||
mod_proxy_ftp: NULL pointer dereference on error paths.
|
mod_proxy_ftp: NULL pointer dereference on error paths.
|
||||||
[Stefan Fritsch <sf fritsch.de>, Joe Orton]
|
[Stefan Fritsch <sf fritsch.de>, Joe Orton]
|
||||||
|
|
||||||
|
*) mod_ssl: enable support for ECC keys and ECDH ciphers. Tested against
|
||||||
|
OpenSSL 1.0.0b3. [Vipul Gupta vipul.gupta sun.com, Sander Temme]
|
||||||
|
|
||||||
*) mod_dav_fs: Include uri when logging a PUT error due to connection abort.
|
*) mod_dav_fs: Include uri when logging a PUT error due to connection abort.
|
||||||
PR 38149. [Stefan Fritsch]
|
PR 38149. [Stefan Fritsch]
|
||||||
|
@@ -81,6 +81,9 @@ SSLEngine on
|
|||||||
# SSL Cipher Suite:
|
# SSL Cipher Suite:
|
||||||
# List the ciphers that the client is permitted to negotiate.
|
# List the ciphers that the client is permitted to negotiate.
|
||||||
# See the mod_ssl documentation for a complete list.
|
# 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
|
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
|
||||||
|
|
||||||
# Server Certificate:
|
# Server Certificate:
|
||||||
@@ -90,16 +93,22 @@ SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
|
|||||||
# in mind that if you have both an RSA and a DSA certificate you
|
# 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
|
# can configure both in parallel (to also allow the use of DSA
|
||||||
# ciphers, etc.)
|
# 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.crt"
|
||||||
#SSLCertificateFile "@exp_sysconfdir@/server-dsa.crt"
|
#SSLCertificateFile "@exp_sysconfdir@/server-dsa.crt"
|
||||||
|
#SSLCertificateFile "@exp_sysconfdir@/server-ecc.crt"
|
||||||
|
|
||||||
# Server Private Key:
|
# Server Private Key:
|
||||||
# If the key is not combined with the certificate, use this
|
# If the key is not combined with the certificate, use this
|
||||||
# directive to point at the key file. Keep in mind that if
|
# 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
|
# 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.)
|
# 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.key"
|
||||||
#SSLCertificateKeyFile "@exp_sysconfdir@/server-dsa.key"
|
#SSLCertificateKeyFile "@exp_sysconfdir@/server-dsa.key"
|
||||||
|
#SSLCertificateKeyFile "@exp_sysconfdir@/server-ecc.key"
|
||||||
|
|
||||||
# Server Certificate Chain:
|
# Server Certificate Chain:
|
||||||
# Point SSLCertificateChainFile at a file containing the
|
# Point SSLCertificateChainFile at a file containing the
|
||||||
|
@@ -440,6 +440,9 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
|
|||||||
*/
|
*/
|
||||||
SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
|
SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
|
||||||
SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH);
|
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_set_verify_result(ssl, X509_V_OK);
|
||||||
|
|
||||||
|
@@ -356,7 +356,11 @@ static void ssl_init_server_check(server_rec *s,
|
|||||||
* Check for problematic re-initializations
|
* Check for problematic re-initializations
|
||||||
*/
|
*/
|
||||||
if (mctx->pks->certs[SSL_AIDX_RSA] ||
|
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,
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
||||||
"Illegal attempt to re-initialise SSL for server "
|
"Illegal attempt to re-initialise SSL for server "
|
||||||
@@ -519,6 +523,9 @@ static void ssl_init_ctx_callbacks(server_rec *s,
|
|||||||
|
|
||||||
SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
|
SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
|
||||||
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
|
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);
|
SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
|
||||||
}
|
}
|
||||||
@@ -810,9 +817,16 @@ static int ssl_server_import_key(server_rec *s,
|
|||||||
ssl_asn1_t *asn1;
|
ssl_asn1_t *asn1;
|
||||||
MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
|
MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
|
||||||
const char *type = ssl_asn1_keystr(idx);
|
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;
|
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))) {
|
if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -922,20 +936,34 @@ static void ssl_init_server_certs(server_rec *s,
|
|||||||
apr_pool_t *ptemp,
|
apr_pool_t *ptemp,
|
||||||
modssl_ctx_t *mctx)
|
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;
|
const char *vhost_id = mctx->sc->vhost_id;
|
||||||
int i;
|
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);
|
rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
|
||||||
dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
|
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_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);
|
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,
|
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 "
|
"Oops, no RSA or DSA server certificate found "
|
||||||
|
#endif
|
||||||
"for '%s:%d'?!", s->server_hostname, s->port);
|
"for '%s:%d'?!", s->server_hostname, s->port);
|
||||||
ssl_die();
|
ssl_die();
|
||||||
}
|
}
|
||||||
@@ -946,10 +974,21 @@ static void ssl_init_server_certs(server_rec *s,
|
|||||||
|
|
||||||
have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
|
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);
|
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,
|
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?!");
|
"Oops, no RSA or DSA server private key found?!");
|
||||||
|
#endif
|
||||||
ssl_die();
|
ssl_die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1244,6 +1244,33 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
|
|||||||
return (DH *)mc->pTmpKeys[idx];
|
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
|
* This OpenSSL callback function is called when OpenSSL
|
||||||
* does client authentication and verifies the certificate chain.
|
* does client authentication and verifies the certificate chain.
|
||||||
|
@@ -172,11 +172,21 @@ typedef int ssl_algo_t;
|
|||||||
#define SSL_ALGO_UNKNOWN (0)
|
#define SSL_ALGO_UNKNOWN (0)
|
||||||
#define SSL_ALGO_RSA (1<<0)
|
#define SSL_ALGO_RSA (1<<0)
|
||||||
#define SSL_ALGO_DSA (1<<1)
|
#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)
|
#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA)
|
||||||
|
#endif /* SSL_LIBRARY_VERSION */
|
||||||
|
|
||||||
#define SSL_AIDX_RSA (0)
|
#define SSL_AIDX_RSA (0)
|
||||||
#define SSL_AIDX_DSA (1)
|
#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)
|
#define SSL_AIDX_MAX (2)
|
||||||
|
#endif /* SSL_LIBRARY_VERSION */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -626,6 +636,9 @@ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
|
|||||||
/** OpenSSL callbacks */
|
/** OpenSSL callbacks */
|
||||||
RSA *ssl_callback_TmpRSA(SSL *, int, int);
|
RSA *ssl_callback_TmpRSA(SSL *, int, int);
|
||||||
DH *ssl_callback_TmpDH(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(int, X509_STORE_CTX *);
|
||||||
int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *);
|
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_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey);
|
||||||
|
@@ -48,6 +48,11 @@
|
|||||||
#include <openssl/ocsp.h>
|
#include <openssl/ocsp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ECC support came along in OpenSSL 1.0.0 */
|
||||||
|
#if (OPENSSL_VERSION_NUMBER < 0x10000000)
|
||||||
|
#define OPENSSL_NO_EC
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Avoid tripping over an engine build installed globally and detected
|
/** Avoid tripping over an engine build installed globally and detected
|
||||||
* when the user points at an explicit non-engine flavor of OpenSSL
|
* when the user points at an explicit non-engine flavor of OpenSSL
|
||||||
*/
|
*/
|
||||||
|
@@ -150,6 +150,11 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
|
|||||||
case EVP_PKEY_DSA:
|
case EVP_PKEY_DSA:
|
||||||
t = SSL_ALGO_DSA;
|
t = SSL_ALGO_DSA;
|
||||||
break;
|
break;
|
||||||
|
#ifndef OPENSSL_NO_EC
|
||||||
|
case EVP_PKEY_EC:
|
||||||
|
t = SSL_ALGO_ECC;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -174,6 +179,11 @@ char *ssl_util_algotypestr(ssl_algo_t t)
|
|||||||
case SSL_ALGO_DSA:
|
case SSL_ALGO_DSA:
|
||||||
cp = "DSA";
|
cp = "DSA";
|
||||||
break;
|
break;
|
||||||
|
#ifndef OPENSSL_NO_EC
|
||||||
|
case SSL_ALGO_ECC:
|
||||||
|
cp = "ECC";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,7 +255,11 @@ void ssl_asn1_table_unset(apr_hash_t *table,
|
|||||||
apr_hash_set(table, key, klen, NULL);
|
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"};
|
static const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *ssl_asn1_keystr(int keytype)
|
const char *ssl_asn1_keystr(int keytype)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user