Przeglądaj źródła

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
kris/onging/CECPQ3_patch15
David Benjamin 10 lat temu
committed by Adam Langley
rodzic
commit
82c9e90a58
22 zmienionych plików z 330 dodań i 1634 usunięć
  1. +0
    -2
      include/openssl/dtls1.h
  2. +44
    -69
      include/openssl/ssl.h
  3. +0
    -5
      ssl/CMakeLists.txt
  4. +1
    -4
      ssl/d1_lib.c
  5. +69
    -27
      ssl/d1_meth.c
  6. +0
    -520
      ssl/s23_clnt.c
  7. +0
    -131
      ssl/s23_lib.c
  8. +0
    -71
      ssl/s23_meth.c
  9. +0
    -117
      ssl/s23_pkt.c
  10. +0
    -493
      ssl/s23_srvr.c
  11. +21
    -0
      ssl/s3_both.c
  12. +6
    -8
      ssl/s3_clnt.c
  13. +1
    -1
      ssl/s3_lib.c
  14. +102
    -37
      ssl/s3_meth.c
  15. +5
    -7
      ssl/s3_srvr.c
  16. +2
    -2
      ssl/ssl_ciph.c
  17. +10
    -24
      ssl/ssl_lib.c
  18. +43
    -111
      ssl/ssl_locl.h
  19. +23
    -1
      ssl/ssl_test.c
  20. +1
    -1
      ssl/t1_enc.c
  21. +1
    -1
      ssl/test/bssl_shim.cc
  22. +1
    -2
      ssl/test/runner/runner.go

+ 0
- 2
include/openssl/dtls1.h Wyświetl plik

@@ -69,8 +69,6 @@ extern "C" {

#define DTLS1_VERSION 0xFEFF
#define DTLS1_2_VERSION 0xFEFD
/* Special value for method supporting multiple versions */
#define DTLS_ANY_VERSION 0x1FFFF

/* lengths of messages */
#define DTLS1_COOKIE_LENGTH 256


+ 44
- 69
include/openssl/ssl.h Wyświetl plik

@@ -277,6 +277,7 @@ extern "C" {
#define SSL_FILETYPE_PEM X509_FILETYPE_PEM

typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_session_st SSL_SESSION;
typedef struct tls_sigalgs_st TLS_SIGALGS;
@@ -318,38 +319,6 @@ struct ssl_cipher_st
int alg_bits; /* Number of bits for algorithm */
};


/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
struct ssl_method_st
{
int version;
int (*ssl_new)(SSL *s);
void (*ssl_clear)(SSL *s);
void (*ssl_free)(SSL *s);
int (*ssl_accept)(SSL *s);
int (*ssl_connect)(SSL *s);
int (*ssl_read)(SSL *s,void *buf,int len);
int (*ssl_peek)(SSL *s,void *buf,int len);
int (*ssl_write)(SSL *s,const void *buf,int len);
int (*ssl_shutdown)(SSL *s);
int (*ssl_renegotiate)(SSL *s);
int (*ssl_renegotiate_check)(SSL *s);
long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
max, int hash_message, int *ok);
int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len,
int peek);
int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
int (*ssl_dispatch_alert)(SSL *s);
long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
int (*ssl_pending)(const SSL *s);
int (*num_ciphers)(void);
const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
int (*ssl_version)(void);
long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
};

/* An SSL_SESSION represents an SSL session that may be resumed in an
* abbreviated handshake. */
struct ssl_session_st
@@ -739,7 +708,7 @@ struct ssl_cipher_preference_list_st

struct ssl_ctx_st
{
const SSL_METHOD *method;
const SSL_PROTOCOL_METHOD *method;

/* max_version is the maximum acceptable protocol version. If
* zero, the maximum supported version, currently (D)TLS 1.2,
@@ -1196,11 +1165,8 @@ struct ssl_st
int version;

/* method is the method table corresponding to the current protocol
* (DTLS or TLS).
*
* TODO(davidben): For now, it also corresponds to the protocol version,
* but that will soon change. */
const SSL_METHOD *method;
* (DTLS or TLS). */
const SSL_PROTOCOL_METHOD *method;

/* enc_method is the method table corresponding to the current protocol
* version. */
@@ -2066,38 +2032,47 @@ OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c);
OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c);
OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c);

OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */

OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */
OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */
OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */

OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */

OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */

OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */


OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */

OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */
/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */
OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);

/* DTLS_method is the SSL_METHOD used for DTLS connections. */
OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);


/* Deprecated methods. */

/* SSLv23_method calls TLS_method. */
OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);

/* Version-specific methods behave exactly like TLS_method and DTLS_method they
* also call SSL_CTX_set_min_version and SSL_CTX_set_max_version to lock
* connections to that protocol version. */
OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);

/* Client- and server-specific methods call their corresponding generic
* methods. */
OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);

OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */
OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */
OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */

OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);



+ 0
- 5
ssl/CMakeLists.txt Wyświetl plik

@@ -13,11 +13,6 @@ add_library(
d1_pkt.c
d1_srtp.c
d1_srvr.c
s23_clnt.c
s23_lib.c
s23_meth.c
s23_pkt.c
s23_srvr.c
s3_both.c
s3_cbc.c
s3_clnt.c


+ 1
- 4
ssl/d1_lib.c Wyświetl plik

@@ -266,10 +266,7 @@ void dtls1_clear(SSL *s)
}

ssl3_clear(s);
if (s->method->version == DTLS_ANY_VERSION)
s->version=DTLS1_2_VERSION;
else
s->version=s->method->version;
s->version = DTLS1_2_VERSION;
}

long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)


+ 69
- 27
ssl/d1_meth.c Wyświetl plik

@@ -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();
}

+ 0
- 520
ssl/s23_clnt.c Wyświetl plik

@@ -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);
}

+ 0
- 131
ssl/s23_lib.c Wyświetl plik

@@ -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);
}
}

+ 0
- 71
ssl/s23_meth.c Wyświetl plik

@@ -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();
}

+ 0
- 117
ssl/s23_pkt.c Wyświetl plik

@@ -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);
}


+ 0
- 493
ssl/s23_srvr.c Wyświetl plik

@@ -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;
}

+ 21
- 0
ssl/s3_both.c Wyświetl plik

@@ -732,3 +732,24 @@ int ssl3_release_read_buffer(SSL *s)
return 1;
}

/* Fill a ClientRandom or ServerRandom field of length len. Returns 0
* on failure, 1 on success. */
int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
{
int send_time = 0;
if (len < 4)
return 0;
if (server)
send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
else
send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
if (send_time)
{
unsigned long Time = (unsigned long)time(NULL);
unsigned char *p = result;
l2n(Time, p);
return RAND_bytes(p, len-4);
}
else
return RAND_bytes(result, len);
}

+ 6
- 8
ssl/s3_clnt.c Wyświetl plik

@@ -590,7 +590,7 @@ int ssl3_send_client_hello(SSL *s)
buf=(unsigned char *)s->init_buf->data;
if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
{
if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION)
if (!s->s3->have_version)
{
uint16_t max_version = ssl3_get_max_client_version(s);
/* Disabling all versions is silly: return an error. */
@@ -771,7 +771,7 @@ int ssl3_get_server_hello(SSL *s)
goto f_err;
}

if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION)
if (!s->s3->have_version)
{
if (!ssl3_is_version_enabled(s, server_version))
{
@@ -783,6 +783,10 @@ int ssl3_get_server_hello(SSL *s)
s->version = server_version;
s->enc_method = ssl3_get_enc_method(server_version);
assert(s->enc_method != NULL);
/* At this point, the connection's version is known and
* s->version is fixed. Begin enforcing the record-layer
* version. */
s->s3->have_version = 1;
}
else if (server_version != s->version)
{
@@ -792,12 +796,6 @@ int ssl3_get_server_hello(SSL *s)
goto f_err;
}

/* At this point, the connection's version is known and s->version is
* fixed. Begin enforcing the record-layer version. Note: SSLv23_method
* currently determines its version sooner, but it will later be moved
* to this point. */
s->s3->have_version = 1;

/* Copy over the server random. */
memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);



+ 1
- 1
ssl/s3_lib.c Wyświetl plik

