diff options
-rw-r--r-- | CHANGES | 22 | ||||
-rw-r--r-- | ssl/s3_lib.c | 13 | ||||
-rw-r--r-- | ssl/s3_srvr.c | 29 | ||||
-rw-r--r-- | ssl/ssl.h | 5 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 201 | ||||
-rw-r--r-- | ssl/ssl_err.c | 5 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 63 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 13 | ||||
-rw-r--r-- | ssl/ssl_rsa.c | 18 |
9 files changed, 299 insertions, 70 deletions
@@ -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; @@ -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 |