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: I8b3df2b427ae34c44ecf972f466ad64dc3dbb171kris/onging/CECPQ3_patch15
@@ -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 | |||
@@ -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); | |||
@@ -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 | |||
@@ -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) | |||
@@ -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(); | |||
} |
@@ -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 <assert.h> | |||
#include <stdio.h> | |||
#include <openssl/buf.h> | |||
#include <openssl/err.h> | |||
#include <openssl/evp.h> | |||
#include <openssl/obj.h> | |||
#include <openssl/rand.h> | |||
#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); | |||
} |
@@ -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 <stdio.h> | |||
#include <openssl/err.h> | |||
#include <openssl/obj.h> | |||
#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); | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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 <stdio.h> | |||
#include <errno.h> | |||
#include <openssl/buf.h> | |||
#include <openssl/evp.h> | |||
#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); | |||
} | |||
@@ -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 <assert.h> | |||
#include <stdio.h> | |||
#include <openssl/buf.h> | |||
#include <openssl/err.h> | |||
#include <openssl/evp.h> | |||
#include <openssl/mem.h> | |||
#include <openssl/obj.h> | |||
#include <openssl/rand.h> | |||
#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; | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
@@ -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) | |||
{ | |||
@@ -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(); | |||
} |
@@ -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 | |||
@@ -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) | |||
@@ -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) | |||
@@ -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); | |||
@@ -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; | |||
} | |||
@@ -687,7 +687,7 @@ printf("\nkey block\n"); | |||
{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } | |||
#endif | |||
if (s->method->version <= TLS1_VERSION && | |||
if (!SSL_USE_EXPLICIT_IV(s) && | |||
(s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) | |||
{ | |||
/* enable vulnerability countermeasure for CBC ciphers with | |||
@@ -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; | |||
} | |||
@@ -445,8 +445,7 @@ var testCases = []testCase{ | |||
FragmentClientVersion: true, | |||
}, | |||
}, | |||
shouldFail: true, | |||
expectedError: ":RECORD_TOO_SMALL:", | |||
expectedVersion: VersionTLS12, | |||
}, | |||
{ | |||
testType: serverTest, | |||