@@ -1119,7 +1119,7 @@ void ssl3_clear(SSL *s)
s->s3->total_renegotiations=0;
s->s3->num_renegotiations=0;
s->s3->in_read_app_data=0;
s->version = s->method->version;
s->version = TLS1_2_VERSION;

if (s->next_proto_negotiated)
{


+ 102
- 37
ssl/s3_meth.c Wyświetl plik

@@ -54,54 +54,119 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */


#include "ssl_locl.h"


IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method)
static const SSL_PROTOCOL_METHOD TLS_protocol_method = {
ssl3_new,
ssl3_clear,
ssl3_free,
ssl3_accept,
ssl3_connect,
ssl3_read,
ssl3_peek,
ssl3_write,
ssl3_shutdown,
ssl3_renegotiate,
ssl3_renegotiate_check,
ssl3_get_message,
ssl3_read_bytes,
ssl3_write_bytes,
ssl3_dispatch_alert,
ssl3_ctrl,
ssl3_ctx_ctrl,
ssl3_pending,
ssl3_num_ciphers,
ssl3_get_cipher,
ssl_undefined_void_function,
ssl3_callback_ctrl,
ssl3_ctx_callback_ctrl,
};

const SSL_METHOD *TLS_method(void) {
static const SSL_METHOD method = {
0,
&TLS_protocol_method,
};
return &method;
}

const SSL_METHOD *SSLv23_method(void) {
return TLS_method();
}

/* Legacy version-locked methods. */

const SSL_METHOD *TLSv1_2_method(void) {
static const SSL_METHOD method = {
TLS1_2_VERSION,
&TLS_protocol_method,
};
return &method;
}

const SSL_METHOD *TLSv1_1_method(void) {
static const SSL_METHOD method = {
TLS1_1_VERSION,
&TLS_protocol_method,
};
return &method;
}

const SSL_METHOD *TLSv1_method(void) {
static const SSL_METHOD method = {
TLS1_VERSION,
&TLS_protocol_method,
};
return &method;
}

const SSL_METHOD *SSLv3_method(void) {
static const SSL_METHOD method = {
SSL3_VERSION,
&TLS_protocol_method,
};
return &method;
}

IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method)
/* Legacy side-specific methods. */

IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method)
const SSL_METHOD *TLSv1_2_server_method(void) {
return TLSv1_2_method();
}

IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method)
const SSL_METHOD *TLSv1_1_server_method(void) {
return TLSv1_1_method();
}

const SSL_METHOD *TLSv1_2_server_method(void)
{
return TLSv1_2_method();
}
const SSL_METHOD *TLSv1_server_method(void) {
return TLSv1_method();
}

const SSL_METHOD *TLSv1_1_server_method(void)
{
return TLSv1_1_method();
}
const SSL_METHOD *SSLv3_server_method(void) {
return SSLv3_method();
}

const SSL_METHOD *TLSv1_server_method(void)
{
return TLSv1_method();
}
const SSL_METHOD *TLSv1_2_client_method(void) {
return TLSv1_2_method();
}

const SSL_METHOD *SSLv3_server_method(void)
{
return SSLv3_method();
}
const SSL_METHOD *TLSv1_1_client_method(void) {
return TLSv1_1_method();
}

const SSL_METHOD *TLSv1_2_client_method(void)
{
return TLSv1_2_method();
}
const SSL_METHOD *TLSv1_client_method(void) {
return TLSv1_method();
}

const SSL_METHOD *TLSv1_1_client_method(void)
{
return TLSv1_1_method();
}
const SSL_METHOD *SSLv3_client_method(void) {
return SSLv3_method();
}

const SSL_METHOD *TLSv1_client_method(void)
{
return TLSv1_method();
}
const SSL_METHOD *SSLv23_server_method(void) {
return SSLv23_method();
}

const SSL_METHOD *SSLv3_client_method(void)
{
return SSLv3_method();
}
const SSL_METHOD *SSLv23_client_method(void) {
return SSLv23_method();
}

+ 5
- 7
ssl/s3_srvr.c Wyświetl plik

@@ -1123,7 +1123,7 @@ int ssl3_get_client_hello(SSL *s)
}
}

if (!s->s3->have_version && s->method->version == DTLS_ANY_VERSION)
if (!s->s3->have_version)
{
/* Select version to use */
uint16_t version = ssl3_get_mutual_version(s, client_version);
@@ -1137,6 +1137,10 @@ int ssl3_get_client_hello(SSL *s)
s->version = version;
s->enc_method = ssl3_get_enc_method(version);
assert(s->enc_method != NULL);
/* At this point, the connection's version is known and
* s->version is fixed. Begin enforcing the record-layer
* version. */
s->s3->have_version = 1;
}
else if (SSL_IS_DTLS(s) ? (s->client_version > s->version)
: (s->client_version < s->version))
@@ -1152,12 +1156,6 @@ int ssl3_get_client_hello(SSL *s)
goto f_err;
}

/* At this point, the connection's version is known and s->version is
* fixed. Begin enforcing the record-layer version. Note: SSLv23_method
* currently determines its version sooner, but it will later be moved
* to this point. */
s->s3->have_version = 1;

s->hit=0;
/* Versions before 0.9.7 always allow clients to resume sessions in renegotiation.
* 0.9.7 and later allow this by default, but optionally ignore resumption requests


+ 2
- 2
ssl/ssl_ciph.c Wyświetl plik

@@ -418,7 +418,7 @@ static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
*head=curr;
}

static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method,
int num_of_ciphers,
CIPHER_ORDER *co_list,
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
@@ -991,7 +991,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
}


STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
struct ssl_cipher_preference_list_st **cipher_list,
STACK_OF(SSL_CIPHER) **cipher_list_by_id,
const char *rule_str, CERT *c)


+ 10
- 24
ssl/ssl_lib.c Wyświetl plik

@@ -205,8 +205,6 @@ int SSL_clear(SSL *s)
assert(s->state == 0);
}

s->version=s->method->version;
s->client_version=s->version;
s->rwstate=SSL_NOTHING;
s->rstate=SSL_ST_READ_HEADER;
#if 0
@@ -224,6 +222,7 @@ int SSL_clear(SSL *s)
ssl_clear_hash_ctx(&s->write_hash);

s->method->ssl_clear(s);
s->client_version=s->version;
return(1);
}

@@ -1847,7 +1846,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)

memset(ret,0,sizeof(SSL_CTX));

ret->method=meth;
ret->method = meth->method;

ret->cert_store=NULL;
ret->session_cache_mode=SSL_SESS_CACHE_SERVER;
@@ -1942,6 +1941,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
*/
ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;

/* Lock the SSL_CTX to the specified version, for compatibility with
* legacy uses of SSL_METHOD. */
if (meth->version != 0)
{
SSL_CTX_set_max_version(ret, meth->version);
SSL_CTX_set_min_version(ret, meth->version);
}

return(ret);
err:
OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
@@ -3073,27 +3080,6 @@ int ssl3_can_cutthrough(const SSL *s)
return 1;
}

const SSL_METHOD *ssl3_get_method(uint16_t version)
{
switch (version)
{
case SSL3_VERSION:
return SSLv3_method();
case TLS1_VERSION:
return TLSv1_method();
case TLS1_1_VERSION:
return TLSv1_1_method();
case TLS1_2_VERSION:
return TLSv1_2_method();
case DTLS1_VERSION:
return DTLSv1_method();
case DTLS1_2_VERSION:
return DTLSv1_2_method();
default:
return NULL;
}
}

