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
diff --git a/include/openssl/dtls1.h b/include/openssl/dtls1.h
index ac097ce..d3a3b55 100644
--- a/include/openssl/dtls1.h
+++ b/include/openssl/dtls1.h
@@ -69,8 +69,6 @@
 
 #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 e5d7a51..e4469e8 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -277,6 +277,7 @@
 #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 @@
 	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_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 @@
 	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_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 */
+/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */
+OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
 
-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 */
+/* DTLS_method is the SSL_METHOD used for DTLS connections. */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
 
 
-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 */
+/* Deprecated methods. */
 
-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 */
+/* SSLv23_method calls TLS_method. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_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 */
+/* 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 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt
index b47b261..3852d20 100644
--- a/ssl/CMakeLists.txt
+++ b/ssl/CMakeLists.txt
@@ -13,11 +13,6 @@
 	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 3f43bf2..8fb9e5d 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -266,10 +266,7 @@
 		}
 
 	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 5e30251..eed0402 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 8ff3087..0000000
--- 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 <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);
-	}
diff --git a/ssl/s23_lib.c b/ssl/s23_lib.c
deleted file mode 100644
index 36f3ef1..0000000
--- 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 <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);
-		}
-	}
diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c
deleted file mode 100644
index d019c54..0000000
--- 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 796dcb3..0000000
--- 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 <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);
-	}
-
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
deleted file mode 100644
index 2aaf413..0000000
--- 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 <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;
-	}
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 7495ea6..d05518d 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -732,3 +732,24 @@
 	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 9eca492..7de5159 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -590,7 +590,7 @@
 	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 @@
 		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 @@
 		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 @@
 		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 f4d4775..ad63e63 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1119,7 +1119,7 @@
 	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 2bf4dd2..2ab1cf7 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,
+};
 
-IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method)
+const SSL_METHOD *TLS_method(void) {
+  static const SSL_METHOD method = {
+      0,
+      &TLS_protocol_method,
+  };
+  return &method;
+}
 
-IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method)
+const SSL_METHOD *SSLv23_method(void) {
+  return TLS_method();
+}
 
-IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method)
+/* Legacy version-locked methods. */
 
-const SSL_METHOD *TLSv1_2_server_method(void)
-	{
-	return TLSv1_2_method();
-	}
+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_server_method(void)
-	{
-	return TLSv1_1_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_server_method(void)
-	{
-	return TLSv1_method();
-	}
+const SSL_METHOD *TLSv1_method(void) {
+  static const SSL_METHOD method = {
+      TLS1_VERSION,
+      &TLS_protocol_method,
+  };
+  return &method;
+}
 
-const SSL_METHOD *SSLv3_server_method(void)
-	{
-	return SSLv3_method();
-	}
+const SSL_METHOD *SSLv3_method(void) {
+  static const SSL_METHOD method = {
+      SSL3_VERSION,
+      &TLS_protocol_method,
+  };
+  return &method;
+}
 
-const SSL_METHOD *TLSv1_2_client_method(void)
-	{
-	return TLSv1_2_method();
-	}
+/* Legacy side-specific methods. */
 
-const SSL_METHOD *TLSv1_1_client_method(void)
-	{
-	return TLSv1_1_method();
-	}
+const SSL_METHOD *TLSv1_2_server_method(void) {
+  return TLSv1_2_method();
+}
 
-const SSL_METHOD *TLSv1_client_method(void)
-	{
-	return TLSv1_method();
-	}
+const SSL_METHOD *TLSv1_1_server_method(void) {
+  return TLSv1_1_method();
+}
 
-const SSL_METHOD *SSLv3_client_method(void)
-	{
-	return SSLv3_method();
-	}
+const SSL_METHOD *TLSv1_server_method(void) {
+  return TLSv1_method();
+}
+
+const SSL_METHOD *SSLv3_server_method(void) {
+  return SSLv3_method();
+}
+
+const SSL_METHOD *TLSv1_2_client_method(void) {
+  return TLSv1_2_method();
+}
+
+const SSL_METHOD *TLSv1_1_client_method(void) {
+  return TLSv1_1_method();
+}
+
+const SSL_METHOD *TLSv1_client_method(void) {
+  return TLSv1_method();
+}
+
+const SSL_METHOD *SSLv3_client_method(void) {
+  return SSLv3_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/s3_srvr.c b/ssl/s3_srvr.c
index b320140..eaeb2b2 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1123,7 +1123,7 @@
 			}
 		}
 
-	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 @@
 		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 @@
 		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 a55b1e7..37c7e43 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -418,7 +418,7 @@
 	*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 @@
 	}
 
 
-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 574b85f..47c91fc 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -205,8 +205,6 @@
 		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 @@
 	ssl_clear_hash_ctx(&s->write_hash);
 
 	s->method->ssl_clear(s);
+	s->client_version=s->version;
 	return(1);
 	}
 
@@ -1847,7 +1846,7 @@
 
 	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 @@
 	 */
 	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 @@
 	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 7ca8e14..afe7c32 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -563,6 +563,48 @@
   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 @@
 
 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 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_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 @@
 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_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 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 ee83693..70291a2 100644
--- a/ssl/ssl_test.c
+++ b/ssl/ssl_test.c
@@ -420,12 +420,34 @@
   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 05f2eca..af8dc83 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -687,7 +687,7 @@
 { 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
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 3d78c1c..6266ad1 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -231,7 +231,7 @@
   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 e3bf338..3cfc92d 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -445,8 +445,7 @@
 				FragmentClientVersion:    true,
 			},
 		},
-		shouldFail:    true,
-		expectedError: ":RECORD_TOO_SMALL:",
+		expectedVersion: VersionTLS12,
 	},
 	{
 		testType: serverTest,