X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs23_srvr.c;h=9d47c22cb86e98f70e57611a26caae9a6ba9a4ac;hp=bcf8e51c5dcbdff0a29a513234d5f3844147328c;hb=44314cf64d1e51c7493799e77b14ae4e94a4c8cf;hpb=cf82191d77a0a8f77894a65185b6f7a4b3855d6c diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c index bcf8e51c5d..9d47c22cb8 100644 --- a/ssl/s23_srvr.c +++ b/ssl/s23_srvr.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -110,15 +110,18 @@ */ #include +#include "ssl_locl.h" #include #include #include #include -#include "ssl_locl.h" +#ifdef OPENSSL_FIPS +#include +#endif -static SSL_METHOD *ssl23_get_server_method(int ver); +static const SSL_METHOD *ssl23_get_server_method(int ver); int ssl23_get_client_hello(SSL *s); -static SSL_METHOD *ssl23_get_server_method(int ver) +static const SSL_METHOD *ssl23_get_server_method(int ver) { #ifndef OPENSSL_NO_SSL2 if (ver == SSL2_VERSION) @@ -128,31 +131,24 @@ static SSL_METHOD *ssl23_get_server_method(int ver) return(SSLv3_server_method()); else if (ver == TLS1_VERSION) return(TLSv1_server_method()); + else if (ver == TLS1_1_VERSION) + return(TLSv1_1_server_method()); + else if (ver == TLS1_2_VERSION) + return(TLSv1_2_server_method()); else return(NULL); } -SSL_METHOD *SSLv23_server_method(void) - { - static int init=1; - static SSL_METHOD SSLv23_server_data; - - if (init) - { - memcpy((char *)&SSLv23_server_data, - (char *)sslv23_base_method(),sizeof(SSL_METHOD)); - SSLv23_server_data.ssl_accept=ssl23_accept; - SSLv23_server_data.get_ssl_method=ssl23_get_server_method; - init=0; - } - return(&SSLv23_server_data); - } +IMPLEMENT_ssl23_meth_func(SSLv23_server_method, + ssl23_accept, + ssl_undefined_function, + ssl23_get_server_method) int ssl23_accept(SSL *s) { BUF_MEM *buf; - unsigned long Time=time(NULL); - void (*cb)()=NULL; + unsigned long Time=(unsigned long)time(NULL); + void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state; @@ -261,9 +257,6 @@ int ssl23_get_client_hello(SSL *s) int n=0,j; int type=0; int v[2]; -#ifndef OPENSSL_NO_RSA - int use_sslv2_strong=0; -#endif if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { @@ -297,7 +290,20 @@ int ssl23_get_client_hello(SSL *s) /* SSLv3/TLSv1 */ if (p[4] >= TLS1_VERSION_MINOR) { - if (!(s->options & SSL_OP_NO_TLSv1)) + if (p[4] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) + { + s->version=TLS1_2_VERSION; + s->state=SSL23_ST_SR_CLNT_HELLO_B; + } + else if (p[4] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) + { + s->version=TLS1_1_VERSION; + /* type=2; */ /* done later to survive restarts */ + s->state=SSL23_ST_SR_CLNT_HELLO_B; + } + else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; /* type=2; */ /* done later to survive restarts */ @@ -329,7 +335,7 @@ int ssl23_get_client_hello(SSL *s) (p[1] == SSL3_VERSION_MAJOR) && (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5 /* silly record length? */) - || (p[9] == p[1]))) + || (p[9] >= p[1]))) { /* * SSLv3 or tls1 header @@ -353,11 +359,30 @@ int ssl23_get_client_hello(SSL *s) v[1] = TLS1_VERSION_MINOR; #endif } + /* if major version number > 3 set minor to a value + * which will use the highest version 3 we support. + * If TLS 2.0 ever appears we will need to revise + * this.... + */ + else if (p[9] > SSL3_VERSION_MAJOR) + v[1]=0xff; else v[1]=p[10]; /* minor version according to client_version */ if (v[1] >= TLS1_VERSION_MINOR) { - if (!(s->options & SSL_OP_NO_TLSv1)) + if (v[1] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) + { + s->version=TLS1_2_VERSION; + type=3; + } + else if (v[1] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) + { + s->version=TLS1_1_VERSION; + type=3; + } + else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; type=3; @@ -400,6 +425,22 @@ int ssl23_get_client_hello(SSL *s) } } + if (s->version < TLS1_2_VERSION && tls1_suiteb(s)) + { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + goto err; + } + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header @@ -430,7 +471,9 @@ int ssl23_get_client_hello(SSL *s) n2s(p,sil); n2s(p,cl); d=(unsigned char *)s->init_buf->data; - if ((csl+sil+cl+11) != s->packet_length) + if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format + * Client Hello, can we? Error condition should be + * '>' otherweise */ { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); goto err; @@ -473,7 +516,16 @@ int ssl23_get_client_hello(SSL *s) *(d++)=1; *(d++)=0; - i=(d-(unsigned char *)s->init_buf->data); +#if 0 + /* copy any remaining data with may be extensions */ + p = p+csl+sil+cl; + while (p < s->packet+s->packet_length) + { + *(d++)=*(p++); + } +#endif + + i = (d-(unsigned char *)s->init_buf->data) - 4; l2n3((long)i, d_len); /* get the data reused from the init_buf */ @@ -505,16 +557,14 @@ int ssl23_get_client_hello(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)) { goto err; } s->state=SSL2_ST_GET_CLIENT_HELLO_A; - if ((s->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) || - use_sslv2_strong || - (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3)) + if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) s->s2->ssl2_rollback=0; else /* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 @@ -550,6 +600,10 @@ int ssl23_get_client_hello(SSL *s) * for SSLv3 */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet= &(s->s3->rbuf.buf[0]); memcpy(s->packet,buf,n); s->s3->rbuf.left=n; @@ -561,8 +615,11 @@ int ssl23_get_client_hello(SSL *s) s->s3->rbuf.left=0; s->s3->rbuf.offset=0; } - - if (s->version == TLS1_VERSION) + if (s->version == TLS1_2_VERSION) + s->method = TLSv1_2_server_method(); + else if (s->version == TLS1_1_VERSION) + s->method = TLSv1_1_server_method(); + else if (s->version == TLS1_VERSION) s->method = TLSv1_server_method(); else s->method = SSLv3_server_method(); @@ -581,7 +638,6 @@ int ssl23_get_client_hello(SSL *s) s->init_num=0; if (buf != buf_space) OPENSSL_free(buf); - s->first_packet=1; return(SSL_accept(s)); err: if (buf != buf_space) OPENSSL_free(buf);