const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version)
{
switch (version)


+ 43
- 111
ssl/ssl_locl.h Wyświetl plik

@@ -563,6 +563,48 @@ enum should_add_to_finished_hash {
dont_add_to_finished_hash,
};

/* SSL_METHOD is a compatibility structure to support the legacy
* version-locked methods. */
struct ssl_method_st
{
/* version, if non-zero, is the only protocol version acceptable to an
* SSL_CTX initialized from this method. */
uint16_t version;
/* method is the underlying SSL_PROTOCOL_METHOD that initializes the
* SSL_CTX. */
const SSL_PROTOCOL_METHOD *method;
};

/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
struct ssl_protocol_method_st
{
int (*ssl_new)(SSL *s);
void (*ssl_clear)(SSL *s);
void (*ssl_free)(SSL *s);
int (*ssl_accept)(SSL *s);
int (*ssl_connect)(SSL *s);
int (*ssl_read)(SSL *s,void *buf,int len);
int (*ssl_peek)(SSL *s,void *buf,int len);
int (*ssl_write)(SSL *s,const void *buf,int len);
int (*ssl_shutdown)(SSL *s);
int (*ssl_renegotiate)(SSL *s);
int (*ssl_renegotiate_check)(SSL *s);
long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
max, int hash_message, int *ok);
int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len,
int peek);
int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
int (*ssl_dispatch_alert)(SSL *s);
long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
int (*ssl_pending)(const SSL *s);
int (*num_ciphers)(void);
const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
int (*ssl_version)(void);
long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
};

/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff
* It is a bit of a mess of functions, but hell, think of it as
* an opaque structure :-) */
@@ -636,7 +678,6 @@ struct ssl_aead_ctx_st

extern const SSL_CIPHER ssl3_ciphers[];


extern const SSL3_ENC_METHOD TLSv1_enc_data;
extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
extern const SSL3_ENC_METHOD TLSv1_2_enc_data;
@@ -644,102 +685,6 @@ extern const SSL3_ENC_METHOD SSLv3_enc_data;
extern const SSL3_ENC_METHOD DTLSv1_enc_data;
extern const SSL3_ENC_METHOD DTLSv1_2_enc_data;

#define IMPLEMENT_tls_meth_func(version, func_name) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
version, \
ssl3_new, \
ssl3_clear, \
ssl3_free, \
ssl3_accept, \
ssl3_connect, \
ssl3_read, \
ssl3_peek, \
ssl3_write, \
ssl3_shutdown, \
ssl3_renegotiate, \
ssl3_renegotiate_check, \
ssl3_get_message, \
ssl3_read_bytes, \
ssl3_write_bytes, \
ssl3_dispatch_alert, \
ssl3_ctrl, \
ssl3_ctx_ctrl, \
ssl3_pending, \
ssl3_num_ciphers, \
ssl3_get_cipher, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \
ssl3_ctx_callback_ctrl, \
}; \
return &func_name##_data; \
}

#define IMPLEMENT_ssl23_meth_func(func_name) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
TLS1_2_VERSION, \
ssl3_new, \
ssl3_clear, \
ssl3_free, \
ssl23_accept, \
ssl23_connect, \
ssl23_read, \
ssl23_peek, \
ssl23_write, \
ssl_undefined_function, \
ssl_undefined_function, \
ssl_ok, \
ssl3_get_message, \
ssl3_read_bytes, \
ssl3_write_bytes, \
ssl3_dispatch_alert, \
ssl3_ctrl, \
ssl3_ctx_ctrl, \
ssl_undefined_const_function, \
ssl3_num_ciphers, \
ssl3_get_cipher, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \
ssl3_ctx_callback_ctrl, \
}; \
return &func_name##_data; \
}

#define IMPLEMENT_dtls1_meth_func(version, func_name) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
version, \
dtls1_new, \
dtls1_clear, \
dtls1_free, \
dtls1_accept, \
dtls1_connect, \
ssl3_read, \
ssl3_peek, \
ssl3_write, \
dtls1_shutdown, \
ssl3_renegotiate, \
ssl3_renegotiate_check, \
dtls1_get_message, \
dtls1_read_bytes, \
dtls1_write_app_data_bytes, \
dtls1_dispatch_alert, \
dtls1_ctrl, \
ssl3_ctx_ctrl, \
ssl3_pending, \
ssl3_num_ciphers, \
dtls1_get_cipher, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \
ssl3_ctx_callback_ctrl, \
}; \
return &func_name##_data; \
}

void ssl_clear_cipher_ctx(SSL *s);
int ssl_clear_bad_session(SSL *s);
CERT *ssl_cert_new(void);
@@ -755,7 +700,7 @@ int ssl_cipher_id_cmp(const void *in_a, const void *in_b);
int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp);
STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p);
STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *meth,
struct ssl_cipher_preference_list_st **pref,
STACK_OF(SSL_CIPHER) **sorted,
const char *rule_str, CERT *c);
@@ -886,10 +831,6 @@ void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
int ssl3_handshake_write(SSL *s, enum should_add_to_finished_hash should_add_to_finished_hash);
void ssl3_add_to_finished_hash(SSL *s);

