Remove method swap in SSL_set_session.

This is a bit of cleanup that probably should have been done at the same time
as 30ddb434bf.

For now, version negotiation is implemented with a method swap. It also
performs this swap on SSL_set_session, but this was neutered in
30ddb434bf. Rather than hackishly neuter it,
remove it outright.  In addition, remove SSL_set_ssl_method. Now all method
swaps are internal: SSLv23_method switch to a version-specific method and
SSL_clear undoing it.

Note that this does change behavior: if an SSL* is created with one
version-specific method and we SSL_set_session to a session from a /different/
version, we would switch to the /other/ version-specific method. This is
extremely confusing, so it's unlikely anyone was actually expecting it.
Version-specific methods in general don't work well.

Change-Id: I72a5c1f321ca9aeb1b52ebe0317072950ba25092
Reviewed-on: https://boringssl-review.googlesource.com/2390
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2014-11-22 14:32:53 -05:00 committed by Adam Langley
parent 61f95277d4
commit 0f1e64bf7f
13 changed files with 21 additions and 237 deletions

View File

@ -348,7 +348,6 @@ struct ssl_method_st
int (*ssl_pending)(const SSL *s);
int (*num_ciphers)(void);
const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
const struct ssl_method_st *(*get_ssl_method)(int version);
struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
int (*ssl_version)(void);
long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
@ -2074,7 +2073,6 @@ OPENSSL_EXPORT int SSL_shutdown(SSL *s);
OPENSSL_EXPORT const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
OPENSSL_EXPORT const SSL_METHOD *SSL_get_ssl_method(SSL *s);
OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);

View File

@ -125,38 +125,24 @@
#include "ssl_locl.h"
static const SSL_METHOD *dtls1_get_client_method(int ver);
static int dtls1_get_hello_verify(SSL *s);
static const SSL_METHOD *dtls1_get_client_method(int ver)
{
if (ver == DTLS1_VERSION)
return(DTLSv1_client_method());
else if (ver == DTLS1_2_VERSION)
return(DTLSv1_2_client_method());
else
return(NULL);
}
IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
DTLSv1_client_method,
ssl_undefined_function,
dtls1_connect,
dtls1_get_client_method,
DTLSv1_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
DTLSv1_2_client_method,
ssl_undefined_function,
dtls1_connect,
dtls1_get_client_method,
DTLSv1_2_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
DTLS_client_method,
ssl_undefined_function,
dtls1_connect,
dtls1_get_client_method,
DTLSv1_2_enc_data)
int dtls1_connect(SSL *s)

View File

@ -55,41 +55,23 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#include <stdio.h>
#include <openssl/obj.h>
#include "ssl_locl.h"
static const SSL_METHOD *dtls1_get_method(int ver);
static const SSL_METHOD *dtls1_get_method(int ver)
{
if (ver == DTLS1_VERSION)
return(DTLSv1_method());
else if (ver == DTLS1_2_VERSION)
return(DTLSv1_2_method());
else
return(NULL);
}
IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
DTLSv1_method,
dtls1_accept,
dtls1_connect,
dtls1_get_method,
DTLSv1_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
DTLSv1_2_method,
dtls1_accept,
dtls1_connect,
dtls1_get_method,
DTLSv1_2_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
DTLS_method,
dtls1_accept,
dtls1_connect,
dtls1_get_method,
DTLSv1_2_enc_data)

View File

@ -125,38 +125,24 @@
#include "ssl_locl.h"
static const SSL_METHOD *dtls1_get_server_method(int ver);
static int dtls1_send_hello_verify_request(SSL *s);
static const SSL_METHOD *dtls1_get_server_method(int ver)
{
if (ver == DTLS1_VERSION)
return(DTLSv1_server_method());
else if (ver == DTLS1_2_VERSION)
return(DTLSv1_2_server_method());
else
return(NULL);
}
IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
DTLSv1_server_method,
dtls1_accept,
ssl_undefined_function,
dtls1_get_server_method,
DTLSv1_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
DTLSv1_2_server_method,
dtls1_accept,
ssl_undefined_function,
dtls1_get_server_method,
DTLSv1_2_enc_data)
IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
DTLS_server_method,
dtls1_accept,
ssl_undefined_function,
dtls1_get_server_method,
DTLSv1_2_enc_data)
int dtls1_accept(SSL *s)

