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,