Create a duplicate of the SSL_CTX's CERT in SSL_new instead of copying
authorBodo Möller <bodo@openssl.org>
Sun, 9 May 1999 20:12:44 +0000 (20:12 +0000)
committerBodo Möller <bodo@openssl.org>
Sun, 9 May 1999 20:12:44 +0000 (20:12 +0000)
pointers.  The cert_st handling is changed by this in various ways.
Submitted by:
Reviewed by:
PR:

CHANGES
ssl/s3_lib.c
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_err.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/ssl_rsa.c

diff --git a/CHANGES b/CHANGES
index 61553dba43095e1e0fc36c552a182f227c5feef3..6ddc9cca3a677d85a9dfc73b349cccf644bad467 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,28 @@
 
  Changes between 0.9.2b and 0.9.3
 
+  *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
+     copying pointers.  The cert_st handling is changed by this in
+     various ways (and thus what used to be known as ctx->default_cert
+     is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
+     any longer when s->cert does not give us what we need).
+     ssl_cert_instantiate becomes obsolete by this change.
+     As soon as we've got the new code right (possibly it already is?),
+     we have solved a couple of bugs of the earlier code where s->cert
+     was used as if it could not have been shared with other SSL structures.
+
+     Note that using the SSL API in certain dirty ways now will result
+     in different behaviour than observed with earlier library versions:
+     Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
+     does not influence s as it used to.
+     
+     Projected further changes:
+     In order to clean up things more thoroughly, inside SSL_SESSION
+     we should not use CERT any longer, but a new structure SESS_CERT
+     that holds per-session data, and CERT should hold only those
+     values that can have meaningful defaults in an SSL_CTX.
+     [Bodo Moeller]
+
   *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
      from the internal representation. Various PKCS#7 fixes: remove some
      evil casts and set the enc_dig_alg field properly based on the signing
