For a long time I've wondered myself why my Apache+mod_ssl development version
still said "no shared ciphers" under DSA/DH situation while our OpenSSL
s_server worked fine with the same DSA certificate/key files. After tracing
down the problem I discovered that the ssl3_choose_cipher() function failed
because the ssl_set_cert_masks() function thought that no temp RSA key and/or
DH temp params (or corresponding callback functions) are configured. This
leads to incorrect decision later.
The reason was just, _WHY_ to the hell were those stuff lost, although both
mod_ssl and s_server initializes it inside the SSL_CTX. I've now found the
reason and difference between s_server and mod_ssl: s_server sets the temp
stuff inside SSL_CTX _AND_ reads the cert/key into the same SSL_CTX while
mod_ssl has to set the temp stuff inside the SSL_CTX but read the cert/key
into the SSL (derived from the SSL_CTX). The problem is that when you read a
cert via SSL_CTX_use_certificate(ctx) the SSL_CTX->cert correctly keeps the
previously configured temp key/param stuff. And when you do a SSL_new the
SSL->cert stuff is still ok. But when you use SSL_use_certificate() the
SSL->cert is _REPLACED_ by a fresh one without copying the temp stuff. So,
it's lost.
In short, this (the s_server approach) works:
ctx = SSL_CTX_new();
SSL_CTX_set_tmp_rsa_callback(ctx, ...);
SSL_CTX_use_certificate(ctx, ...);
ssl = SSL_new();
/* now ssl->cert contains the callbacks for the RSA temp key */
while this (the mod_ssl approach) fails:
ctx = SSL_CTX_new();
SSL_CTX_set_tmp_rsa_callback(ctx, ...);
ssl = SSL_new();
SSL_use_certificate(ctx, ...);
/* now ssl->cert is a fresh one without the callbacks */
IMHO this inconsistency is a bug. The SSL_use_certificate() and related
functions should keep the temp stuff from the context. A patch is appended.
With this I'm now able to connect correctly with for instance the
EDH-DSS-DES-CBC3-SHA (168/168 bits) cipher to an Apache+mod_ssl.
Opinions and votes?
Ralf S. Engelschall
[EMAIL PROTECTED]
www.engelschall.com
Index: ssl_cert.c
===================================================================
RCS file: /e/openssl/cvs/openssl/ssl/ssl_cert.c,v
retrieving revision 1.3
diff -u -r1.3 ssl_cert.c
--- ssl_cert.c 1999/01/07 19:15:58 1.3
+++ ssl_cert.c 1999/02/23 13:42:50
@@ -144,6 +144,23 @@
Free(c);
}
+int ssl_copy_cert_tmp(CERT *to, CERT *from)
+ {
+ if (to == NULL || from == NULL)
+ return 0;
+ if (from->rsa_tmp)
+ to->rsa_tmp = RSAPrivateKey_dup(from->rsa_tmp);
+ if (from->dh_tmp)
+ {
+ to->dh_tmp = DHparams_dup(from->dh_tmp);
+ if (to->dh_tmp != NULL)
+ DH_generate_key(to->dh_tmp);
+ }
+ to->rsa_tmp_cb = from->rsa_tmp_cb;
+ to->dh_tmp_cb = from->dh_tmp_cb;
+ return 1;
+ }
+
int ssl_set_cert_type(c, type)
CERT *c;
int type;
Index: ssl_locl.h
===================================================================
RCS file: /e/openssl/cvs/openssl/ssl/ssl_locl.h,v
retrieving revision 1.7
diff -u -r1.7 ssl_locl.h
--- ssl_locl.h 1999/02/21 21:58:59 1.7
+++ ssl_locl.h 1999/02/23 13:43:09
@@ -349,6 +349,7 @@
int ssl_clear_bad_session(SSL *s);
CERT *ssl_cert_new(void);
void ssl_cert_free(CERT *c);
+int ssl_copy_cert_tmp(CERT *to, CERT *from);
int ssl_set_cert_type(CERT *c, int type);
int ssl_get_new_session(SSL *s, int session);
int ssl_get_prev_session(SSL *s, unsigned char *session,int len);
@@ -484,6 +485,7 @@
int ssl_clear_bad_session();
CERT *ssl_cert_new();
void ssl_cert_free();
+int ssl_copy_cert_tmp();
int ssl_set_cert_type();
int ssl_get_new_session();
int ssl_get_prev_session();
Index: ssl_rsa.c
===================================================================
RCS file: /e/openssl/cvs/openssl/ssl/ssl_rsa.c,v
retrieving revision 1.3
diff -u -r1.3 ssl_rsa.c
--- ssl_rsa.c 1999/02/16 09:22:21 1.3
+++ ssl_rsa.c 1999/02/23 13:46:01
@@ -93,6 +93,7 @@
}
if (ssl->cert != NULL) ssl_cert_free(ssl->cert);
ssl->cert=c;
+ ssl_copy_cert_tmp(ssl->cert, ssl->ctx->default_cert);
}
c=ssl->cert;
@@ -197,6 +198,7 @@
}
if (ssl->cert != NULL) ssl_cert_free(ssl->cert);
ssl->cert=c;
+ ssl_copy_cert_tmp(ssl->cert, ssl->ctx->default_cert);
}
c=ssl->cert;
if ((pkey=EVP_PKEY_new()) == NULL)
@@ -385,6 +387,7 @@
}
if (ssl->cert != NULL) ssl_cert_free(ssl->cert);
ssl->cert=c;
+ ssl_copy_cert_tmp(ssl->cert, ssl->ctx->default_cert);
}
c=ssl->cert;
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]