X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fs23_clnt.c;h=64ee4269ec1069828f7e7f03d29b7ed470956c54;hb=e4b52ac3530849a48aae3b18b9781019cb16826b;hp=57d3623f3f001bb5c54c71622d7b154a4507fc60;hpb=d02b48c63a58ea4367a0e905979f140b7d090f86;p=openssl.git diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 57d3623f3f..64ee4269ec 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -1,5 +1,5 @@ /* ssl/s23_clnt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -57,69 +57,71 @@ */ #include -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" #include "ssl_locl.h" +#include +#include +#include +#include -#define BREAK break - -#ifndef NOPROTO +static SSL_METHOD *ssl23_get_client_method(int ver); static int ssl23_client_hello(SSL *s); static int ssl23_get_server_hello(SSL *s); -#else -static int ssl23_client_hello(); -static int ssl23_get_server_hello(); -#endif - -static SSL_METHOD *ssl23_get_client_method(ver) -int ver; +static SSL_METHOD *ssl23_get_client_method(int ver) { - if (ver == 2) +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) return(SSLv2_client_method()); - else if (ver == 3) +#endif + if (ver == SSL3_VERSION) return(SSLv3_client_method()); + else if (ver == TLS1_VERSION) + return(TLSv1_client_method()); else return(NULL); } -SSL_METHOD *SSLv23_client_method() +SSL_METHOD *SSLv23_client_method(void) { static int init=1; static SSL_METHOD SSLv23_client_data; if (init) { - init=0; - memcpy((char *)&SSLv23_client_data, - (char *)sslv23_base_method(),sizeof(SSL_METHOD)); - SSLv23_client_data.ssl_connect=ssl23_connect; - SSLv23_client_data.get_ssl_method=ssl23_get_client_method; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv23_client_data, + (char *)sslv23_base_method(),sizeof(SSL_METHOD)); + SSLv23_client_data.ssl_connect=ssl23_connect; + SSLv23_client_data.get_ssl_method=ssl23_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv23_client_data); } -int ssl23_connect(s) -SSL *s; +int ssl23_connect(SSL *s) { - BUF_MEM *buf; + BUF_MEM *buf=NULL; unsigned long Time=time(NULL); - void (*cb)()=NULL; + void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state; - RAND_seed((unsigned char *)&Time,sizeof(Time)); + RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; - if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); for (;;) { @@ -132,9 +134,16 @@ SSL *s; case SSL_ST_BEFORE|SSL_ST_CONNECT: case SSL_ST_OK|SSL_ST_CONNECT: + if (s->session != NULL) + { + SSLerr(SSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE); + ret= -1; + goto end; + } + s->server=0; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=3; + /* s->version=TLS1_VERSION; */ s->type=SSL_ST_CONNECT; if (s->init_buf == NULL) @@ -150,6 +159,7 @@ SSL *s; goto end; } s->init_buf=buf; + buf=NULL; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } @@ -157,7 +167,7 @@ SSL *s; ssl3_init_finished_mac(s); s->state=SSL23_ST_CW_CLNT_HELLO_A; - s->ctx->sess_connect++; + s->ctx->stats.sess_connect++; s->init_num=0; break; @@ -177,7 +187,7 @@ SSL *s; ret=ssl23_get_server_hello(s); if (ret >= 0) cb=NULL; goto end; - break; + /* break; */ default: SSLerr(SSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE); @@ -186,7 +196,7 @@ SSL *s; /* break; */ } - if (s->debug) BIO_flush(s->wbio); + if (s->debug) { (void)BIO_flush(s->wbio); } if ((cb != NULL) && (s->state != state)) { @@ -198,18 +208,20 @@ SSL *s; } end: s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); } -static int ssl23_client_hello(s) -SSL *s; +static int ssl23_client_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; int i,ch_len; + int ret; buf=(unsigned char *)s->init_buf->data; if (s->state == SSL23_ST_CW_CLNT_HELLO_A) @@ -223,15 +235,36 @@ SSL *s; #endif p=s->s3->client_random; - RAND_bytes(p,SSL3_RANDOM_SIZE); + RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE); /* Do the message type and length last */ d= &(buf[2]); p=d+9; *(d++)=SSL2_MT_CLIENT_HELLO; - *(d++)=SSL3_VERSION_MAJOR; - *(d++)=SSL3_VERSION_MINOR; + if (!(s->options & SSL_OP_NO_TLSv1)) + { + *(d++)=TLS1_VERSION_MAJOR; + *(d++)=TLS1_VERSION_MINOR; + s->client_version=TLS1_VERSION; + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + { + *(d++)=SSL3_VERSION_MAJOR; + *(d++)=SSL3_VERSION_MINOR; + s->client_version=SSL3_VERSION; + } + else if (!(s->options & SSL_OP_NO_SSLv2)) + { + *(d++)=SSL2_VERSION_MAJOR; + *(d++)=SSL2_VERSION_MINOR; + s->client_version=SSL2_VERSION; + } + else + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE); + return(-1); + } /* Ciphers supported */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p); @@ -251,7 +284,7 @@ SSL *s; #endif s2n(0,d); - if (s->ctx->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; @@ -263,7 +296,7 @@ SSL *s; i=ch_len; s2n(i,d); memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); - RAND_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); + RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); p+=i; @@ -280,17 +313,19 @@ SSL *s; } /* SSL3_ST_CW_CLNT_HELLO_B */ - return(ssl23_write_bytes(s)); + ret = ssl23_write_bytes(s); + if (ret >= 2) + if (s->msg_callback) + s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ + return ret; } -static int ssl23_get_server_hello(s) -SSL *s; +static int ssl23_get_server_hello(SSL *s) { char buf[8]; unsigned char *p; - int i,ch_len; + int i; int n; - BIO *bbio; n=ssl23_read_bytes(s,7); @@ -302,10 +337,20 @@ SSL *s; if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && (p[5] == 0x00) && (p[6] == 0x02)) { +#ifdef OPENSSL_NO_SSL2 + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); + goto err; +#else /* we are talking sslv2 */ /* we need to clean up the SSLv3 setup and put in the * sslv2 stuff. */ + int ch_len; + if (s->options & SSL_OP_NO_SSLv2) + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } if (s->s2 == NULL) { if (!ssl2_new(s)) @@ -314,7 +359,7 @@ SSL *s; else ssl2_clear(s); - if (s->ctx->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; @@ -328,7 +373,7 @@ SSL *s; if (s->s3 != NULL) ssl3_free(s); - if (!BUF_MEM_grow(s->init_buf, + if (!BUF_MEM_grow_clean(s->init_buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); @@ -336,7 +381,9 @@ SSL *s; } s->state=SSL2_ST_GET_SERVER_HELLO_A; - s->s2->ssl2_rollback=1; + if (!(s->client_version == SSL2_VERSION)) + /* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */ + s->s2->ssl2_rollback=1; /* setup the 5 bytes we have read so we get them from * the sslv2 buffer */ @@ -352,36 +399,17 @@ SSL *s; s->method=SSLv2_client_method(); s->handshake_func=s->method->ssl_connect; +#endif } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && - (p[2] == SSL3_VERSION_MINOR) && + ((p[2] == SSL3_VERSION_MINOR) || + (p[2] == TLS1_VERSION_MINOR)) && (p[5] == SSL3_MT_SERVER_HELLO)) { - /* we have sslv3 */ - - if (s->bbio == NULL) - { - bbio=BIO_new(BIO_f_buffer()); - if (bbio == NULL) - { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); - goto err; - } - s->bbio=bbio; - } - else - bbio=s->bbio; + /* we have sslv3 or tls1 */ - BIO_reset(bbio); - if (!BIO_set_write_buffer_size(bbio,16*1024)) - { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); - goto err; - } - - /* start the buffering */ - s->wbio=BIO_push(s->bbio,s->wbio); + if (!ssl_init_wbio_buffer(s,1)) goto err; /* we are in this state */ s->state=SSL3_ST_CR_SRVR_HELLO_A; @@ -395,16 +423,34 @@ SSL *s; s->s3->rbuf.left=n; s->s3->rbuf.offset=0; - s->method=SSLv3_client_method(); + if ((p[2] == SSL3_VERSION_MINOR) && + !(s->options & SSL_OP_NO_SSLv3)) + { + s->version=SSL3_VERSION; + s->method=SSLv3_client_method(); + } + else if ((p[2] == TLS1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1)) + { + s->version=TLS1_VERSION; + s->method=TLSv1_client_method(); + } + else + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + s->handshake_func=s->method->ssl_connect; } else if ((p[0] == SSL3_RT_ALERT) && (p[1] == SSL3_VERSION_MAJOR) && - (p[2] == SSL3_VERSION_MINOR) && + ((p[2] == SSL3_VERSION_MINOR) || + (p[2] == TLS1_VERSION_MINOR)) && (p[3] == 0) && (p[4] == 2)) { - void (*cb)()=NULL; + void (*cb)(const SSL *ssl,int type,int val)=NULL; int j; /* An alert */ @@ -421,7 +467,7 @@ SSL *s; } s->rwstate=SSL_NOTHING; - SSLerr(SSL_F_SSL3_READ_BYTES,1000+p[6]); + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); goto err; } else