Use a single SSL context object (#989)

openssl allows multiple TLS version support through a single SSL_CTX
object.

This PR replaces 4 per-version SSL_CTX objects with a single object
(DTLS is not yet changed).
SSL context initialization code for openssl with modern API (>=1.1.0)
uses `TLS_server_method` and `SSL_CTX_set_min_proto_version` instead of
enabling specific TLS version. Byproduct of this is TLSv1_3 support when
used with openssl-1.1.1 and above

TLS 1.2 and TLS 1.3 cannot be disabled (as before)

Test plan:
- run_tests.sh script now runs turnserver with SSL certificate (which
enables TLS support)
- run_tests.sh now has one more basic test that uses TLS protocol

Co-authored-by: Pavel Punsky <pavel.punsky@epicgames.com>
This commit is contained in:
Pavel Punsky 2022-09-28 00:50:25 -07:00 committed by GitHub
parent 57f5a25099
commit 4bab2adba4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 114 deletions

View File

@ -204,11 +204,14 @@ Flags:
--dh1066 Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
--no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.
--no-tlsv1 Set TLSv1_1/DTLSv1.2 as a minimum supported protocol version.
With openssl-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.
--no-tlsv1_1 Do not allow TLSv1.1 protocol.
--no-tlsv1_1 Set TLSv1_2/DTLSv1.2 as a minimum supported protocol version.
With openssl-1.0.2 and below, do not allow TLSv1.1 protocol.
--no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.
--no-tlsv1_2 Set TLSv1_3/DTLSv1.2 as a minimum supported protocol version.
With openssl-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.
--no-udp Do not start UDP client listeners.

View File

@ -1,7 +1,7 @@
#!/bin/bash
echo 'Running turnserver'
../bin/turnserver --use-auth-secret --static-auth-secret=secret --realm=north.gov --allow-loopback-peers --no-cli > /dev/null &
../bin/turnserver --use-auth-secret --static-auth-secret=secret --realm=north.gov --allow-loopback-peers --no-cli --cert ../examples/ca/turn_server_cert.pem --pkey ../examples/ca/turn_server_pkey.pem > /dev/null &
echo 'Running peer client'
../bin/turnutils_peer -L 127.0.0.1 -L ::1 -L 0.0.0.0 > /dev/null &
@ -16,6 +16,15 @@ else
exit $?
fi
echo 'Running turn client TLS'
../bin/turnutils_uclient -t -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
if [ $? -eq 0 ]; then
echo OK
else
echo FAIL
exit $?
fi
echo 'Running turn client UDP'
../bin/turnutils_uclient -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
if [ $? -eq 0 ]; then

View File

@ -83,13 +83,7 @@ char HTTP_ALPN[128] = "http/1.1";
#define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1)
turn_params_t turn_params = {
NULL, NULL,
#if TLSv1_1_SUPPORTED
NULL,
#if TLSv1_2_SUPPORTED
NULL,
#endif
#endif
#if DTLS_SUPPORTED
NULL,
#endif
@ -603,9 +597,12 @@ static char Usage[] = "Usage: turnserver [options]\n"
" --dh1066 Use 1066 bits predefined DH TLS key. Default size of the predefined key is 2066.\n"
" --dh-file <dh-file-name> Use custom DH TLS key, stored in PEM format in the file.\n"
" Flags --dh566 and --dh1066 are ignored when the DH key is taken from a file.\n"
" --no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.\n"
" --no-tlsv1_1 Do not allow TLSv1.1 protocol.\n"
" --no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.\n"
" --no-tlsv1 Set TLSv1_1/DTLSv1.2 as a minimum supported protocol version.\n"
" With openssl-1.0.2 and below, do not allow TLSv1/DTLSv1 protocols.\n"
" --no-tlsv1_1 Set TLSv1_2/DTLSv1.2 as a minimum supported protocol version.\n"
" With openssl-1.0.2 and below, do not allow TLSv1.1 protocol.\n"
" --no-tlsv1_2 Set TLSv1_3/DTLSv1.2 as a minimum supported protocol version.\n"
" With openssl-1.0.2 and below, do not allow TLSv1.2/DTLSv1.2 protocols.\n"
" --no-udp Do not start UDP client listeners.\n"
" --no-tcp Do not start TCP client listeners.\n"
" --no-tls Do not start TLS client listeners.\n"
@ -3152,23 +3149,10 @@ static void set_ctx(SSL_CTX** out, const char *protocol, const SSL_METHOD* metho
op |= SSL_OP_NO_SSLv2;
#endif
#if defined(SSL_OP_NO_SSLv2)
#if defined(SSL_OP_NO_SSLv3)
op |= SSL_OP_NO_SSLv3;
#endif
if(turn_params.no_tlsv1)
op |= SSL_OP_NO_TLSv1;
#if defined(SSL_OP_NO_TLSv1_1)
if(turn_params.no_tlsv1_1)
op |= SSL_OP_NO_TLSv1_1;
#endif
#if defined(SSL_OP_NO_TLSv1_2)
if(turn_params.no_tlsv1_2)
op |= SSL_OP_NO_TLSv1_2;
#endif
#if defined(SSL_OP_NO_DTLSv1) && DTLS_SUPPORTED
if(turn_params.no_tlsv1)
op |= SSL_OP_NO_DTLSv1;
@ -3240,20 +3224,35 @@ static void openssl_load_certificates(void)
{
pthread_mutex_lock(&turn_params.tls_mutex);
if(!turn_params.no_tls) {
set_ctx(&turn_params.tls_ctx_ssl23,"SSL23",SSLv23_server_method()); /*compatibility mode */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
set_ctx(&turn_params.tls_ctx,"TLS", TLSv1_2_server_method()); /*openssl-1.0.2 version specific API */
if(!turn_params.no_tlsv1) {
set_ctx(&turn_params.tls_ctx_v1_0,"TLS1.0",TLSv1_server_method());
SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1);
}
#if TLSv1_1_SUPPORTED
if(!turn_params.no_tlsv1_1) {
set_ctx(&turn_params.tls_ctx_v1_1,"TLS1.1",TLSv1_1_server_method());
SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_1);
}
#if TLSv1_2_SUPPORTED
if(!turn_params.no_tlsv1_2) {
set_ctx(&turn_params.tls_ctx_v1_2,"TLS1.2",TLSv1_2_server_method());
SSL_CTX_set_options(turn_params.tls_ctx, SSL_OP_NO_TLSv1_2);
}
#endif
#endif
#else // OPENSSL_VERSION_NUMBER < 0x10100000L
set_ctx(&turn_params.tls_ctx,"TLS", TLS_server_method());
if(!turn_params.no_tlsv1) {
SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_1_VERSION);
}
if(!turn_params.no_tlsv1_1) {
SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_2_VERSION);
}
#if TLSv1_3_SUPPORTED
if(!turn_params.no_tlsv1_2) {
SSL_CTX_set_min_proto_version(turn_params.tls_ctx, TLS1_3_VERSION);
}
#endif
#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n",turn_params.cipher_list);
}

