summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>1999-05-09 20:12:44 +0000
committerBodo Möller <bodo@openssl.org>1999-05-09 20:12:44 +0000
commitca8e5b9b8ad3c199943ad7850bf66bc03279c0b9 (patch)
tree6826d0a788880b08e6774c31d8c0629ee855e53c
parent8d1157c71c477be91bbf276ff0b0e6b1d4c139c5 (diff)
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. Submitted by: Reviewed by: PR:
-rw-r--r--CHANGES22
-rw-r--r--ssl/s3_lib.c13
-rw-r--r--ssl/s3_srvr.c29
-rw-r--r--ssl/ssl.h5
-rw-r--r--ssl/ssl_cert.c201
-rw-r--r--ssl/ssl_err.c5
-rw-r--r--ssl/ssl_lib.c63
-rw-r--r--ssl/ssl_locl.h13
-rw-r--r--ssl/ssl_rsa.c18
9 files changed, 299 insertions, 70 deletions
diff --git a/CHANGES b/CHANGES
index 61553dba43..6ddc9cca3a 100644
--- 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
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index c41e2548bd..2fa3c4c0f8 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -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;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index ccf81b8881..bdd1d912b9 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -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;
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 9964b666aa..a48d597d24 100644
--- 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
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index be4efac384..0d1c570113 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -55,6 +55,54 @@
* 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)
{
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index eae7ad7db1..c96fb6cbcf 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -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"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 5ed626fa93..cbc89b888d 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -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;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 4f3d56f0d3..f1bfcf9519 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -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);
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index ba0c7f5117..fcd4248529 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -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