OpenSSL: Remove context duplication
OpenSSL is perfectly capable of having a single context that is shared by both client and server sessions alike; one simply needs to call SSL_set_accept_state (for server) or SSL_set_connect_state (for client) before attempting handshaking.
This commit is contained in:
parent
2aec9b6d68
commit
8a40573369
1 changed files with 32 additions and 53 deletions
|
@ -33,8 +33,7 @@
|
||||||
|
|
||||||
#include "openssl_ratbox.h"
|
#include "openssl_ratbox.h"
|
||||||
|
|
||||||
static SSL_CTX *ssl_server_ctx = NULL;
|
static SSL_CTX *ssl_ctx = NULL;
|
||||||
static SSL_CTX *ssl_client_ctx = NULL;
|
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
get_last_err(void)
|
get_last_err(void)
|
||||||
|
@ -169,7 +168,7 @@ void
|
||||||
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
|
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
|
||||||
{
|
{
|
||||||
new_F->type |= RB_FD_SSL;
|
new_F->type |= RB_FD_SSL;
|
||||||
new_F->ssl = SSL_new(ssl_server_ctx);
|
new_F->ssl = SSL_new(ssl_ctx);
|
||||||
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||||
|
|
||||||
new_F->accept->callback = cb;
|
new_F->accept->callback = cb;
|
||||||
|
@ -178,6 +177,7 @@ rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
|
||||||
|
|
||||||
new_F->accept->addrlen = 0;
|
new_F->accept->addrlen = 0;
|
||||||
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
|
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
|
||||||
|
SSL_set_accept_state((SSL *) new_F->ssl);
|
||||||
rb_ssl_accept_common(new_F);
|
rb_ssl_accept_common(new_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ void
|
||||||
rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen)
|
rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen)
|
||||||
{
|
{
|
||||||
new_F->type |= RB_FD_SSL;
|
new_F->type |= RB_FD_SSL;
|
||||||
new_F->ssl = SSL_new(ssl_server_ctx);
|
new_F->ssl = SSL_new(ssl_ctx);
|
||||||
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||||
|
|
||||||
new_F->accept->callback = F->accept->callback;
|
new_F->accept->callback = F->accept->callback;
|
||||||
|
@ -198,6 +198,7 @@ rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrl
|
||||||
new_F->accept->addrlen = addrlen;
|
new_F->accept->addrlen = addrlen;
|
||||||
|
|
||||||
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
|
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
|
||||||
|
SSL_set_accept_state((SSL *) new_F->ssl);
|
||||||
rb_ssl_accept_common(new_F);
|
rb_ssl_accept_common(new_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,9 +295,6 @@ rb_init_ssl(void)
|
||||||
int
|
int
|
||||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||||
{
|
{
|
||||||
SSL_CTX *ssl_server_ctx_new;
|
|
||||||
SSL_CTX *ssl_client_ctx_new;
|
|
||||||
|
|
||||||
if(cert == NULL)
|
if(cert == NULL)
|
||||||
{
|
{
|
||||||
rb_lib_log("rb_setup_ssl_server: No certificate file");
|
rb_lib_log("rb_setup_ssl_server: No certificate file");
|
||||||
|
@ -313,62 +311,48 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, c
|
||||||
cipher_list = rb_default_ciphers;
|
cipher_list = rb_default_ciphers;
|
||||||
|
|
||||||
#ifdef LRB_HAVE_TLS_METHOD_API
|
#ifdef LRB_HAVE_TLS_METHOD_API
|
||||||
if((ssl_server_ctx_new = SSL_CTX_new(TLS_server_method())) == NULL)
|
SSL_CTX *const ssl_ctx_new = SSL_CTX_new(TLS_method());
|
||||||
#else
|
#else
|
||||||
if((ssl_server_ctx_new = SSL_CTX_new(SSLv23_server_method())) == NULL)
|
SSL_CTX *const ssl_ctx_new = SSL_CTX_new(SSLv23_method());
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
|
|
||||||
get_ssl_error(ERR_get_error()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LRB_HAVE_TLS_METHOD_API
|
if(ssl_ctx_new == NULL)
|
||||||
if((ssl_client_ctx_new = SSL_CTX_new(TLS_client_method())) == NULL)
|
|
||||||
#else
|
|
||||||
if((ssl_client_ctx_new = SSL_CTX_new(SSLv23_client_method())) == NULL)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
|
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL context: %s",
|
||||||
get_ssl_error(ERR_get_error()));
|
get_ssl_error(ERR_get_error()));
|
||||||
|
|
||||||
SSL_CTX_free(ssl_server_ctx_new);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LRB_HAVE_TLS_METHOD_API
|
#ifndef LRB_HAVE_TLS_METHOD_API
|
||||||
SSL_CTX_set_options(ssl_server_ctx_new, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
SSL_CTX_set_options(ssl_ctx_new, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||||
SSL_CTX_set_options(ssl_client_ctx_new, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_OP_SINGLE_DH_USE
|
#ifdef SSL_OP_SINGLE_DH_USE
|
||||||
SSL_CTX_set_options(ssl_server_ctx_new, SSL_OP_SINGLE_DH_USE);
|
SSL_CTX_set_options(ssl_ctx_new, SSL_OP_SINGLE_DH_USE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||||
SSL_CTX_set_options(ssl_server_ctx_new, SSL_OP_SINGLE_ECDH_USE);
|
SSL_CTX_set_options(ssl_ctx_new, SSL_OP_SINGLE_ECDH_USE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_TICKET
|
#ifdef SSL_OP_NO_TICKET
|
||||||
SSL_CTX_set_options(ssl_server_ctx_new, SSL_OP_NO_TICKET);
|
SSL_CTX_set_options(ssl_ctx_new, SSL_OP_NO_TICKET);
|
||||||
SSL_CTX_set_options(ssl_client_ctx_new, SSL_OP_NO_TICKET);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||||
SSL_CTX_set_options(ssl_server_ctx_new, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
SSL_CTX_set_options(ssl_ctx_new, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LRB_HAVE_TLS_ECDH_AUTO
|
#ifdef LRB_HAVE_TLS_ECDH_AUTO
|
||||||
SSL_CTX_set_ecdh_auto(ssl_server_ctx_new, 1);
|
SSL_CTX_set_ecdh_auto(ssl_ctx_new, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LRB_HAVE_TLS_SET_CURVES
|
#ifdef LRB_HAVE_TLS_SET_CURVES
|
||||||
SSL_CTX_set1_curves_list(ssl_server_ctx_new, rb_default_curves);
|
SSL_CTX_set1_curves_list(ssl_ctx_new, rb_default_curves);
|
||||||
SSL_CTX_set1_curves_list(ssl_client_ctx_new, rb_default_curves);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_CTX_set_verify(ssl_server_ctx_new, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
|
SSL_CTX_set_verify(ssl_ctx_new, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
|
||||||
SSL_CTX_set_session_cache_mode(ssl_server_ctx_new, SSL_SESS_CACHE_OFF);
|
SSL_CTX_set_session_cache_mode(ssl_ctx_new, SSL_SESS_CACHE_OFF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available
|
* Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available
|
||||||
|
@ -376,31 +360,28 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, c
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH)
|
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH)
|
||||||
EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
|
EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
|
||||||
if(key) {
|
if(key) {
|
||||||
SSL_CTX_set_tmp_ecdh(ssl_server_ctx_new, key);
|
SSL_CTX_set_tmp_ecdh(ssl_ctx_new, key);
|
||||||
EC_KEY_free(key);
|
EC_KEY_free(key);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_CTX_set_cipher_list(ssl_server_ctx_new, cipher_list);
|
SSL_CTX_set_cipher_list(ssl_ctx_new, cipher_list);
|
||||||
SSL_CTX_set_cipher_list(ssl_client_ctx_new, cipher_list);
|
|
||||||
|
|
||||||
if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx_new, cert) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx_new, cert))
|
if(! SSL_CTX_use_certificate_chain_file(ssl_ctx_new, cert))
|
||||||
{
|
{
|
||||||
rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert,
|
rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert,
|
||||||
get_ssl_error(ERR_get_error()));
|
get_ssl_error(ERR_get_error()));
|
||||||
|
|
||||||
SSL_CTX_free(ssl_server_ctx_new);
|
SSL_CTX_free(ssl_ctx_new);
|
||||||
SSL_CTX_free(ssl_client_ctx_new);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx_new, keyfile, SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx_new, keyfile, SSL_FILETYPE_PEM))
|
if(! SSL_CTX_use_PrivateKey_file(ssl_ctx_new, keyfile, SSL_FILETYPE_PEM))
|
||||||
{
|
{
|
||||||
rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
|
rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
|
||||||
get_ssl_error(ERR_get_error()));
|
get_ssl_error(ERR_get_error()));
|
||||||
|
|
||||||
SSL_CTX_free(ssl_server_ctx_new);
|
SSL_CTX_free(ssl_ctx_new);
|
||||||
SSL_CTX_free(ssl_client_ctx_new);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,20 +404,16 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, c
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SSL_CTX_set_tmp_dh(ssl_server_ctx_new, dh);
|
SSL_CTX_set_tmp_dh(ssl_ctx_new, dh);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ssl_server_ctx)
|
if(ssl_ctx)
|
||||||
SSL_CTX_free(ssl_server_ctx);
|
SSL_CTX_free(ssl_ctx);
|
||||||
|
|
||||||
if(ssl_client_ctx)
|
ssl_ctx = ssl_ctx_new;
|
||||||
SSL_CTX_free(ssl_client_ctx);
|
|
||||||
|
|
||||||
ssl_server_ctx = ssl_server_ctx_new;
|
|
||||||
ssl_client_ctx = ssl_client_ctx_new;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -521,8 +498,9 @@ rb_ssl_tryconn(rb_fde_t *F, int status, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
F->type |= RB_FD_SSL;
|
F->type |= RB_FD_SSL;
|
||||||
F->ssl = SSL_new(ssl_client_ctx);
|
F->ssl = SSL_new(ssl_ctx);
|
||||||
SSL_set_fd((SSL *) F->ssl, F->fd);
|
SSL_set_fd((SSL *) F->ssl, F->fd);
|
||||||
|
SSL_set_connect_state((SSL *) F->ssl);
|
||||||
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||||
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
||||||
{
|
{
|
||||||
|
@ -583,9 +561,10 @@ rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout)
|
||||||
F->connect->callback = callback;
|
F->connect->callback = callback;
|
||||||
F->connect->data = data;
|
F->connect->data = data;
|
||||||
F->type |= RB_FD_SSL;
|
F->type |= RB_FD_SSL;
|
||||||
F->ssl = SSL_new(ssl_client_ctx);
|
F->ssl = SSL_new(ssl_ctx);
|
||||||
|
|
||||||
SSL_set_fd((SSL *) F->ssl, F->fd);
|
SSL_set_fd((SSL *) F->ssl, F->fd);
|
||||||
|
SSL_set_connect_state((SSL *) F->ssl);
|
||||||
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||||
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue