From 82c9e90a5860bd93851cf7399bea3fc5bd03cdf2 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 12 Dec 2014 15:55:27 -0500 Subject: [PATCH] Merge SSLv23_method and DTLS_ANY_VERSION. This makes SSLv23_method go through DTLS_ANY_VERSION's version negotiation logic. This allows us to get rid of duplicate ClientHello logic. For compatibility, SSL_METHOD is now split into SSL_PROTOCOL_METHOD and a version. The legacy version-locked methods set min_version and max_version based this version field to emulate the original semantics. As a bonus, we can now handle fragmented ClientHello versions now. Because SSLv23_method is a silly name, deprecate that too and introduce TLS_method. Change-Id: I8b3df2b427ae34c44ecf972f466ad64dc3dbb171 --- include/openssl/dtls1.h | 2 - include/openssl/ssl.h | 113 ++++----- ssl/CMakeLists.txt | 5 - ssl/d1_lib.c | 5 +- ssl/d1_meth.c | 96 +++++-- ssl/s23_clnt.c | 520 -------------------------------------- ssl/s23_lib.c | 131 ---------- ssl/s23_meth.c | 71 ------ ssl/s23_pkt.c | 117 --------- ssl/s23_srvr.c | 493 ------------------------------------ ssl/s3_both.c | 21 ++ ssl/s3_clnt.c | 14 +- ssl/s3_lib.c | 2 +- ssl/s3_meth.c | 139 +++++++--- ssl/s3_srvr.c | 12 +- ssl/ssl_ciph.c | 4 +- ssl/ssl_lib.c | 34 +-- ssl/ssl_locl.h | 154 ++++------- ssl/ssl_test.c | 24 +- ssl/t1_enc.c | 2 +- ssl/test/bssl_shim.cc | 2 +- ssl/test/runner/runner.go | 3 +- 22 files changed, 330 insertions(+), 1634 deletions(-) delete mode 100644 ssl/s23_clnt.c delete mode 100644 ssl/s23_lib.c delete mode 100644 ssl/s23_meth.c delete mode 100644 ssl/s23_pkt.c delete mode 100644 ssl/s23_srvr.c diff --git a/include/openssl/dtls1.h b/include/openssl/dtls1.h index ac097ce7..d3a3b55b 100644 --- a/include/openssl/dtls1.h +++ b/include/openssl/dtls1.h @@ -69,8 +69,6 @@ extern "C" { #define DTLS1_VERSION 0xFEFF #define DTLS1_2_VERSION 0xFEFD -/* Special value for method supporting multiple versions */ -#define DTLS_ANY_VERSION 0x1FFFF /* lengths of messages */ #define DTLS1_COOKIE_LENGTH 256 diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index e5d7a511..e4469e8f 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -277,6 +277,7 @@ extern "C" { #define SSL_FILETYPE_PEM X509_FILETYPE_PEM typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD; typedef struct ssl_cipher_st SSL_CIPHER; typedef struct ssl_session_st SSL_SESSION; typedef struct tls_sigalgs_st TLS_SIGALGS; @@ -318,38 +319,6 @@ struct ssl_cipher_st int alg_bits; /* Number of bits for algorithm */ }; - -/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ -struct ssl_method_st - { - int version; - int (*ssl_new)(SSL *s); - void (*ssl_clear)(SSL *s); - void (*ssl_free)(SSL *s); - int (*ssl_accept)(SSL *s); - int (*ssl_connect)(SSL *s); - int (*ssl_read)(SSL *s,void *buf,int len); - int (*ssl_peek)(SSL *s,void *buf,int len); - int (*ssl_write)(SSL *s,const void *buf,int len); - int (*ssl_shutdown)(SSL *s); - int (*ssl_renegotiate)(SSL *s); - int (*ssl_renegotiate_check)(SSL *s); - long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long - max, int hash_message, int *ok); - int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, - int peek); - int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len); - int (*ssl_dispatch_alert)(SSL *s); - long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg); - long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg); - int (*ssl_pending)(const SSL *s); - int (*num_ciphers)(void); - const SSL_CIPHER *(*get_cipher)(unsigned ncipher); - int (*ssl_version)(void); - long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void)); - long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void)); - }; - /* An SSL_SESSION represents an SSL session that may be resumed in an * abbreviated handshake. */ struct ssl_session_st @@ -739,7 +708,7 @@ struct ssl_cipher_preference_list_st struct ssl_ctx_st { - const SSL_METHOD *method; + const SSL_PROTOCOL_METHOD *method; /* max_version is the maximum acceptable protocol version. If * zero, the maximum supported version, currently (D)TLS 1.2, @@ -1196,11 +1165,8 @@ struct ssl_st int version; /* method is the method table corresponding to the current protocol - * (DTLS or TLS). - * - * TODO(davidben): For now, it also corresponds to the protocol version, - * but that will soon change. */ - const SSL_METHOD *method; + * (DTLS or TLS). */ + const SSL_PROTOCOL_METHOD *method; /* enc_method is the method table corresponding to the current protocol * version. */ @@ -2066,38 +2032,47 @@ OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c); OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c); OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c); -OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ -OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ -OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ - -OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ -OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ -OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ - -OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ - -OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ - -OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ -OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ - - -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ - -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */ -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */ -OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */ +/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */ +OPENSSL_EXPORT const SSL_METHOD *TLS_method(void); + +/* DTLS_method is the SSL_METHOD used for DTLS connections. */ +OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); + + +/* Deprecated methods. */ + +/* SSLv23_method calls TLS_method. */ +OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); + +/* Version-specific methods behave exactly like TLS_method and DTLS_method they + * also call SSL_CTX_set_min_version and SSL_CTX_set_max_version to lock + * connections to that protocol version. */ +OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); + +/* Client- and server-specific methods call their corresponding generic + * methods. */ +OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); -OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ -OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ -OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt index b47b261e..3852d20f 100644 --- a/ssl/CMakeLists.txt +++ b/ssl/CMakeLists.txt @@ -13,11 +13,6 @@ add_library( d1_pkt.c d1_srtp.c d1_srvr.c - s23_clnt.c - s23_lib.c - s23_meth.c - s23_pkt.c - s23_srvr.c s3_both.c s3_cbc.c s3_clnt.c diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 3f43bf24..8fb9e5dd 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -266,10 +266,7 @@ void dtls1_clear(SSL *s) } ssl3_clear(s); - if (s->method->version == DTLS_ANY_VERSION) - s->version=DTLS1_2_VERSION; - else - s->version=s->method->version; + s->version = DTLS1_2_VERSION; } long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c index 5e302515..eed04020 100644 --- a/ssl/d1_meth.c +++ b/ssl/d1_meth.c @@ -58,38 +58,80 @@ #include "ssl_locl.h" -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, DTLSv1_method) +static const SSL_PROTOCOL_METHOD DTLS_protocol_method = { + dtls1_new, + dtls1_clear, + dtls1_free, + dtls1_accept, + dtls1_connect, + ssl3_read, + ssl3_peek, + ssl3_write, + dtls1_shutdown, + ssl3_renegotiate, + ssl3_renegotiate_check, + dtls1_get_message, + dtls1_read_bytes, + dtls1_write_app_data_bytes, + dtls1_dispatch_alert, + dtls1_ctrl, + ssl3_ctx_ctrl, + ssl3_pending, + ssl3_num_ciphers, + dtls1_get_cipher, + ssl_undefined_void_function, + ssl3_callback_ctrl, + ssl3_ctx_callback_ctrl, +}; -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, DTLSv1_2_method) +const SSL_METHOD *DTLS_method(void) { + static const SSL_METHOD method = { + 0, + &DTLS_protocol_method, + }; + return &method; +} -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, DTLS_method) +/* Legacy version-locked methods. */ -const SSL_METHOD *DTLSv1_2_server_method(void) - { - return DTLSv1_2_method(); - } +const SSL_METHOD *DTLSv1_2_method(void) { + static const SSL_METHOD method = { + DTLS1_2_VERSION, + &DTLS_protocol_method, + }; + return &method; +} -const SSL_METHOD *DTLSv1_server_method(void) - { - return DTLSv1_method(); - } +const SSL_METHOD *DTLSv1_method(void) { + static const SSL_METHOD method = { + DTLS1_VERSION, + &DTLS_protocol_method, + }; + return &method; +} -const SSL_METHOD *DTLS_server_method(void) - { - return DTLS_method(); - } +/* Legacy side-specific methods. */ -const SSL_METHOD *DTLSv1_2_client_method(void) - { - return DTLSv1_2_method(); - } +const SSL_METHOD *DTLSv1_2_server_method(void) { + return DTLSv1_2_method(); +} -const SSL_METHOD *DTLSv1_client_method(void) - { - return DTLSv1_method(); - } +const SSL_METHOD *DTLSv1_server_method(void) { + return DTLSv1_method(); +} -const SSL_METHOD *DTLS_client_method(void) - { - return DTLS_method(); - } +const SSL_METHOD *DTLSv1_2_client_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_client_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLS_server_method(void) { + return DTLS_method(); +} + +const SSL_METHOD *DTLS_client_method(void) { + return DTLS_method(); +} diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c deleted file mode 100644 index 8ff30870..00000000 --- a/ssl/s23_clnt.c +++ /dev/null @@ -1,520 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -* All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * 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 - * 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "ssl_locl.h" - -static int ssl23_client_hello(SSL *s); -static int ssl23_get_server_hello(SSL *s); - -int ssl23_connect(SSL *s) - { - BUF_MEM *buf=NULL; - void (*cb)(const SSL *ssl,int type,int val)=NULL; - int ret= -1; - int new_state,state; - - assert(s->handshake_func == ssl23_connect); - assert(!s->server); - assert(!SSL_IS_DTLS(s)); - - ERR_clear_error(); - ERR_clear_system_error(); - - if (s->info_callback != NULL) - cb=s->info_callback; - else if (s->ctx->info_callback != NULL) - cb=s->ctx->info_callback; - - s->in_handshake++; - - for (;;) - { - state=s->state; - - switch(s->state) - { - case SSL_ST_CONNECT: - case SSL_ST_BEFORE|SSL_ST_CONNECT: - - if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - - if (s->init_buf == NULL) - { - if ((buf=BUF_MEM_new()) == NULL) - { - ret= -1; - goto end; - } - if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) - { - ret= -1; - goto end; - } - s->init_buf=buf; - buf=NULL; - } - - if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } - - if (!ssl3_init_finished_mac(s)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_connect, ERR_R_INTERNAL_ERROR); - ret = -1; - goto end; - } - - s->state=SSL23_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num=0; - break; - - case SSL23_ST_CW_CLNT_HELLO_A: - case SSL23_ST_CW_CLNT_HELLO_B: - - s->shutdown=0; - ret=ssl23_client_hello(s); - if (ret <= 0) goto end; - s->state=SSL23_ST_CR_SRVR_HELLO_A; - s->init_num=0; - - break; - - case SSL23_ST_CR_SRVR_HELLO_A: - case SSL23_ST_CR_SRVR_HELLO_B: - ret=ssl23_get_server_hello(s); - if (ret >= 0) cb=NULL; - goto end; - /* break; */ - - default: - OPENSSL_PUT_ERROR(SSL, ssl23_connect, SSL_R_UNKNOWN_STATE); - ret= -1; - goto end; - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) - { - new_state=s->state; - s->state=state; - cb(s,SSL_CB_CONNECT_LOOP,1); - s->state=new_state; - } - } -end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s,SSL_CB_CONNECT_EXIT,ret); - return(ret); - } - -/* Fill a ClientRandom or ServerRandom field of length len. Returns 0 - * on failure, 1 on success. */ -int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) - { - int send_time = 0; - if (len < 4) - return 0; - if (server) - send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; - else - send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; - if (send_time) - { - unsigned long Time = (unsigned long)time(NULL); - unsigned char *p = result; - l2n(Time, p); - return RAND_bytes(p, len-4); - } - else - return RAND_bytes(result, len); - } - -static int ssl23_client_hello(SSL *s) - { - unsigned char *buf; - unsigned char *p,*d; - int i; - unsigned long l; - uint16_t version; - uint8_t version_major, version_minor; - int ret; - - version = ssl3_get_max_client_version(s); - if (version == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, SSL_R_WRONG_SSL_VERSION); - return -1; - } - - buf=(unsigned char *)s->init_buf->data; - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) - { - /* If the configured session was created at a version - * higher than our maximum version, drop it. */ - if (s->session && - (s->session->ssl_version > version || - s->session->session_id_length == 0 || - s->session->not_resumable)) - { - SSL_set_session(s, NULL); - } - - p=s->s3->client_random; - if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) - return -1; - - if (version == TLS1_2_VERSION) - { - version_major = TLS1_2_VERSION_MAJOR; - version_minor = TLS1_2_VERSION_MINOR; - } - else if (version == TLS1_1_VERSION) - { - version_major = TLS1_1_VERSION_MAJOR; - version_minor = TLS1_1_VERSION_MINOR; - } - else if (version == TLS1_VERSION) - { - version_major = TLS1_VERSION_MAJOR; - version_minor = TLS1_VERSION_MINOR; - } - else if (version == SSL3_VERSION) - { - version_major = SSL3_VERSION_MAJOR; - version_minor = SSL3_VERSION_MINOR; - } - else - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, SSL_R_NO_PROTOCOLS_AVAILABLE); - return(-1); - } - - s->client_version = version; - - /* create Client Hello in SSL 3.0/TLS 1.0 format */ - - /* do the record header (5 bytes) and handshake message - * header (4 bytes) last. Note: the final argument to - * ssl_add_clienthello_tlsext below depends on the size - * of this prefix. */ - d = p = &(buf[9]); - - *(p++) = version_major; - *(p++) = version_minor; - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID */ - if (s->new_session || s->session == NULL) - i=0; - else - i=s->session->session_id_length; - *(p++)=i; - if (i != 0) - { - if (i > (int)sizeof(s->session->session_id)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p,s->session->session_id,i); - p+=i; - } - - /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); - if (i == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, SSL_R_NO_CIPHERS_AVAILABLE); - return -1; - } - s2n(i,p); - p+=i; - - /* COMPRESSION */ - *(p++)=1; - *(p++)=0; /* Add the NULL method */ - - /* TLS extensions*/ - if (ssl_prepare_clienthello_tlsext(s) <= 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, SSL_R_CLIENTHELLO_TLSEXT); - return -1; - } - - /* The buffer includes the 5 byte record header, so - * subtract it to compute hlen for - * ssl_add_clienthello_tlsext. */ - if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf-5)) == NULL) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, ERR_R_INTERNAL_ERROR); - return -1; - } - - l = p-d; - - /* fill in 4-byte handshake header */ - d=&(buf[5]); - *(d++)=SSL3_MT_CLIENT_HELLO; - l2n3(l,d); - - l += 4; - - if (l > SSL3_RT_MAX_PLAIN_LENGTH) - { - OPENSSL_PUT_ERROR(SSL, ssl23_client_hello, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* fill in 5-byte record header */ - d=buf; - *(d++) = SSL3_RT_HANDSHAKE; - *(d++) = version_major; - /* Some servers hang if we use long client hellos - * and a record number > TLS 1.0. - */ - if (TLS1_get_client_version(s) > TLS1_VERSION) - *(d++) = 1; - else - *(d++) = version_minor; - s2n((int)l,d); - - /* number of bytes to write */ - s->init_num=p-buf; - s->init_off=0; - - ssl3_finish_mac(s,&(buf[5]), s->init_num - 5); - - s->state=SSL23_ST_CW_CLNT_HELLO_B; - s->init_off=0; - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - ret = ssl23_write_bytes(s); - - if ((ret >= 2) && s->msg_callback) - { - /* Client Hello has been sent; tell msg_callback */ - - s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, s, s->msg_callback_arg); - s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg); - } - - return ret; - } - -static int ssl23_get_server_hello(SSL *s) - { - char buf[8]; - unsigned char *p; - int i; - int n; - - n=ssl23_read_bytes(s,7); - - if (n != 7) return(n); - p=s->packet; - - memcpy(buf,p,n); - - if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && - (p[5] == 0x00) && (p[6] == 0x02)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - else if (p[1] == SSL3_VERSION_MAJOR && - p[2] <= TLS1_2_VERSION_MINOR && - ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || - (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) - { - uint16_t version = (p[1] << 8) | p[2]; - if (!ssl3_is_version_enabled(s, version)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - s->version = version; - s->method = ssl3_get_method(version); - assert(s->method != NULL); - s->enc_method = ssl3_get_enc_method(s->version); - assert(s->enc_method != NULL); - - if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) - { - /* fatal alert */ - - void (*cb)(const SSL *ssl,int type,int val)=NULL; - int j; - - if (s->info_callback != NULL) - cb=s->info_callback; - else if (s->ctx->info_callback != NULL) - cb=s->ctx->info_callback; - - i=p[5]; - if (cb != NULL) - { - j=(i<<8)|p[6]; - cb(s,SSL_CB_READ_ALERT,j); - } - - if (s->msg_callback) - { - s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg); - s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg); - } - - s->rwstate=SSL_NOTHING; - OPENSSL_PUT_ERROR(SSL, ssl23_get_server_hello, SSL_AD_REASON_OFFSET + p[6]); - goto err; - } - - if (!ssl_init_wbio_buffer(s,1)) goto err; - - /* we are in this state */ - s->state=SSL3_ST_CR_SRVR_HELLO_A; - - /* put the 7 bytes we have read into the input buffer - * 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; - s->s3->rbuf.offset=0; - - s->handshake_func=s->method->ssl_connect; - } - else - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_server_hello, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - s->init_num=0; - return(SSL_connect(s)); -err: - return(-1); - } diff --git a/ssl/s23_lib.c b/ssl/s23_lib.c deleted file mode 100644 index 36f3ef1d..00000000 --- a/ssl/s23_lib.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include -#include - -#include "ssl_locl.h" - -int ssl23_read(SSL *s, void *buf, int len) - { - int n; - - ERR_clear_system_error(); - if (SSL_in_init(s) && (!s->in_handshake)) - { - n=s->handshake_func(s); - if (n < 0) return(n); - if (n == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_read, SSL_R_SSL_HANDSHAKE_FAILURE); - return(-1); - } - return(SSL_read(s,buf,len)); - } - else - { - ssl_undefined_function(s); - return(-1); - } - } - -int ssl23_peek(SSL *s, void *buf, int len) - { - int n; - - ERR_clear_system_error(); - if (SSL_in_init(s) && (!s->in_handshake)) - { - n=s->handshake_func(s); - if (n < 0) return(n); - if (n == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_peek, SSL_R_SSL_HANDSHAKE_FAILURE); - return(-1); - } - return(SSL_peek(s,buf,len)); - } - else - { - ssl_undefined_function(s); - return(-1); - } - } - -int ssl23_write(SSL *s, const void *buf, int len) - { - int n; - - ERR_clear_system_error(); - if (SSL_in_init(s) && (!s->in_handshake)) - { - n=s->handshake_func(s); - if (n < 0) return(n); - if (n == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_write, SSL_R_SSL_HANDSHAKE_FAILURE); - return(-1); - } - return(SSL_write(s,buf,len)); - } - else - { - ssl_undefined_function(s); - return(-1); - } - } diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c deleted file mode 100644 index d019c54e..00000000 --- a/ssl/s23_meth.c +++ /dev/null @@ -1,71 +0,0 @@ -/* ssl/s23_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include "ssl_locl.h" - - -IMPLEMENT_ssl23_meth_func(SSLv23_method) - -const SSL_METHOD *SSLv23_server_method(void) - { - return SSLv23_method(); - } - -const SSL_METHOD *SSLv23_client_method(void) - { - return SSLv23_method(); - } diff --git a/ssl/s23_pkt.c b/ssl/s23_pkt.c deleted file mode 100644 index 796dcb32..00000000 --- a/ssl/s23_pkt.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include -#include - -#include -#include - -#include "ssl_locl.h" - - -int ssl23_write_bytes(SSL *s) - { - int i,num,tot; - char *buf; - - buf=s->init_buf->data; - tot=s->init_off; - num=s->init_num; - for (;;) - { - s->rwstate=SSL_WRITING; - i=BIO_write(s->wbio,&(buf[tot]),num); - if (i <= 0) - { - s->init_off=tot; - s->init_num=num; - return(i); - } - s->rwstate=SSL_NOTHING; - if (i == num) return(tot+i); - - num-=i; - tot+=i; - } - } - -/* return regularly only when we have read (at least) 'n' bytes */ -int ssl23_read_bytes(SSL *s, int n) - { - unsigned char *p; - int j; - - if (s->packet_length < (unsigned int)n) - { - p=s->packet; - - for (;;) - { - s->rwstate=SSL_READING; - j=BIO_read(s->rbio,(char *)&(p[s->packet_length]), - n-s->packet_length); - if (j <= 0) - return(j); - s->rwstate=SSL_NOTHING; - s->packet_length+=j; - if (s->packet_length >= (unsigned int)n) - return(s->packet_length); - } - } - return(n); - } - diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c deleted file mode 100644 index 2aaf413e..00000000 --- a/ssl/s23_srvr.c +++ /dev/null @@ -1,493 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * 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 - * 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ssl_locl.h" - -static int ssl23_get_client_hello(SSL *s); -static int ssl23_get_v2_client_hello(SSL *s); - -int ssl23_accept(SSL *s) - { - BUF_MEM *buf = NULL; - void (*cb)(const SSL *ssl,int type,int val)=NULL; - int ret= -1; - int new_state,state; - - assert(s->handshake_func == ssl23_accept); - assert(s->server); - assert(!SSL_IS_DTLS(s)); - - ERR_clear_error(); - ERR_clear_system_error(); - - if (s->info_callback != NULL) - cb=s->info_callback; - else if (s->ctx->info_callback != NULL) - cb=s->ctx->info_callback; - - s->in_handshake++; - - for (;;) - { - state=s->state; - - switch(s->state) - { - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE|SSL_ST_ACCEPT: - - if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - - if (s->init_buf == NULL) - { - if ((buf=BUF_MEM_new()) == NULL) - { - ret= -1; - goto end; - } - if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) - { - ret= -1; - goto end; - } - s->init_buf=buf; - buf = NULL; - } - - if (!ssl3_init_finished_mac(s)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_accept, ERR_R_INTERNAL_ERROR); - ret = -1; - goto end; - } - - s->state=SSL23_ST_SR_CLNT_HELLO; - s->ctx->stats.sess_accept++; - s->init_num=0; - break; - - case SSL23_ST_SR_CLNT_HELLO: - s->shutdown = 0; - ret = ssl23_get_client_hello(s); - if (ret <= 0) goto end; - break; - - case SSL23_ST_SR_V2_CLNT_HELLO: - ret = ssl23_get_v2_client_hello(s); - if (ret <= 0) goto end; - break; - - case SSL23_ST_SR_SWITCH_VERSION: - if (!ssl_init_wbio_buffer(s, 1)) - { - ret = -1; - goto end; - } - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - s->method = ssl3_get_method(s->version); - assert(s->method != NULL); - s->enc_method = ssl3_get_enc_method(s->version); - assert(s->enc_method != NULL); - s->handshake_func = s->method->ssl_accept; - s->init_num = 0; - - /* NULL the callback; SSL_accept will call it instead. */ - cb = NULL; - ret = SSL_accept(s); - goto end; - /* break; */ - - default: - OPENSSL_PUT_ERROR(SSL, ssl23_accept, SSL_R_UNKNOWN_STATE); - ret= -1; - goto end; - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) - { - new_state=s->state; - s->state=state; - cb(s,SSL_CB_ACCEPT_LOOP,1); - s->state=new_state; - } - } -end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s,SSL_CB_ACCEPT_EXIT,ret); - return(ret); - } - -static int ssl23_get_client_hello(SSL *s) - { - uint8_t *p; - int n = 0; - - /* Sniff enough of the input to determine ClientHello type and the - * client version. */ - if (!ssl3_setup_buffers(s)) goto err; - - /* Read the initial 11 bytes of the input. This is sufficient to - * determine the client version for a ClientHello or a - * V2ClientHello. - * - * ClientHello (assuming client_version is unfragmented): - * Byte Content - * 0 type \ - * 1-2 version > record header - * 3-4 length / - * 5 msg_type \ - * 6-8 length > Client Hello message - * 9-10 client_version / - * - * V2ClientHello: - * Byte Content - * 0-1 msg_length - * 2 msg_type - * 3-4 version - * 5-6 cipher_spec_length - * 7-8 session_id_length - * 9-10 challenge_length - */ - n = ssl23_read_bytes(s, 11); - if (n <= 0) - return n; - assert(n == 11); - - p = s->packet; - - /* Some dedicated error codes for protocol mixups should the application - * wish to interpret them differently. (These do not overlap with - * ClientHello or V2ClientHello.) */ - if ((strncmp("GET ", (char *)p, 4) == 0) || - (strncmp("POST ",(char *)p, 5) == 0) || - (strncmp("HEAD ",(char *)p, 5) == 0) || - (strncmp("PUT ", (char *)p, 4) == 0)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTP_REQUEST); - goto err; - } - if (strncmp("CONNECT",(char *)p, 7) == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTPS_PROXY_REQUEST); - goto err; - } - - /* Determine if this is a ClientHello or V2ClientHello. */ - if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) - { - /* This is a V2ClientHello. Determine the version to - * use. */ - uint16_t client_version = (p[3] << 8) | p[4]; - uint16_t version = ssl3_get_mutual_version(s, client_version); - if (version == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - s->version = version; - /* Parse the entire V2ClientHello. */ - s->state = SSL23_ST_SR_V2_CLNT_HELLO; - } - else if ((p[0] == SSL3_RT_HANDSHAKE) && - (p[1] >= SSL3_VERSION_MAJOR) && - (p[5] == SSL3_MT_CLIENT_HELLO)) - { - /* This is a fragment of a ClientHello. We look at the - * client_hello to negotiate the version. However, this - * is difficult if we have only a pathologically small - * fragment. No known client fragments ClientHello like - * this, so we simply reject such connections to avoid - * protocol version downgrade attacks. */ - uint16_t record_length = (p[3] << 8) | p[4]; - uint16_t client_version, version; - if (record_length < 6) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_RECORD_TOO_SMALL); - goto err; - } - - client_version = (p[9] << 8) | p[10]; - version = ssl3_get_mutual_version(s, client_version); - if (version == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - s->version = version; - - /* Reset the record-layer state for SSL3. */ - assert(s->rstate == SSL_ST_READ_HEADER); - s->s3->rbuf.left = s->packet_length; - s->s3->rbuf.offset = 0; - s->packet_length = 0; - - /* Ready to switch versions. */ - s->state = SSL23_ST_SR_SWITCH_VERSION; - } - else - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - - return 1; -err: - return -1; - } - -static int ssl23_get_v2_client_hello(SSL *s) - { - uint8_t *p; - size_t rand_len; - int n = 0; - - CBS v2_client_hello, cipher_specs, session_id, challenge; - size_t msg_length, len; - uint8_t msg_type; - uint16_t version, cipher_spec_length, session_id_length, challenge_length; - CBB client_hello, hello_body, cipher_suites; - uint8_t random[SSL3_RANDOM_SIZE]; - - /* Read the remainder of the V2ClientHello. We have previously read 11 - * bytes in ssl23_get_client_hello. */ - p = s->packet; - msg_length = ((p[0] & 0x7f) << 8) | p[1]; - if (msg_length > (1024 * 4)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE); - goto err; - } - if (msg_length < 11 - 2) - { - /* Reject lengths that are too short early. We have already read - * 11 bytes, so we should not attempt to process an (invalid) - * V2ClientHello which would be shorter than that. */ - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - n = ssl23_read_bytes(s, msg_length + 2); - if (n <= 0) - return n; - assert(n == s->packet_length); - - /* The V2ClientHello without the length is incorporated into the - * Finished hash. */ - ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); - if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ - - CBS_init(&v2_client_hello, s->packet + 2, s->packet_length - 2); - if (!CBS_get_u8(&v2_client_hello, &msg_type) || - !CBS_get_u16(&v2_client_hello, &version) || - !CBS_get_u16(&v2_client_hello, &cipher_spec_length) || - !CBS_get_u16(&v2_client_hello, &session_id_length) || - !CBS_get_u16(&v2_client_hello, &challenge_length) || - !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) || - !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || - !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || - CBS_len(&v2_client_hello) != 0) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_DECODE_ERROR); - goto err; - } - - /* msg_type has already been checked. */ - assert(msg_type == SSL2_MT_CLIENT_HELLO); - - /* The client_random is the V2ClientHello challenge. Truncate or - * left-pad with zeros as needed. */ - memset(random, 0, SSL3_RANDOM_SIZE); - rand_len = CBS_len(&challenge); - if (rand_len > SSL3_RANDOM_SIZE) - rand_len = SSL3_RANDOM_SIZE; - memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge), rand_len); - - /* Write out an equivalent SSLv3 ClientHello. */ - if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data, s->init_buf->max)) - { - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) || - !CBB_add_u24_length_prefixed(&client_hello, &hello_body) || - !CBB_add_u16(&hello_body, version) || - !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || - /* No session id. */ - !CBB_add_u8(&hello_body, 0) || - !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) - { - CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* Copy the cipher suites. */ - while (CBS_len(&cipher_specs) > 0) - { - uint32_t cipher_spec; - if (!CBS_get_u24(&cipher_specs, &cipher_spec)) - { - CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_DECODE_ERROR); - goto err; - } - - /* Skip SSLv2 ciphers. */ - if ((cipher_spec & 0xff0000) != 0) - continue; - if (!CBB_add_u16(&cipher_suites, cipher_spec)) - { - CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - /* Add the null compression scheme and finish. */ - if (!CBB_add_u8(&hello_body, 1) || - !CBB_add_u8(&hello_body, 0) || - !CBB_finish(&client_hello, NULL, &len)) - { - CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* Mark the message for "re"-use by the version-specific - * method. */ - s->s3->tmp.reuse_message = 1; - s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; - /* The handshake message header is 4 bytes. */ - s->s3->tmp.message_size = len - 4; - - /* Reset the record layer for SSL3. */ - assert(s->rstate == SSL_ST_READ_HEADER); - s->packet_length = 0; - s->s3->rbuf.left = 0; - s->s3->rbuf.offset = 0; - - s->state = SSL23_ST_SR_SWITCH_VERSION; - return 1; -err: - return -1; - } diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 7495ea68..d05518d7 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -732,3 +732,24 @@ int ssl3_release_read_buffer(SSL *s) return 1; } +/* Fill a ClientRandom or ServerRandom field of length len. Returns 0 + * on failure, 1 on success. */ +int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) + { + int send_time = 0; + if (len < 4) + return 0; + if (server) + send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; + else + send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; + if (send_time) + { + unsigned long Time = (unsigned long)time(NULL); + unsigned char *p = result; + l2n(Time, p); + return RAND_bytes(p, len-4); + } + else + return RAND_bytes(result, len); + } diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9eca4921..7de51593 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -590,7 +590,7 @@ int ssl3_send_client_hello(SSL *s) buf=(unsigned char *)s->init_buf->data; if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { - if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION) + if (!s->s3->have_version) { uint16_t max_version = ssl3_get_max_client_version(s); /* Disabling all versions is silly: return an error. */ @@ -771,7 +771,7 @@ int ssl3_get_server_hello(SSL *s) goto f_err; } - if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION) + if (!s->s3->have_version) { if (!ssl3_is_version_enabled(s, server_version)) { @@ -783,6 +783,10 @@ int ssl3_get_server_hello(SSL *s) s->version = server_version; s->enc_method = ssl3_get_enc_method(server_version); assert(s->enc_method != NULL); + /* At this point, the connection's version is known and + * s->version is fixed. Begin enforcing the record-layer + * version. */ + s->s3->have_version = 1; } else if (server_version != s->version) { @@ -792,12 +796,6 @@ int ssl3_get_server_hello(SSL *s) goto f_err; } - /* At this point, the connection's version is known and s->version is - * fixed. Begin enforcing the record-layer version. Note: SSLv23_method - * currently determines its version sooner, but it will later be moved - * to this point. */ - s->s3->have_version = 1; - /* Copy over the server random. */ memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index f4d47759..ad63e636 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1119,7 +1119,7 @@ void ssl3_clear(SSL *s) s->s3->total_renegotiations=0; s->s3->num_renegotiations=0; s->s3->in_read_app_data=0; - s->version = s->method->version; + s->version = TLS1_2_VERSION; if (s->next_proto_negotiated) { diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c index 2bf4dd21..2ab1cf79 100644 --- a/ssl/s3_meth.c +++ b/ssl/s3_meth.c @@ -54,54 +54,119 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ - #include "ssl_locl.h" -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method) +static const SSL_PROTOCOL_METHOD TLS_protocol_method = { + ssl3_new, + ssl3_clear, + ssl3_free, + ssl3_accept, + ssl3_connect, + ssl3_read, + ssl3_peek, + ssl3_write, + ssl3_shutdown, + ssl3_renegotiate, + ssl3_renegotiate_check, + ssl3_get_message, + ssl3_read_bytes, + ssl3_write_bytes, + ssl3_dispatch_alert, + ssl3_ctrl, + ssl3_ctx_ctrl, + ssl3_pending, + ssl3_num_ciphers, + ssl3_get_cipher, + ssl_undefined_void_function, + ssl3_callback_ctrl, + ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD *TLS_method(void) { + static const SSL_METHOD method = { + 0, + &TLS_protocol_method, + }; + return &method; +} + +const SSL_METHOD *SSLv23_method(void) { + return TLS_method(); +} + +/* Legacy version-locked methods. */ + +const SSL_METHOD *TLSv1_2_method(void) { + static const SSL_METHOD method = { + TLS1_2_VERSION, + &TLS_protocol_method, + }; + return &method; +} + +const SSL_METHOD *TLSv1_1_method(void) { + static const SSL_METHOD method = { + TLS1_1_VERSION, + &TLS_protocol_method, + }; + return &method; +} + +const SSL_METHOD *TLSv1_method(void) { + static const SSL_METHOD method = { + TLS1_VERSION, + &TLS_protocol_method, + }; + return &method; +} + +const SSL_METHOD *SSLv3_method(void) { + static const SSL_METHOD method = { + SSL3_VERSION, + &TLS_protocol_method, + }; + return &method; +} -IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method) +/* Legacy side-specific methods. */ -IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method) +const SSL_METHOD *TLSv1_2_server_method(void) { + return TLSv1_2_method(); +} -IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method) +const SSL_METHOD *TLSv1_1_server_method(void) { + return TLSv1_1_method(); +} -const SSL_METHOD *TLSv1_2_server_method(void) - { - return TLSv1_2_method(); - } +const SSL_METHOD *TLSv1_server_method(void) { + return TLSv1_method(); +} -const SSL_METHOD *TLSv1_1_server_method(void) - { - return TLSv1_1_method(); - } +const SSL_METHOD *SSLv3_server_method(void) { + return SSLv3_method(); +} -const SSL_METHOD *TLSv1_server_method(void) - { - return TLSv1_method(); - } +const SSL_METHOD *TLSv1_2_client_method(void) { + return TLSv1_2_method(); +} -const SSL_METHOD *SSLv3_server_method(void) - { - return SSLv3_method(); - } +const SSL_METHOD *TLSv1_1_client_method(void) { + return TLSv1_1_method(); +} -const SSL_METHOD *TLSv1_2_client_method(void) - { - return TLSv1_2_method(); - } +const SSL_METHOD *TLSv1_client_method(void) { + return TLSv1_method(); +} -const SSL_METHOD *TLSv1_1_client_method(void) - { - return TLSv1_1_method(); - } +const SSL_METHOD *SSLv3_client_method(void) { + return SSLv3_method(); +} -const SSL_METHOD *TLSv1_client_method(void) - { - return TLSv1_method(); - } +const SSL_METHOD *SSLv23_server_method(void) { + return SSLv23_method(); +} -const SSL_METHOD *SSLv3_client_method(void) - { - return SSLv3_method(); - } +const SSL_METHOD *SSLv23_client_method(void) { + return SSLv23_method(); +} diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index b320140f..eaeb2b26 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -1123,7 +1123,7 @@ int ssl3_get_client_hello(SSL *s) } } - if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION) + if (!s->s3->have_version) { /* Select version to use */ uint16_t version = ssl3_get_mutual_version(s, client_version); @@ -1137,6 +1137,10 @@ int ssl3_get_client_hello(SSL *s) s->version = version; s->enc_method = ssl3_get_enc_method(version); assert(s->enc_method != NULL); + /* At this point, the connection's version is known and + * s->version is fixed. Begin enforcing the record-layer + * version. */ + s->s3->have_version = 1; } else if (SSL_IS_DTLS(s) ? (s->client_version > s->version) : (s->client_version < s->version)) @@ -1152,12 +1156,6 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } - /* At this point, the connection's version is known and s->version is - * fixed. Begin enforcing the record-layer version. Note: SSLv23_method - * currently determines its version sooner, but it will later be moved - * to this point. */ - s->s3->have_version = 1; - s->hit=0; /* Versions before 0.9.7 always allow clients to resume sessions in renegotiation. * 0.9.7 and later allow this by default, but optionally ignore resumption requests diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index a55b1e78..37c7e433 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -418,7 +418,7 @@ static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, *head=curr; } -static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, +static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method, int num_of_ciphers, CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) @@ -991,7 +991,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, } -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method, struct ssl_cipher_preference_list_st **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, const char *rule_str, CERT *c) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 574b85f8..47c91fcd 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -205,8 +205,6 @@ int SSL_clear(SSL *s) assert(s->state == 0); } - s->version=s->method->version; - s->client_version=s->version; s->rwstate=SSL_NOTHING; s->rstate=SSL_ST_READ_HEADER; #if 0 @@ -224,6 +222,7 @@ int SSL_clear(SSL *s) ssl_clear_hash_ctx(&s->write_hash); s->method->ssl_clear(s); + s->client_version=s->version; return(1); } @@ -1847,7 +1846,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) memset(ret,0,sizeof(SSL_CTX)); - ret->method=meth; + ret->method = meth->method; ret->cert_store=NULL; ret->session_cache_mode=SSL_SESS_CACHE_SERVER; @@ -1942,6 +1941,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) */ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + /* Lock the SSL_CTX to the specified version, for compatibility with + * legacy uses of SSL_METHOD. */ + if (meth->version != 0) + { + SSL_CTX_set_max_version(ret, meth->version); + SSL_CTX_set_min_version(ret, meth->version); + } + return(ret); err: OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE); @@ -3073,27 +3080,6 @@ int ssl3_can_cutthrough(const SSL *s) return 1; } -const SSL_METHOD *ssl3_get_method(uint16_t version) - { - switch (version) - { - case SSL3_VERSION: - return SSLv3_method(); - case TLS1_VERSION: - return TLSv1_method(); - case TLS1_1_VERSION: - return TLSv1_1_method(); - case TLS1_2_VERSION: - return TLSv1_2_method(); - case DTLS1_VERSION: - return DTLSv1_method(); - case DTLS1_2_VERSION: - return DTLSv1_2_method(); - default: - return NULL; - } - } - const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) { switch (version) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 7ca8e143..afe7c320 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -563,6 +563,48 @@ enum should_add_to_finished_hash { dont_add_to_finished_hash, }; +/* SSL_METHOD is a compatibility structure to support the legacy + * version-locked methods. */ +struct ssl_method_st + { + /* version, if non-zero, is the only protocol version acceptable to an + * SSL_CTX initialized from this method. */ + uint16_t version; + /* method is the underlying SSL_PROTOCOL_METHOD that initializes the + * SSL_CTX. */ + const SSL_PROTOCOL_METHOD *method; + }; + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +struct ssl_protocol_method_st + { + int (*ssl_new)(SSL *s); + void (*ssl_clear)(SSL *s); + void (*ssl_free)(SSL *s); + int (*ssl_accept)(SSL *s); + int (*ssl_connect)(SSL *s); + int (*ssl_read)(SSL *s,void *buf,int len); + int (*ssl_peek)(SSL *s,void *buf,int len); + int (*ssl_write)(SSL *s,const void *buf,int len); + int (*ssl_shutdown)(SSL *s); + int (*ssl_renegotiate)(SSL *s); + int (*ssl_renegotiate_check)(SSL *s); + long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long + max, int hash_message, int *ok); + int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert)(SSL *s); + long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg); + long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg); + int (*ssl_pending)(const SSL *s); + int (*num_ciphers)(void); + const SSL_CIPHER *(*get_cipher)(unsigned ncipher); + int (*ssl_version)(void); + long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void)); + long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void)); + }; + /* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff * It is a bit of a mess of functions, but hell, think of it as * an opaque structure :-) */ @@ -636,7 +678,6 @@ struct ssl_aead_ctx_st extern const SSL_CIPHER ssl3_ciphers[]; - extern const SSL3_ENC_METHOD TLSv1_enc_data; extern const SSL3_ENC_METHOD TLSv1_1_enc_data; extern const SSL3_ENC_METHOD TLSv1_2_enc_data; @@ -644,102 +685,6 @@ extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SSL3_ENC_METHOD DTLSv1_enc_data; extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; -#define IMPLEMENT_tls_meth_func(version, func_name) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - ssl3_new, \ - ssl3_clear, \ - ssl3_free, \ - ssl3_accept, \ - ssl3_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - ssl3_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -#define IMPLEMENT_ssl23_meth_func(func_name) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - TLS1_2_VERSION, \ - ssl3_new, \ - ssl3_clear, \ - ssl3_free, \ - ssl23_accept, \ - ssl23_connect, \ - ssl23_read, \ - ssl23_peek, \ - ssl23_write, \ - ssl_undefined_function, \ - ssl_undefined_function, \ - ssl_ok, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl_undefined_const_function, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -#define IMPLEMENT_dtls1_meth_func(version, func_name) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - dtls1_new, \ - dtls1_clear, \ - dtls1_free, \ - dtls1_accept, \ - dtls1_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - dtls1_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - dtls1_get_message, \ - dtls1_read_bytes, \ - dtls1_write_app_data_bytes, \ - dtls1_dispatch_alert, \ - dtls1_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - dtls1_get_cipher, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - void ssl_clear_cipher_ctx(SSL *s); int ssl_clear_bad_session(SSL *s); CERT *ssl_cert_new(void); @@ -755,7 +700,7 @@ int ssl_cipher_id_cmp(const void *in_a, const void *in_b); int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp); STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs); int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p); -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *meth, struct ssl_cipher_preference_list_st **pref, STACK_OF(SSL_CIPHER) **sorted, const char *rule_str, CERT *c); @@ -886,10 +831,6 @@ void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len); int ssl3_handshake_write(SSL *s, enum should_add_to_finished_hash should_add_to_finished_hash); void ssl3_add_to_finished_hash(SSL *s); -int ssl23_read(SSL *s, void *buf, int len); -int ssl23_peek(SSL *s, void *buf, int len); -int ssl23_write(SSL *s, const void *buf, int len); - int dtls1_do_write(SSL *s,int type, enum should_add_to_finished_hash should_add_to_finished_hash); int ssl3_read_n(SSL *s, int n, int max, int extend); int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); @@ -959,11 +900,6 @@ int ssl3_get_cert_verify(SSL *s); int ssl3_get_next_proto(SSL *s); int ssl3_get_channel_id(SSL *s); -int ssl23_accept(SSL *s); -int ssl23_connect(SSL *s); -int ssl23_read_bytes(SSL *s, int n); -int ssl23_write_bytes(SSL *s); - int dtls1_new(SSL *s); int dtls1_accept(SSL *s); int dtls1_connect(SSL *s); @@ -1071,10 +1007,6 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, int ssl3_can_cutthrough(const SSL *s); -/* ssl3_get_method returns the version-locked SSL_METHOD corresponding - * to |version|. */ -const SSL_METHOD *ssl3_get_method(uint16_t version); - /* ssl3_get_enc_method returns the SSL3_ENC_METHOD corresponding to * |version|. */ const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version); diff --git a/ssl/ssl_test.c b/ssl/ssl_test.c index ee836939..70291a29 100644 --- a/ssl/ssl_test.c +++ b/ssl/ssl_test.c @@ -420,12 +420,34 @@ static int test_ssl_session_asn1(const char *input_b64) { return ret; } +int test_default_version(uint16_t version, const SSL_METHOD *(*method)(void)) { + SSL_CTX *ctx; + int ret; + + ctx = SSL_CTX_new(method()); + if (ctx == NULL) { + return 0; + } + + ret = ctx->min_version == version && ctx->max_version == version; + SSL_CTX_free(ctx); + return ret; +} + int main(void) { SSL_library_init(); if (!test_cipher_rules() || !test_ssl_session_asn1(kOpenSSLSession) || - !test_ssl_session_asn1(kCustomSession)) { + !test_ssl_session_asn1(kCustomSession) || + !test_default_version(0, &TLS_method) || + !test_default_version(SSL3_VERSION, &SSLv3_method) || + !test_default_version(TLS1_VERSION, &TLSv1_method) || + !test_default_version(TLS1_1_VERSION, &TLSv1_1_method) || + !test_default_version(TLS1_2_VERSION, &TLSv1_2_method) || + !test_default_version(0, &DTLS_method) || + !test_default_version(DTLS1_VERSION, &DTLSv1_method) || + !test_default_version(DTLS1_2_VERSION, &DTLSv1_2_method)) { return 1; } diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 05f2ecae..af8dc831 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -687,7 +687,7 @@ printf("\nkey block\n"); { int z; for (z=0; zmethod->version <= TLS1_VERSION && + if (!SSL_USE_EXPLICIT_IV(s) && (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) { /* enable vulnerability countermeasure for CBC ciphers with diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 3d78c1cc..6266ad16 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -231,7 +231,7 @@ static SSL_CTX *setup_ctx(const TestConfig *config) { SSL_CTX *ssl_ctx = NULL; DH *dh = NULL; - ssl_ctx = SSL_CTX_new(config->is_dtls ? DTLS_method() : SSLv23_method()); + ssl_ctx = SSL_CTX_new(config->is_dtls ? DTLS_method() : TLS_method()); if (ssl_ctx == NULL) { goto err; } diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index e3bf338a..3cfc92de 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -445,8 +445,7 @@ var testCases = []testCase{ FragmentClientVersion: true, }, }, - shouldFail: true, - expectedError: ":RECORD_TOO_SMALL:", + expectedVersion: VersionTLS12, }, { testType: serverTest,