View File

@ -176,16 +176,7 @@ typedef struct _turn_params_ {
//////////////// OpenSSL group //////////////////////
SSL_CTX *tls_ctx_ssl23;
SSL_CTX *tls_ctx_v1_0;
#if TLSv1_1_SUPPORTED
SSL_CTX *tls_ctx_v1_1;
#if TLSv1_2_SUPPORTED
SSL_CTX *tls_ctx_v1_2;
#endif
#endif
SSL_CTX *tls_ctx;
#if DTLS_SUPPORTED
SSL_CTX *dtls_ctx;

View File

@ -333,14 +333,7 @@ static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb
/* No mutex with "e" as these are only used in the same event loop */
pthread_mutex_lock(&turn_params.tls_mutex);
replace_one_ssl_ctx(&e->tls_ctx_ssl23, params->tls_ctx_ssl23);
replace_one_ssl_ctx(&e->tls_ctx_v1_0, params->tls_ctx_v1_0);
#if TLSv1_1_SUPPORTED
replace_one_ssl_ctx(&e->tls_ctx_v1_1, params->tls_ctx_v1_1);
#if TLSv1_2_SUPPORTED
replace_one_ssl_ctx(&e->tls_ctx_v1_2, params->tls_ctx_v1_2);
#endif
#endif
replace_one_ssl_ctx(&e->tls_ctx, params->tls_ctx);
#if DTLS_SUPPORTED
replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx);
#endif

View File

@ -2425,34 +2425,11 @@ static int socket_input_worker(ioa_socket_handle s)
if(s->bev) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat);
}
switch(tls_type) {
#if TLSv1_2_SUPPORTED
case TURN_TLS_v1_2:
if(s->e->tls_ctx_v1_2) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_2));
}
break;
#endif
#if TLSv1_1_SUPPORTED
case TURN_TLS_v1_1:
if(s->e->tls_ctx_v1_1) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_1));
}
break;
#endif
case TURN_TLS_v1_0:
if(s->e->tls_ctx_v1_0) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_0));
}
break;
default:
if(s->e->tls_ctx_ssl23) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_ssl23));
} else {
s->tobeclosed = 1;
return 0;
}
};
if(s->e->tls_ctx) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx));
}
if(s->ssl) {
s->bev = bufferevent_openssl_socket_new(s->e->event_base,
s->fd,
@ -2491,34 +2468,9 @@ static int socket_input_worker(ioa_socket_handle s)
if(s->bev) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat);
}
switch(tls_type) {
#if TLSv1_2_SUPPORTED
case TURN_TLS_v1_2:
if(s->e->tls_ctx_v1_2) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_2));
}
break;
#endif
#if TLSv1_1_SUPPORTED
case TURN_TLS_v1_1:
if(s->e->tls_ctx_v1_1) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_1));
}
break;
#endif
case TURN_TLS_v1_0:
if(s->e->tls_ctx_v1_0) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_v1_0));
}
break;
default:
if(s->e->tls_ctx_ssl23) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx_ssl23));
} else {
s->tobeclosed = 1;
return 0;
}
};
if(s->e->tls_ctx) {
set_socket_ssl(s,SSL_new(s->e->tls_ctx));
}
if(s->ssl) {
s->bev = bufferevent_openssl_socket_new(s->e->event_base,
s->fd,
@ -3520,7 +3472,7 @@ int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, in
#if TLS_SUPPORTED
if(!(s->ssl)) {
//??? how we can get to this point ???
set_socket_ssl(s,SSL_new(e->tls_ctx_ssl23));
set_socket_ssl(s,SSL_new(e->tls_ctx));
s->bev = bufferevent_openssl_socket_new(s->e->event_base,
s->fd,
s->ssl,

View File

@ -141,14 +141,7 @@ struct _ioa_engine
turnipports* tp;
rtcp_map *map_rtcp;
stun_buffer_list bufs;
SSL_CTX *tls_ctx_ssl23;
SSL_CTX *tls_ctx_v1_0;
#if TLSv1_1_SUPPORTED
SSL_CTX *tls_ctx_v1_1;
#if TLSv1_2_SUPPORTED
SSL_CTX *tls_ctx_v1_2;
#endif
#endif
SSL_CTX *tls_ctx;
#if DTLS_SUPPORTED
SSL_CTX *dtls_ctx;
#endif