View File

@ -116,24 +116,12 @@
#include "ssl_locl.h"
static const SSL_METHOD *ssl23_get_client_method(int ver);
static int ssl23_client_hello(SSL *s);
static int ssl23_get_server_hello(SSL *s);
static const SSL_METHOD *ssl23_get_client_method(int ver)
{
/* When SSL_set_session is called, do NOT switch to the version-specific
* method table. The server may still negotiate a different version when
* rejecting the session.
*
* TODO(davidben): Clean this up. This duplicates logic from the
* version-specific tables. https://crbug.com/403378 */
return SSLv23_client_method();
}
IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
ssl_undefined_function,
ssl23_connect,
ssl23_get_client_method)
ssl23_connect)
int ssl23_connect(SSL *s)
{
@ -299,16 +287,14 @@ static int ssl23_client_hello(SSL *s)
buf=(unsigned char *)s->init_buf->data;
if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
{
/* Check if the session is resumable. If not, drop it. */
if (s->session != NULL)
{
if (s->session->ssl_version > version ||
/* 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_SESSION_free(s->session);
s->session = NULL;
}
s->session->not_resumable))
{
SSL_set_session(s, NULL);
}
p=s->s3->client_random;

View File

@ -55,30 +55,9 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <stdio.h>
#include <openssl/obj.h>
#include "ssl_locl.h"
static const SSL_METHOD *ssl23_get_method(int ver);
static const SSL_METHOD *ssl23_get_method(int ver)
{
if (ver == SSL3_VERSION)
return(SSLv3_method());
else
if (ver == TLS1_VERSION)
return(TLSv1_method());
else if (ver == TLS1_1_VERSION)
return(TLSv1_1_method());
else if (ver == TLS1_2_VERSION)
return(TLSv1_2_method());
else
return(NULL);
}
IMPLEMENT_ssl23_meth_func(SSLv23_method,
ssl23_accept,
ssl23_connect,
ssl23_get_method)
ssl23_connect)

View File

@ -118,7 +118,6 @@
#include "ssl_locl.h"
static const SSL_METHOD *ssl23_get_server_method(int ver);
static int ssl23_get_client_hello(SSL *s);
static int ssl23_get_v2_client_hello(SSL *s);
@ -138,8 +137,7 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
IMPLEMENT_ssl23_meth_func(SSLv23_server_method,
ssl23_accept,
ssl_undefined_function,
ssl23_get_server_method)
ssl_undefined_function)
int ssl23_accept(SSL *s)
{

View File

@ -165,45 +165,24 @@
#include "ssl_locl.h"
#include "../crypto/dh/internal.h"
static const SSL_METHOD *ssl3_get_client_method(int ver)
{
switch (ver)
{
case TLS1_2_VERSION:
return TLSv1_2_client_method();
case TLS1_1_VERSION:
return TLSv1_1_client_method();
case TLS1_VERSION:
return TLSv1_client_method();
case SSL3_VERSION:
return SSLv3_client_method();
default:
return NULL;
}
}
IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method,
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method,
TLSv1_2_enc_data)
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method,
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method,
TLSv1_1_enc_data)
IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method,
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method,
TLSv1_enc_data)
IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_client_method,
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method,
SSLv3_enc_data)
int ssl3_connect(SSL *s)

View File

@ -55,50 +55,25 @@
* [including the GNU Public Licence.] */
#include <stdio.h>
#include <openssl/obj.h>
#include "ssl_locl.h"
static const SSL_METHOD *ssl3_get_method(int ver)
{
switch (ver)
{
case TLS1_2_VERSION:
return TLSv1_2_method();
case TLS1_1_VERSION:
return TLSv1_1_method();
case TLS1_VERSION:
return TLSv1_method();
case SSL3_VERSION:
return SSLv3_method();
default:
return NULL;
}
}
IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
ssl3_accept,
ssl3_connect,
ssl3_get_method,
TLSv1_2_enc_data)
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
ssl3_accept,
ssl3_connect,
ssl3_get_method,
TLSv1_1_enc_data)
IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
ssl3_accept,
ssl3_connect,
ssl3_get_method,
TLSv1_enc_data)
IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method,
ssl3_accept,
ssl3_connect,
ssl3_get_method,
SSLv3_enc_data)