index c41e2548bdbd89ead141e7da579db38e8ba4d42b..2fa3c4c0f8d944bb97a338d1426ca05f02737501 100644 (file)
@@ -584,7 +584,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, char *parg)
 #endif
                0)
                {
-               if (!ssl_cert_instantiate(&s->cert, s->ctx->default_cert)) 
+               if (!ssl_cert_inst(&s->cert))
                        {
                        SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
                        return(0);
@@ -677,7 +677,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
        {
        CERT *cert;
 
-       cert=ctx->default_cert;
+       cert=ctx->cert;
 
        switch (cmd)
                {
@@ -841,11 +841,8 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *have,
        CERT *cert;
        unsigned long alg,mask,emask;
 
-       /* Lets see which ciphers we can supported */
-       if (s->cert != NULL)
-               cert=s->cert;
-       else
-               cert=s->ctx->default_cert;
+       /* Let's see which ciphers we can support */
+       cert=s->cert;
 
        sk_SSL_CIPHER_set_cmp_func(pref,ssl_cipher_ptr_id_cmp);
 
@@ -862,7 +859,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *have,
                {
                c=sk_SSL_CIPHER_value(have,i);
 
-               ssl_set_cert_masks(cert,s->ctx->default_cert,c);
+               ssl_set_cert_masks(cert,c);
                mask=cert->mask;
                emask=cert->export_mask;
                        
index ccf81b8881f385237ae05d6620be08b70035407d..bdd1d912b95edf7f72013e75350f23d809f038b5 100644 (file)
@@ -268,11 +268,6 @@ int ssl3_accept(SSL *s)
                                        CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
                                        s->session->cert=s->cert;
                                        }
-                               else
-                                       {
-                                       CRYPTO_add(&s->ctx->default_cert->references,1,CRYPTO_LOCK_SSL_CERT);
-                                       s->session->cert=s->ctx->default_cert;
-                                       }
                                }
                        ct=s->session->cert;
 
@@ -913,9 +908,9 @@ static int ssl3_send_server_key_exchange(SSL *s)
                if (type & SSL_kRSA)
                        {
                        rsa=cert->rsa_tmp;
-                       if ((rsa == NULL) && (s->ctx->default_cert->rsa_tmp_cb != NULL))
+                       if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
                                {
-                               rsa=s->ctx->default_cert->rsa_tmp_cb(s,
+                               rsa=s->cert->rsa_tmp_cb(s,
                                      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
                                      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
                                CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA);
@@ -937,8 +932,8 @@ static int ssl3_send_server_key_exchange(SSL *s)
                        if (type & SSL_kEDH)
                        {
                        dhp=cert->dh_tmp;
-                       if ((dhp == NULL) && (cert->dh_tmp_cb != NULL))
-                               dhp=cert->dh_tmp_cb(s,
+                       if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
+                               dhp=s->cert->dh_tmp_cb(s,
                                      !SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
                                      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
                        if (dhp == NULL)
@@ -1215,9 +1210,9 @@ static int ssl3_get_client_key_exchange(SSL *s)
                        if ((s->session->cert != NULL) &&
                                (s->session->cert->rsa_tmp != NULL))
                                rsa=s->session->cert->rsa_tmp;
-                       else if ((s->ctx->default_cert != NULL) &&
-                               (s->ctx->default_cert->rsa_tmp != NULL))
-                               rsa=s->ctx->default_cert->rsa_tmp;
+                       else if ((s->cert != NULL) &&
+                               (s->cert->rsa_tmp != NULL))
+                               rsa=s->cert->rsa_tmp;
                        /* Don't do a callback because rsa_tmp should
                         * be sent already */
                        if (rsa == NULL)
@@ -1653,16 +1648,6 @@ static int ssl3_get_client_certificate(SSL *s)
                X509_free(s->session->peer);
        s->session->peer=sk_X509_shift(sk);
 
-       /* FIXME: s->session->cert could be a SSL_CTX's struct cert_st!
-        * struct cert_st is used for too many purposes.  It makes
-        * sense to use the same structure in both SSL_CTX and SSL,
-        * but then don't put any per-connection data in it. */
-#if 0 /* This could become a workaround, but it would still be utterly ugly */
-       if (!ssl_cert_instantiate(&s->cert, s->ctx->default_cert)) 
-               {
-               handle the error;
-               }
-#endif
        s->session->cert->cert_chain=sk;
 
        sk=NULL;
index 9964b666aaa327558d0ca00b0d0703b949d99adc..a48d597d2439d0c9d149053f58bb090d9fe1007b 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -392,7 +392,7 @@ struct ssl_ctx_st
 /**/   char *app_verify_arg;
 
        /* default values to use in SSL structures */
-/**/   struct cert_st /* CERT */ *default_cert;
+/**/   struct cert_st /* CERT */ *cert;
 /**/   int read_ahead;
 /**/   int verify_mode;
 /**/   int verify_depth;
@@ -1159,6 +1159,8 @@ int SSL_COMP_add_compression_method(int id,char *cm);
 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK       216
 #define SSL_F_SSL_BAD_METHOD                            160
 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST                  161
+#define SSL_F_SSL_CERT_DUP                              221
+#define SSL_F_SSL_CERT_INST                             222
 #define SSL_F_SSL_CERT_INSTANTIATE                      214
 #define SSL_F_SSL_CERT_NEW                              162
 #define SSL_F_SSL_CHECK_PRIVATE_KEY                     163
@@ -1279,6 +1281,7 @@ int SSL_COMP_add_compression_method(int id,char *cm);
 #define SSL_R_INVALID_CHALLENGE_LENGTH                  158
 #define SSL_R_LENGTH_MISMATCH                           159
 #define SSL_R_LENGTH_TOO_SHORT                          160
+#define SSL_R_LIBRARY_BUG                               274
 #define SSL_R_LIBRARY_HAS_NO_CIPHERS                    161
 #define SSL_R_MISSING_DH_DSA_CERT                       162
 #define SSL_R_MISSING_DH_KEY                            163
index be4efac384d653c5297821ba976f9b2f65262fb8..0d1c57011311a7c45111b2fff59ff09073145443 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -104,6 +152,132 @@ CERT *ssl_cert_new(void)
        return(ret);
        }
 
+CERT *ssl_cert_dup(CERT *cert)
+       {
+       CERT *ret;
+       int i;
+
+       ret = (CERT *)Malloc(sizeof(CERT));
+       if (ret == NULL)
+               {
+               SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+               return(NULL);
+               }
+
+       memset(ret, 0, sizeof(CERT));
+
+       ret->cert_type = cert->cert_type;
+
+       ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
+       /* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
+        * if you find that more readable */
+
+       ret->valid = cert->valid;
+       ret->mask = cert->mask;
+       ret->export_mask = cert->export_mask;
+
+#ifndef NO_RSA
+       if (cert->rsa_tmp != NULL)
+               {
+               ret->rsa_tmp = cert->rsa_tmp;
+               CRYPTO_add(&ret->rsa_tmp->references, 1, CRYPTO_LOCK_RSA);
+               }
+       ret->rsa_tmp_cb = cert->rsa_tmp_cb;
+#endif
+
+#ifndef NO_DH
+       if (cert->dh_tmp != NULL)
+               {
+               /* DH parameters don't have a reference count (and cannot
+                * reasonably be shared anyway, as the secret exponent may
+                * be created just when it is needed -- earlier library
+                * versions did not pay attention to this) */
+               ret->dh_tmp = DHparams_dup(cert->dh_tmp);
+               if (ret->dh_tmp == NULL)
+                       {
+                       SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_DH_LIB);
+                       goto err;
+                       }
+               }
+       ret->dh_tmp_cb = cert->dh_tmp_cb;
+#endif
+
+       for (i = 0; i < SSL_PKEY_NUM; i++)
+               {
+               if (cert->pkeys[i].x509 != NULL)
+                       {
+                       ret->pkeys[i].x509 = cert->pkeys[i].x509;
+                       CRYPTO_add(&ret->pkeys[i].x509->references, 1,
+                               CRYPTO_LOCK_X509);
+                       }
+               
+               if (cert->pkeys[i].privatekey != NULL)
+                       {
+                       ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
+                       CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
+                               CRYPTO_LOCK_EVP_PKEY);
+
+                       switch(i) 
+                               {
+                               /* If there was anything special to do for
+                                * certain types of keys, we'd do it here.
+                                * (Nothing at the moment, I think.) */
+
+                       case SSL_PKEY_RSA_ENC:
+                       case SSL_PKEY_RSA_SIGN:
+                               /* We have an RSA key. */
+                               break;
+                               
+                       case SSL_PKEY_DSA_SIGN:
+                               /* We have a DSA key. */
+                               break;
+                               
+                       case SSL_PKEY_DH_RSA:
+                       case SSL_PKEY_DH_DSA:
+                               /* We have a DH key. */
+                               break;
+                               
+                       default:
+                               /* Can't happen. */
+                               SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
+                               }
+                       }
+               }
+       
+
+       /* ret->cert_chain should not exist: that's pure per-connection data.
+        * Anyway, we never use this function when it is non-NULL,
+        * so we just don't look at it. */
+
+       /* ret->extra_certs *should* exist, but currently the own certificate
+        * chain is held inside SSL_CTX */
+
+       ret->references=1;
+
+       return(ret);
+       
+err:
+#ifndef NO_RSA
+       if (ret->rsa_tmp != NULL)
+               RSA_free(ret->rsa_tmp);
+#endif
+#ifndef NO_DH
+       if (ret->dh_tmp != NULL)
+               DH_free(ret->dh_tmp);
+#endif
+
+       for (i = 0; i < SSL_PKEY_NUM; i++)
+               {
+               if (ret->pkeys[i].x509 != NULL)
+                       X509_free(ret->pkeys[i].x509);
+               if (ret->pkeys[i].privatekey != NULL)
+                       EVP_PKEY_free(ret->pkeys[i].privatekey);
+               }
+
+       return NULL;
+       }
+
+
 void ssl_cert_free(CERT *c)
        {
        int i;
@@ -147,6 +321,32 @@ void ssl_cert_free(CERT *c)
        Free(c);
        }
 
+#if 1
+int ssl_cert_inst(CERT **o)
+       {
+       /* Create a CERT if there isn't already one
+        * (which cannot really happen, as it is initially created in
+        * SSL_CTX_new; but the earlier code usually allows for that one
+        * being non-existant, so we follow that behaviour, as it might
+        * turn out that there actually is a reason for it.). */
+        
+       if (o == NULL) 
+               {
+               SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
+               return(0);
+               }
+       if (*o == NULL)
+               {
+               if ((*o = ssl_cert_new()) == NULL)
+                       {
+                       SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
+                       return(0);
+                       }
+               }
+       return(1);
+       }
+
+#else /* Not needed any longer: SSL's always have their own copy */
 int ssl_cert_instantiate(CERT **o, CERT *d)
        {
        CERT *n;
@@ -167,6 +367,7 @@ int ssl_cert_instantiate(CERT **o, CERT *d)
        *o = n;
        return(1);
        }
+#endif
 
 int ssl_set_cert_type(CERT *c,int type)
        {
index eae7ad7db1e3ac42a3bcde341a2f12baeb8238a0..c96fb6cbcfdeef7ee1f9dc2b1d7872a4eb54d212 100644 (file)
@@ -130,6 +130,8 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_PACK(0,SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,0),      "SSL_add_file_cert_subjects_to_stack"},
 {ERR_PACK(0,SSL_F_SSL_BAD_METHOD,0),   "SSL_BAD_METHOD"},
 {ERR_PACK(0,SSL_F_SSL_BYTES_TO_CIPHER_LIST,0), "SSL_BYTES_TO_CIPHER_LIST"},
+{ERR_PACK(0,SSL_F_SSL_CERT_DUP,0),     "SSL_CERT_DUP"},
+{ERR_PACK(0,SSL_F_SSL_CERT_INST,0),    "SSL_CERT_INST"},
 {ERR_PACK(0,SSL_F_SSL_CERT_INSTANTIATE,0),     "SSL_CERT_INSTANTIATE"},
 {ERR_PACK(0,SSL_F_SSL_CERT_NEW,0),     "SSL_CERT_NEW"},
 {ERR_PACK(0,SSL_F_SSL_CHECK_PRIVATE_KEY,0),    "SSL_check_private_key"},
@@ -142,7 +144,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_PACK(0,SSL_F_SSL_CTX_SET_SSL_VERSION,0),  "SSL_CTX_set_ssl_version"},
 {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE,0),  "SSL_CTX_use_certificate"},
 {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,0),     "SSL_CTX_use_certificate_ASN1"},
-{ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,0),       "SSL_CTX_USE_CERTIFICATE_CHAIN_FILE"},
+{ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,0),       "SSL_CTX_use_certificate_chain_file"},
 {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,0),     "SSL_CTX_use_certificate_file"},
 {ERR_PACK(0,SSL_F_SSL_CTX_USE_PRIVATEKEY,0),   "SSL_CTX_use_PrivateKey"},
 {ERR_PACK(0,SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1,0),      "SSL_CTX_use_PrivateKey_ASN1"},
