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]

Reply via email to