From de8f24ea083384bb66b32ec105dc4743c5663cdf Mon Sep 17 00:00:00 2001 From: beck <> Date: Wed, 29 Sep 1999 04:37:45 +0000 Subject: OpenSSL 0.9.4 merge --- src/lib/libssl/s3_srvr.c | 336 ++++++++++++++++++++++++----------------------- 1 file changed, 172 insertions(+), 164 deletions(-) (limited to 'src/lib/libssl/s3_srvr.c') diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c index 64903af151..e003d88357 100644 --- a/src/lib/libssl/s3_srvr.c +++ b/src/lib/libssl/s3_srvr.c @@ -59,22 +59,16 @@ #define REUSE_CIPHER_BUG #include -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" +#include +#include +#include +#include +#include +#include +#include #include "ssl_locl.h" -#define BREAK break -/* SSLerr(SSL_F_SSL3_ACCEPT,ERR_R_MALLOC_FAILURE); - * SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE); - * SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); - * SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_MALLOC_FAILURE); - * SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE); - */ - -#ifndef NOPROTO +static SSL_METHOD *ssl3_get_server_method(int ver); static int ssl3_get_client_hello(SSL *s); static int ssl3_send_server_hello(SSL *s); static int ssl3_send_server_key_exchange(SSL *s); @@ -85,22 +79,7 @@ static int ssl3_get_client_key_exchange(SSL *s); static int ssl3_get_client_certificate(SSL *s); static int ssl3_send_hello_request(SSL *s); -#else - -static int ssl3_get_client_hello(); -static int ssl3_send_server_hello(); -static int ssl3_send_server_key_exchange(); -static int ssl3_send_certificate_request(); -static int ssl3_send_server_done(); -static int ssl3_get_cert_verify(); -static int ssl3_get_client_key_exchange(); -static int ssl3_get_client_certificate(); -static int ssl3_send_hello_request(); - -#endif - -static SSL_METHOD *ssl3_get_server_method(ver) -int ver; +static SSL_METHOD *ssl3_get_server_method(int ver) { if (ver == SSL3_VERSION) return(SSLv3_server_method()); @@ -108,35 +87,32 @@ int ver; return(NULL); } -SSL_METHOD *SSLv3_server_method() +SSL_METHOD *SSLv3_server_method(void) { static int init=1; static SSL_METHOD SSLv3_server_data; if (init) { - init=0; memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(), sizeof(SSL_METHOD)); SSLv3_server_data.ssl_accept=ssl3_accept; SSLv3_server_data.get_ssl_method=ssl3_get_server_method; + init=0; } return(&SSLv3_server_data); } -int ssl3_accept(s) -SSL *s; +int ssl3_accept(SSL *s) { BUF_MEM *buf; unsigned long l,Time=time(NULL); void (*cb)()=NULL; long num1; int ret= -1; - CERT *ct; - BIO *under; int new_state,state,skip=0; - RAND_seed((unsigned char *)&Time,sizeof(Time)); + RAND_seed(&Time,sizeof(Time)); ERR_clear_error(); clear_sys_error(); @@ -149,17 +125,11 @@ SSL *s; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); s->in_handshake++; -#ifdef undef - /* FIX THIS EAY EAY EAY */ - /* we don't actually need a cert, we just need a cert or a DH_tmp */ - if (((s->session == NULL) || (s->session->cert == NULL)) && - (s->cert == NULL)) + if (s->cert == NULL) { SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET); - ret= -1; - goto end; + return(-1); } -#endif for (;;) { @@ -176,6 +146,7 @@ SSL *s; case SSL_ST_BEFORE|SSL_ST_ACCEPT: case SSL_ST_OK|SSL_ST_ACCEPT: + s->server=1; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); if ((s->version>>8) != 3) @@ -215,11 +186,11 @@ SSL *s; { s->state=SSL3_ST_SR_CLNT_HELLO_A; ssl3_init_finished_mac(s); - s->ctx->sess_accept++; + s->ctx->stats.sess_accept++; } else { - s->ctx->sess_accept_renegotiate++; + s->ctx->stats.sess_accept_renegotiate++; s->state=SSL3_ST_SW_HELLO_REQ_A; } break; @@ -238,15 +209,6 @@ SSL *s; break; case SSL3_ST_SW_HELLO_REQ_C: - /* remove buffering on output */ - under=BIO_pop(s->wbio); - if (under != NULL) - s->wbio=under; - else - abort(); /* ok */ - BIO_free(s->bbio); - s->bbio=NULL; - s->state=SSL_ST_OK; ret=1; goto end; @@ -292,20 +254,6 @@ SSL *s; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: l=s->s3->tmp.new_cipher->algorithms; - if (s->session->cert == NULL) - { - if (s->cert != NULL) - { - 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; /* clear this, it may get reset by * send_server_key_exchange */ @@ -316,16 +264,16 @@ SSL *s; /* only send if a DH key exchange, fortezza or * RSA but we have a sign only certificate */ - if ( s->s3->tmp.use_rsa_tmp || - (l & (SSL_DH|SSL_kFZA)) || - ((l & SSL_kRSA) && - ((ct->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)|| - ((l & SSL_EXPORT) && - (EVP_PKEY_size(ct->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > 512) - ) - ) + if (s->s3->tmp.use_rsa_tmp + || (l & (SSL_DH|SSL_kFZA)) + || ((l & SSL_kRSA) + && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL + || (SSL_IS_EXPORT(l) + && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_EXPORT_PKEYLENGTH(l) + ) + ) + ) ) - ) { ret=ssl3_send_server_key_exchange(s); if (ret <= 0) goto end; @@ -478,20 +426,14 @@ SSL *s; s->init_buf=NULL; /* remove buffering on output */ - under=BIO_pop(s->wbio); - if (under != NULL) - s->wbio=under; - else - abort(); /* ok */ - BIO_free(s->bbio); - s->bbio=NULL; + ssl_free_wbio_buffer(s); s->new_session=0; s->init_num=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); - s->ctx->sess_accept_good++; + s->ctx->stats.sess_accept_good++; /* s->server=1; */ s->handshake_func=ssl3_accept; ret=1; @@ -536,8 +478,7 @@ end: return(ret); } -static int ssl3_send_hello_request(s) -SSL *s; +static int ssl3_send_hello_request(SSL *s) { unsigned char *p; @@ -559,15 +500,15 @@ SSL *s; return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_get_client_hello(s) -SSL *s; +static int ssl3_get_client_hello(SSL *s) { int i,j,ok,al,ret= -1; long n; unsigned long id; - unsigned char *p,*d; + unsigned char *p,*d,*q; SSL_CIPHER *c; - STACK *ciphers=NULL; + SSL_COMP *comp=NULL; + STACK_OF(SSL_CIPHER) *ciphers=NULL; /* We do this so that we will respond with our native type. * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, @@ -593,6 +534,7 @@ SSL *s; /* The version number has already been checked in ssl3_get_message. * I a native TLSv1/SSLv3 method, the match must be correct except * perhaps for the first message */ +/* s->client_version=(((int)p[0])<<8)|(int)p[1]; */ p+=2; /* load the client random */ @@ -615,7 +557,9 @@ SSL *s; { /* previous session */ s->hit=1; } - else + else if (i == -1) + goto err; + else /* i == 0 */ { if (!ssl_get_new_session(s,1)) goto err; @@ -651,9 +595,16 @@ SSL *s; j=0; id=s->session->cipher->id; - for (i=0; iid == id) { j=1; @@ -662,11 +613,11 @@ SSL *s; } if (j == 0) { - if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_num(ciphers) == 1)) + if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) { /* Very bad for multi-threading.... */ - s->session->cipher= - (SSL_CIPHER *)sk_value(ciphers,0); + s->session->cipher=sk_SSL_CIPHER_value(ciphers, + 0); } else { @@ -681,8 +632,11 @@ SSL *s; /* compression */ i= *(p++); + q=p; for (j=0; j= i) @@ -693,6 +647,35 @@ SSL *s; goto f_err; } + /* Worst case, we will use the NULL compression, but if we have other + * options, we will now look for them. We have i-1 compression + * algorithms from the client, starting at q. */ + s->s3->tmp.new_compression=NULL; + if (s->ctx->comp_methods != NULL) + { /* See if we have a match */ + int m,nn,o,v,done=0; + + nn=sk_SSL_COMP_num(s->ctx->comp_methods); + for (m=0; mctx->comp_methods,m); + v=comp->id; + for (o=0; os3->tmp.new_compression=comp; + else + comp=NULL; + } + /* TLS does not mind if there is extra stuff */ if (s->version == SSL3_VERSION) { @@ -706,15 +689,14 @@ SSL *s; } } - /* do nothing with compression */ - /* Given s->session->ciphers and ssl_get_ciphers_by_id(s), we must * pick a cipher */ if (!s->hit) { + s->session->compress_meth=(comp == NULL)?0:comp->id; if (s->session->ciphers != NULL) - sk_free(s->session->ciphers); + sk_SSL_CIPHER_free(s->session->ciphers); s->session->ciphers=ciphers; if (ciphers == NULL) { @@ -724,7 +706,7 @@ SSL *s; } ciphers=NULL; c=ssl3_choose_cipher(s,s->session->ciphers, - ssl_get_ciphers_by_id(s)); + ssl_get_ciphers_by_id(s)); if (c == NULL) { @@ -738,19 +720,19 @@ SSL *s; { /* Session-id reuse */ #ifdef REUSE_CIPHER_BUG - STACK *sk; + STACK_OF(SSL_CIPHER) *sk; SSL_CIPHER *nc=NULL; SSL_CIPHER *ec=NULL; if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { sk=s->session->ciphers; - for (i=0; ialgorithms & SSL_eNULL) nc=c; - if (c->algorithms & SSL_EXP) + if (SSL_C_IS_EXPORT(c)) ec=c; } if (nc != NULL) @@ -783,12 +765,11 @@ f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); } err: - if (ciphers != NULL) sk_free(ciphers); + if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers); return(ret); } -static int ssl3_send_server_hello(s) -SSL *s; +static int ssl3_send_server_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; @@ -833,7 +814,10 @@ SSL *s; p+=i; /* put the compression method */ - *(p++)=0; + if (s->s3->tmp.new_compression == NULL) + *(p++)=0; + else + *(p++)=s->s3->tmp.new_compression->id; /* do the header */ l=(p-d); @@ -851,8 +835,7 @@ SSL *s; return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_send_server_done(s) -SSL *s; +static int ssl3_send_server_done(SSL *s) { unsigned char *p; @@ -876,8 +859,7 @@ SSL *s; return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_send_server_key_exchange(s) -SSL *s; +static int ssl3_send_server_key_exchange(SSL *s) { #ifndef NO_RSA unsigned char *q; @@ -902,7 +884,7 @@ SSL *s; if (s->state == SSL3_ST_SW_KEY_EXCH_A) { type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; - cert=s->session->cert; + cert=s->cert; buf=s->init_buf; @@ -912,11 +894,11 @@ 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, - (s->s3->tmp.new_cipher->algorithms| - SSL_NOT_EXP)?0:1); + 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); cert->rsa_tmp=rsa; } @@ -936,10 +918,10 @@ SSL *s; if (type & SSL_kEDH) { dhp=cert->dh_tmp; - if ((dhp == NULL) && (cert->dh_tmp_cb != NULL)) - dhp=cert->dh_tmp_cb(s, - (s->s3->tmp.new_cipher->algorithms| - SSL_NOT_EXP)?0:1); + 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) { al=SSL_AD_HANDSHAKE_FAILURE; @@ -953,13 +935,16 @@ SSL *s; } s->s3->tmp.dh=dh; - if (((dhp->pub_key == NULL) || - (dhp->priv_key == NULL) || - (s->options & SSL_OP_SINGLE_DH_USE)) && - (!DH_generate_key(dh))) + if ((dhp->pub_key == NULL || + dhp->priv_key == NULL || + (s->options & SSL_OP_SINGLE_DH_USE))) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); - goto err; + if(!DH_generate_key(dh)) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } } else { @@ -1098,12 +1083,11 @@ err: return(-1); } -static int ssl3_send_certificate_request(s) -SSL *s; +static int ssl3_send_certificate_request(SSL *s) { unsigned char *p,*d; int i,j,nl,off,n; - STACK *sk=NULL; + STACK_OF(X509_NAME) *sk=NULL; X509_NAME *name; BUF_MEM *buf; @@ -1128,9 +1112,9 @@ SSL *s; nl=0; if (sk != NULL) { - for (i=0; is3->tmp.use_rsa_tmp) { - 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; + 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) @@ -1259,15 +1240,28 @@ SSL *s; i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING); #if 1 - /* If a bad decrypt, use a dud master key */ + /* If a bad decrypt, use a random master key */ if ((i != SSL_MAX_MASTER_KEY_LENGTH) || - ((p[0] != (s->version>>8)) || - (p[1] != (s->version & 0xff)))) + ((p[0] != (s->client_version>>8)) || + (p[1] != (s->client_version & 0xff)))) { - p[0]=(s->version>>8); - p[1]=(s->version & 0xff); - RAND_bytes(&(p[2]),SSL_MAX_MASTER_KEY_LENGTH-2); - i=SSL_MAX_MASTER_KEY_LENGTH; + int bad=1; + + if ((i == SSL_MAX_MASTER_KEY_LENGTH) && + (p[0] == (s->version>>8)) && + (p[1] == 0)) + { + if (s->options & SSL_OP_TLS_ROLLBACK_BUG) + bad=0; + } + if (bad) + { + p[0]=(s->version>>8); + p[1]=(s->version & 0xff); + RAND_bytes(&(p[2]),SSL_MAX_MASTER_KEY_LENGTH-2); + i=SSL_MAX_MASTER_KEY_LENGTH; + } + /* else, an SSLeay bug, ssl only server, tls client */ } #else if (i != SSL_MAX_MASTER_KEY_LENGTH) @@ -1370,8 +1364,7 @@ err: return(-1); } -static int ssl3_get_cert_verify(s) -SSL *s; +static int ssl3_get_cert_verify(SSL *s) { EVP_PKEY *pkey=NULL; unsigned char *p; @@ -1505,17 +1498,17 @@ f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); } end: + EVP_PKEY_free(pkey); return(ret); } -static int ssl3_get_client_certificate(s) -SSL *s; +static int ssl3_get_client_certificate(SSL *s) { int i,ok,al,ret= -1; X509 *x=NULL; unsigned long l,nc,llen,n; unsigned char *p,*d,*q; - STACK *sk=NULL; + STACK_OF(X509) *sk=NULL; n=ssl3_get_message(s, SSL3_ST_SR_CERT_A, @@ -1558,7 +1551,7 @@ SSL *s; } d=p=(unsigned char *)s->init_buf->data; - if ((sk=sk_new_null()) == NULL) + if ((sk=sk_X509_new_null()) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE); goto err; @@ -1594,7 +1587,7 @@ SSL *s; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } - if (!sk_push(sk,(char *)x)) + if (!sk_X509_push(sk,x)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE); goto err; @@ -1603,7 +1596,7 @@ SSL *s; nc+=l+3; } - if (sk_num(sk) <= 0) + if (sk_X509_num(sk) <= 0) { /* TLS does not mind 0 certs returned */ if (s->version == SSL3_VERSION) @@ -1632,10 +1625,26 @@ SSL *s; } } - /* This should not be needed */ - if (s->session->peer != NULL) + if (s->session->peer != NULL) /* This should not be needed */ X509_free(s->session->peer); - s->session->peer=(X509 *)sk_shift(sk); + s->session->peer=sk_X509_shift(sk); + + /* With the current implementation, sess_cert will always be NULL + * when we arrive here. */ + if (s->session->sess_cert == NULL) + { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (s->session->sess_cert->cert_chain != NULL) + sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); + s->session->sess_cert->cert_chain=sk; + + sk=NULL; ret=1; if (0) @@ -1645,12 +1654,11 @@ f_err: } err: if (x != NULL) X509_free(x); - if (sk != NULL) sk_pop_free(sk,X509_free); + if (sk != NULL) sk_X509_pop_free(sk,X509_free); return(ret); } -int ssl3_send_server_certificate(s) -SSL *s; +int ssl3_send_server_certificate(SSL *s) { unsigned long l; X509 *x; -- cgit v1.2.3-55-g6feb