@@ -253,6 +255,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {SSL_R_INVALID_CHALLENGE_LENGTH          ,"invalid challenge length"},
 {SSL_R_LENGTH_MISMATCH                   ,"length mismatch"},
 {SSL_R_LENGTH_TOO_SHORT                  ,"length too short"},
+{SSL_R_LIBRARY_BUG                       ,"library bug"},
 {SSL_R_LIBRARY_HAS_NO_CIPHERS            ,"library has no ciphers"},
 {SSL_R_MISSING_DH_DSA_CERT               ,"missing dh dsa cert"},
 {SSL_R_MISSING_DH_KEY                    ,"missing dh key"},
index 5ed626fa935752fc82668668174e60d6d86d9dbd..cbc89b888de0b16625338da41700d4560877fc70 100644 (file)
@@ -178,14 +178,24 @@ SSL *SSL_new(SSL_CTX *ctx)
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
-       if (ctx->default_cert != NULL)
-               {
-               CRYPTO_add(&ctx->default_cert->references,1,
-                          CRYPTO_LOCK_SSL_CERT);
-               s->cert=ctx->default_cert;
+       if (ctx->cert != NULL)
+               {
+               /* Earlier library versions used to copy the pointer to
+                * the CERT, not its contents; only when setting new
+                * parameters for the per-SSL copy, ssl_cert_new would be
+                * called (and the direct reference to the per-SSL_CTX
+                * settings would be lost, but those still were indirectly
+                * accessed for various purposes, and for that reason they
+                * used to be known as s->ctx->default_cert).
+                * Now we don't look at the SSL_CTX's CERT after having
+                * duplicated it once. */
+
+               s->cert = ssl_cert_dup(ctx->cert);
+               if (s->cert == NULL)
+                       goto err;
                }
        else
-               s->cert=NULL;
+               s->cert=NULL; /* Cannot really happen (see SSL_CTX_new) */
        s->sid_ctx_length=ctx->sid_ctx_length;
        memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
        s->verify_mode=ctx->verify_mode;
@@ -199,11 +209,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->method=ctx->method;
 
        if (!s->method->ssl_new(s))
-               {
-               SSL_CTX_free(ctx);
-               Free(s);
                goto err;
-               }
 
        s->quiet_shutdown=ctx->quiet_shutdown;
        s->references=1;
@@ -215,6 +221,14 @@ SSL *SSL_new(SSL_CTX *ctx)
 
        return(s);
 err:
+       if (s != NULL)
+               {
+               if (s->cert != NULL)
+                       ssl_cert_free(s->cert);
+               if (s->ctx != NULL)
+                       SSL_CTX_free(s->ctx); /* decrement reference count */
+               Free(s);
+               }
        SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
        return(NULL);
        }