View File

@ -172,45 +172,24 @@
#include "../crypto/internal.h"
#include "../crypto/dh/internal.h"
static const SSL_METHOD *ssl3_get_server_method(int ver)
{
switch (ver)
{
case TLS1_2_VERSION:
return TLSv1_2_server_method();
case TLS1_1_VERSION:
return TLSv1_1_server_method();
case TLS1_VERSION:
return TLSv1_server_method();
case SSL3_VERSION:
return SSLv3_server_method();
default:
return NULL;
}
}
IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method,
TLSv1_2_enc_data)
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method,
TLSv1_1_enc_data)
IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method,
TLSv1_enc_data)
IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method,
SSLv3_enc_data)
int ssl3_accept(SSL *s)

View File

@ -2294,33 +2294,6 @@ const SSL_METHOD *SSL_get_ssl_method(SSL *s)
return(s->method);
}
int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
{
int conn= -1;
int ret=1;
if (s->method != meth)
{
if (s->handshake_func != NULL)
conn=(s->handshake_func == s->method->ssl_connect);
if (s->method->version == meth->version)
s->method=meth;
else
{
s->method->ssl_free(s);
s->method=meth;
ret=s->method->ssl_new(s);
}
if (conn == 1)
s->handshake_func=meth->ssl_connect;
else if (conn == 0)
s->handshake_func=meth->ssl_accept;
}
return(ret);
}
int SSL_get_error(const SSL *s,int i)
{
int reason;

View File

@ -650,7 +650,7 @@ extern SSL3_ENC_METHOD DTLSv1_enc_data;
extern SSL3_ENC_METHOD DTLSv1_2_enc_data;
#define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
s_get_meth, enc_data) \
enc_data) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
@ -675,7 +675,6 @@ const SSL_METHOD *func_name(void) \
ssl3_pending, \
ssl3_num_ciphers, \
ssl3_get_cipher, \
s_get_meth, \
&enc_data, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \
@ -684,7 +683,7 @@ const SSL_METHOD *func_name(void) \
return &func_name##_data; \
}
#define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
#define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
@ -709,7 +708,6 @@ const SSL_METHOD *func_name(void) \
ssl_undefined_const_function, \
ssl3_num_ciphers, \
ssl3_get_cipher, \
s_get_meth, \
&TLSv1_2_enc_data, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \
@ -719,7 +717,7 @@ const SSL_METHOD *func_name(void) \
}
#define IMPLEMENT_dtls1_meth_func(version, func_name, s_accept, s_connect, \
s_get_meth, enc_data) \
enc_data) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
@ -744,7 +742,6 @@ const SSL_METHOD *func_name(void) \
ssl3_pending, \
ssl3_num_ciphers, \
dtls1_get_cipher, \
s_get_meth, \
&enc_data, \
ssl_undefined_void_function, \
ssl3_callback_ctrl, \

View File

@ -681,52 +681,18 @@ void SSL_SESSION_free(SSL_SESSION *ss)
int SSL_set_session(SSL *s, SSL_SESSION *session)
{
int ret=0;
const SSL_METHOD *meth;
if (s->session == session)
return 1;
if (s->session != NULL)
SSL_SESSION_free(s->session);
s->session = session;
if (session != NULL)
{
meth=s->ctx->method->get_ssl_method(session->ssl_version);
if (meth == NULL)
meth=s->method->get_ssl_method(session->ssl_version);
if (meth == NULL)
{
OPENSSL_PUT_ERROR(SSL, SSL_set_session, SSL_R_UNABLE_TO_FIND_SSL_METHOD);
return(0);
}
if (meth != s->method)
{
if (!SSL_set_ssl_method(s,meth))
return(0);
}
/* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
if (s->session != NULL)
SSL_SESSION_free(s->session);
s->session=session;
s->verify_result = s->session->verify_result;
/* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
ret=1;
CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
s->verify_result = session->verify_result;
}
else
{
if (s->session != NULL)
{
SSL_SESSION_free(s->session);
s->session=NULL;
}
meth=s->ctx->method;
if (meth != s->method)
{
if (!SSL_set_ssl_method(s,meth))
return(0);
}
ret=1;
}
return(ret);
return 1;
}
long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)