int ssl23_read(SSL *s, void *buf, int len);
int ssl23_peek(SSL *s, void *buf, int len);
int ssl23_write(SSL *s, const void *buf, int len);

int dtls1_do_write(SSL *s,int type, enum should_add_to_finished_hash should_add_to_finished_hash);
int ssl3_read_n(SSL *s, int n, int max, int extend);
int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
@@ -959,11 +900,6 @@ int ssl3_get_cert_verify(SSL *s);
int ssl3_get_next_proto(SSL *s);
int ssl3_get_channel_id(SSL *s);

int ssl23_accept(SSL *s);
int ssl23_connect(SSL *s);
int ssl23_read_bytes(SSL *s, int n);
int ssl23_write_bytes(SSL *s);

int dtls1_new(SSL *s);
int dtls1_accept(SSL *s);
int dtls1_connect(SSL *s);
@@ -1071,10 +1007,6 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx,

int ssl3_can_cutthrough(const SSL *s);

/* ssl3_get_method returns the version-locked SSL_METHOD corresponding
* to |version|. */
const SSL_METHOD *ssl3_get_method(uint16_t version);

/* ssl3_get_enc_method returns the SSL3_ENC_METHOD corresponding to
* |version|. */
const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version);


+ 23
- 1
ssl/ssl_test.c Wyświetl plik

@@ -420,12 +420,34 @@ static int test_ssl_session_asn1(const char *input_b64) {
return ret;
}

int test_default_version(uint16_t version, const SSL_METHOD *(*method)(void)) {
SSL_CTX *ctx;
int ret;

ctx = SSL_CTX_new(method());
if (ctx == NULL) {
return 0;
}

ret = ctx->min_version == version && ctx->max_version == version;
SSL_CTX_free(ctx);
return ret;
}

int main(void) {
SSL_library_init();

if (!test_cipher_rules() ||
!test_ssl_session_asn1(kOpenSSLSession) ||
!test_ssl_session_asn1(kCustomSession)) {
!test_ssl_session_asn1(kCustomSession) ||
!test_default_version(0, &TLS_method) ||
!test_default_version(SSL3_VERSION, &SSLv3_method) ||
!test_default_version(TLS1_VERSION, &TLSv1_method) ||
!test_default_version(TLS1_1_VERSION, &TLSv1_1_method) ||
!test_default_version(TLS1_2_VERSION, &TLSv1_2_method) ||
!test_default_version(0, &DTLS_method) ||
!test_default_version(DTLS1_VERSION, &DTLSv1_method) ||
!test_default_version(DTLS1_2_VERSION, &DTLSv1_2_method)) {
return 1;
}



+ 1
- 1
ssl/t1_enc.c Wyświetl plik

@@ -687,7 +687,7 @@ printf("\nkey block\n");
{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
#endif

if (s->method->version <= TLS1_VERSION &&
if (!SSL_USE_EXPLICIT_IV(s) &&
(s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0)
{
/* enable vulnerability countermeasure for CBC ciphers with


+ 1
- 1
ssl/test/bssl_shim.cc Wyświetl plik

@@ -231,7 +231,7 @@ static SSL_CTX *setup_ctx(const TestConfig *config) {
SSL_CTX *ssl_ctx = NULL;
DH *dh = NULL;

ssl_ctx = SSL_CTX_new(config->is_dtls ? DTLS_method() : SSLv23_method());
ssl_ctx = SSL_CTX_new(config->is_dtls ? DTLS_method() : TLS_method());
if (ssl_ctx == NULL) {
goto err;
}


+ 1
- 2
ssl/test/runner/runner.go Wyświetl plik

@@ -445,8 +445,7 @@ var testCases = []testCase{
FragmentClientVersion: true,
},
},
shouldFail: true,
expectedError: ":RECORD_TOO_SMALL:",
expectedVersion: VersionTLS12,
},
{
testType: serverTest,


Ładowanie…
Anuluj
Zapisz