@@ -538,18 +552,18 @@ void SSL_copy_session_id(SSL *t,SSL *f)
 int SSL_CTX_check_private_key(SSL_CTX *ctx)
        {
        if (    (ctx == NULL) ||
-               (ctx->default_cert == NULL) ||
-               (ctx->default_cert->key->x509 == NULL))
+               (ctx->cert == NULL) ||
+               (ctx->cert->key->x509 == NULL))
                {
                SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
                return(0);
                }
-       if      (ctx->default_cert->key->privatekey == NULL)
+       if      (ctx->cert->key->privatekey == NULL)
                {
                SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
                return(0);
                }
-       return(X509_check_private_key(ctx->default_cert->key->x509, ctx->default_cert->key->privatekey));
+       return(X509_check_private_key(ctx->cert->key->x509, ctx->cert->key->privatekey));
        }
 
 /* Fix this function so that it takes an optional type parameter */
@@ -977,7 +991,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->verify_mode=SSL_VERIFY_NONE;
        ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
        ret->default_verify_callback=NULL;
-       if ((ret->default_cert=ssl_cert_new()) == NULL)
+       if ((ret->cert=ssl_cert_new()) == NULL)
                goto err;
 
        ret->default_passwd_callback=NULL;
@@ -1064,8 +1078,8 @@ void SSL_CTX_free(SSL_CTX *a)
                sk_SSL_CIPHER_free(a->cipher_list);
        if (a->cipher_list_by_id != NULL)
                sk_SSL_CIPHER_free(a->cipher_list_by_id);
-       if (a->default_cert != NULL)
-               ssl_cert_free(a->default_cert);
+       if (a->cert != NULL)
+               ssl_cert_free(a->cert);
        if (a->client_CA != NULL)
                sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
        if (a->extra_certs != NULL)
@@ -1099,10 +1113,7 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
        ctx->verify_depth=depth;
        }
 
-/* Need default_cert to check for callbacks, for now (see comment in CERT
-   strucure)
-*/
-void ssl_set_cert_masks(CERT *c,CERT *default_cert,SSL_CIPHER *cipher)
+void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
        {
        CERT_PKEY *cpk;
        int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
@@ -1115,15 +1126,15 @@ void ssl_set_cert_masks(CERT *c,CERT *default_cert,SSL_CIPHER *cipher)
        kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
 
 #ifndef NO_RSA
-       rsa_tmp=(c->rsa_tmp != NULL || default_cert->rsa_tmp_cb != NULL);
-       rsa_tmp_export=(default_cert->rsa_tmp_cb != NULL ||
+       rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
+       rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
                (rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
 #else
        rsa_tmp=rsa_tmp_export=0;
 #endif
 #ifndef NO_DH
-       dh_tmp=(c->dh_tmp != NULL || default_cert->dh_tmp_cb != NULL);
-       dh_tmp_export=(default_cert->dh_tmp_cb != NULL ||
+       dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
+       dh_tmp_export=(c->dh_tmp_cb != NULL ||
                (dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
 #else
        dh_tmp=dh_tmp_export=0;
@@ -1210,7 +1221,7 @@ X509 *ssl_get_server_send_cert(SSL *s)
        int i,export;
 
        c=s->cert;
-       ssl_set_cert_masks(c,s->ctx->default_cert,s->s3->tmp.new_cipher);
+       ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
        alg=s->s3->tmp.new_cipher->algorithms;
        export=SSL_IS_EXPORT(alg);
        mask=export?c->export_mask:c->mask;
index 4f3d56f0d3d68e598e37804b0febb9435f696a8c..f1bfcf95190355c37f1510c7470fe75f53543485 100644 (file)
@@ -255,7 +255,9 @@ typedef struct cert_st
        int cert_type;
 
        /* Current active set */
-       CERT_PKEY *key;
+       CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
+                                        * Probably it would make more sense to store
+                                        * an index, not a pointer. */
 
        /* The following masks are for the key and auth
         * algorithms that are supported by the certs below */
@@ -275,7 +277,7 @@ typedef struct cert_st
 
        STACK_OF(X509) *cert_chain; /* XXX should only exist in sess_cert_st */
 
-       int references; /* XXX should only exist in sess_cert_st */
+       int references; /* XXX will finally always be 1 */
        } CERT;
 
 
@@ -345,7 +347,12 @@ SSL_METHOD *sslv3_base_method(void);
 void ssl_clear_cipher_ctx(SSL *s);
 int ssl_clear_bad_session(SSL *s);
 CERT *ssl_cert_new(void);
+CERT *ssl_cert_dup(CERT *cert);
+#if 1
+int ssl_cert_inst(CERT **o);
+#else
 int ssl_cert_instantiate(CERT **o, CERT *d);
+#endif
 void ssl_cert_free(CERT *c);
 int ssl_set_cert_type(CERT *c, int type);
 int ssl_get_new_session(SSL *s, int session);
@@ -367,7 +374,7 @@ int ssl_undefined_function(SSL *s);
 X509 *ssl_get_server_send_cert(SSL *);
 EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *);
 int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
-void ssl_set_cert_masks(CERT *c,CERT *default_cert,SSL_CIPHER *cipher);
+void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher);
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 int ssl_verify_alarm_type(long type);
 
index ba0c7f5117de6f7812d67d4af1fb0f512c3d85c4..fcd4248529aa990ad26e944c3d4a8a60bf0e4cee 100644 (file)
@@ -73,7 +73,7 @@ int SSL_use_certificate(SSL *ssl, X509 *x)
                SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ssl->cert, ssl->ctx->default_cert)) 
+       if (!ssl_cert_inst(&ssl->cert))
                {
                SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
                return(0);
@@ -159,7 +159,7 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
                SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ssl->cert, ssl->ctx->default_cert)) 
+       if (!ssl_cert_inst(&ssl->cert))
                {
                SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
                return(0);
@@ -328,7 +328,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
                SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ssl->cert, ssl->ctx->default_cert)) 
+       if (!ssl_cert_inst(&ssl->cert))
                {
                SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
                return(0);
@@ -405,12 +405,12 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
                SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ctx->default_cert, NULL))
+       if (!ssl_cert_inst(&ctx->cert))
                {
                SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
                return(0);
                }
-       return(ssl_set_cert(ctx->default_cert,x));
+       return(ssl_set_cert(ctx->cert, x));
        }
 
 static int ssl_set_cert(CERT *c, X509 *x)
@@ -571,7 +571,7 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
                SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ctx->default_cert, NULL))
+       if (!ssl_cert_inst(&ctx->cert))
                {
                SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
                return(0);
@@ -585,7 +585,7 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
        CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA);
        EVP_PKEY_assign_RSA(pkey,rsa);
 
-       ret=ssl_set_pkey(ctx->default_cert,pkey);
+       ret=ssl_set_pkey(ctx->cert, pkey);
        EVP_PKEY_free(pkey);
        return(ret);
        }
@@ -664,12 +664,12 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if (!ssl_cert_instantiate(&ctx->default_cert, NULL))
+       if (!ssl_cert_inst(&ctx->cert))
                {
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
                return(0);
                }
-       return(ssl_set_pkey(ctx->default_cert,pkey));
+       return(ssl_set_pkey(ctx->cert,pkey));
        }
 
 #ifndef NO_STDIO