From 786105a9b4bcf21ed111da753f5b4813903f3182 Mon Sep 17 00:00:00 2001 From: mom040267 Date: Tue, 9 Dec 2014 09:29:27 +0000 Subject: [PATCH] DTLS v1.2 supported. --- ChangeLog | 4 ++ STATUS | 2 + TODO | 2 - rpm/build.settings.sh | 2 +- rpm/turnserver.spec | 4 +- src/apps/common/apputils.c | 8 +++ src/apps/relay/dtls_listener.c | 67 +++++++++++++++++++++++--- src/apps/relay/mainrelay.c | 14 ++++-- src/apps/relay/mainrelay.h | 3 ++ src/apps/relay/netengine.c | 18 +++++-- src/apps/relay/ns_ioalib_engine_impl.c | 9 +++- src/apps/relay/ns_ioalib_impl.h | 9 +++- src/apps/uclient/mainuclient.c | 5 ++ src/apps/uclient/startuclient.c | 2 + src/ns_turn_defs.h | 2 +- 15 files changed, 131 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bd06874..041d5560 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +12/09/2014 Oleg Moskalenko +Version 4.3.2.1 'Tolomei': + - DTLS v1.2 supported (for OpenSSL 1.0.2+); + 11/29/2014 Oleg Moskalenko Version 4.3.1.3 'Tolomei': - Reliability fixes (Issue 141 from rfc5766-turn-server). diff --git a/STATUS b/STATUS index d908316a..3585fe1d 100644 --- a/STATUS +++ b/STATUS @@ -108,6 +108,8 @@ compatibility. 46) Third-party security mechanism (through oAuth) implemented. 47) SQLite support added as default database. + +48) DTLS1.2 supported. Things to be implemented in future (the development roadmap) are described in the TODO file. diff --git a/TODO b/TODO index 05e71fc6..6bd108ae 100644 --- a/TODO +++ b/TODO @@ -61,8 +61,6 @@ 3) Redirect draft. -4) DTLS 1.2 (when available). - ================================================================== ### VII. MISC FEATURES ### diff --git a/rpm/build.settings.sh b/rpm/build.settings.sh index e4c19573..67acef40 100755 --- a/rpm/build.settings.sh +++ b/rpm/build.settings.sh @@ -2,7 +2,7 @@ # Common settings script. -TURNVERSION=4.3.1.3 +TURNVERSION=4.3.2.1 BUILDDIR=~/rpmbuild ARCH=`uname -p` TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index 6b76d9e6..995ba866 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -1,5 +1,5 @@ Name: turnserver -Version: 4.3.1.3 +Version: 4.3.2.1 Release: 0%{dist} Summary: Coturn TURN Server @@ -294,6 +294,8 @@ fi %{_includedir}/turn/client/TurnMsgLib.h %changelog +* Tue Dec 09 2014 Oleg Moskalenko + - Sync to 4.3.2.1 * Sat Nov 29 2014 Oleg Moskalenko - Sync to 4.3.1.3 * Mon Nov 23 2014 Oleg Moskalenko diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index e76e3910..12cf7abf 100644 --- a/src/apps/common/apputils.c +++ b/src/apps/common/apputils.c @@ -864,6 +864,14 @@ static const char* turn_get_method(const SSL_METHOD *method, const char* mdefaul return "DTLSv1.0"; } else if(method == DTLSv1_client_method()) { return "DTLSv1.0"; + +#if defined(SSL_OP_NO_DTLSv1_2) + } else if(method == DTLSv1_2_server_method()) { + return "DTLSv1.2"; + } else if(method == DTLSv1_2_client_method()) { + return "DTLSv1.2"; +#endif + #endif } else { if(mdefault) diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index f6847ec3..2280298a 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -59,6 +59,9 @@ struct dtls_listener_relay_server_info { turn_turnserver *ts; int verbose; SSL_CTX *dtls_ctx; +#if defined(SSL_OP_NO_DTLSv1_2) + SSL_CTX *dtls_ctx_v1_2; +#endif struct event *udp_listen_ev; ioa_socket_handle udp_listen_s; ur_addr_map *children_ss; /* map of socket children on remote addr */ @@ -79,27 +82,28 @@ int is_dtls_handshake_message(const unsigned char* buf, int len); int is_dtls_data_message(const unsigned char* buf, int len); int is_dtls_alert_message(const unsigned char* buf, int len); int is_dtls_cipher_change_message(const unsigned char* buf, int len); +int get_dtls_version(const unsigned char* buf, int len); int is_dtls_message(const unsigned char* buf, int len); int is_dtls_handshake_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x16 && buf[1]==0xfe && buf[2]==0xff); + return (buf && len>3 && buf[0]==0x16 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); } int is_dtls_data_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && buf[2]==0xff); + return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); } int is_dtls_alert_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && buf[2]==0xff); + return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); } int is_dtls_cipher_change_message(const unsigned char* buf, int len) { - return (buf && len>3 && buf[0]==0x14 && buf[1]==0xfe && buf[2]==0xff); + return (buf && len>3 && buf[0]==0x14 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))); } int is_dtls_message(const unsigned char* buf, int len) { - if(buf && (len>3) && (buf[1])==0xfe && (buf[2]==0xff)) { + if(buf && (len>3) && (buf[1])==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))) { switch (buf[0]) { case 0x14: case 0x15: @@ -113,6 +117,13 @@ int is_dtls_message(const unsigned char* buf, int len) { return 0; } +/* 0 - 1.0, 1 - 1.2 */ +int get_dtls_version(const unsigned char* buf, int len) { + if(buf && (len>3) && (buf[2] == 0xfd)) + return 1; + return 0; +} + ///////////// utils ///////////////////// #if !defined(TURN_NO_DTLS) @@ -266,7 +277,18 @@ static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_ty timeout.tv_usec = 0; BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); - connecting_ssl = SSL_NEW(server->dtls_ctx); +#if defined(SSL_OP_NO_DTLSv1_2) + if(get_dtls_version(ioa_network_buffer_data(nbh), + (int)ioa_network_buffer_get_size(nbh)) == 1) { + connecting_ssl = SSL_NEW(server->dtls_ctx_v1_2); + } else { + connecting_ssl = SSL_NEW(server->dtls_ctx); + } +#else + { + connecting_ssl = SSL_NEW(server->dtls_ctx); + } +#endif SSL_set_accept_state(connecting_ssl); @@ -536,7 +558,18 @@ static int create_new_connected_udp_socket( timeout.tv_usec = 0; BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); - connecting_ssl = SSL_NEW(server->dtls_ctx); +#if defined(SSL_OP_NO_DTLSv1_2) + if(get_dtls_version(ioa_network_buffer_data(server->sm.m.sm.nd.nbh), + (int)ioa_network_buffer_get_size(server->sm.m.sm.nd.nbh)) == 1) { + connecting_ssl = SSL_NEW(server->dtls_ctx_v1_2); + } else { + connecting_ssl = SSL_NEW(server->dtls_ctx); + } +#else + { + connecting_ssl = SSL_NEW(server->dtls_ctx); + } +#endif SSL_set_accept_state(connecting_ssl); @@ -865,6 +898,9 @@ static int init_server(dtls_listener_relay_server_type* server, if(!server) return -1; server->dtls_ctx = e->dtls_ctx; +#if defined(SSL_OP_NO_DTLSv1_2) + server->dtls_ctx_v1_2 = e->dtls_ctx_v1_2; +#endif server->ts = ts; server->connect_cb = send_socket; @@ -896,6 +932,23 @@ static int init_server(dtls_listener_relay_server_type* server, #endif } +#if defined(SSL_OP_NO_DTLSv1_2) + if(server->dtls_ctx_v1_2) { + + #if defined(REQUEST_CLIENT_CERT) + /* If client has to authenticate, then */ + SSL_CTX_set_verify(server->dtls_ctx_v1_2, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback); + #endif + + SSL_CTX_set_read_ahead(server->dtls_ctx_v1_2, 1); + + #if !defined(TURN_NO_DTLS) + SSL_CTX_set_cookie_generate_cb(server->dtls_ctx_v1_2, generate_cookie); + SSL_CTX_set_cookie_verify_cb(server->dtls_ctx_v1_2, verify_cookie); + #endif + } +#endif + return create_server_socket(server, report_creation); } diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 5abf1bd8..df316501 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -65,17 +65,17 @@ static int anon_credentials = 0; #define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1) turn_params_t turn_params = { - NULL, NULL, - #if defined(SSL_TXT_TLSV1_1) NULL, #if defined(SSL_TXT_TLSV1_2) NULL, #endif #endif - NULL, +#if defined(SSL_OP_NO_DTLSv1_2) +NULL, +#endif DH_1066, "", DEFAULT_EC_CURVE_NAME, "", "turn_server_cert.pem","turn_server_pkey.pem", "", "", @@ -2546,7 +2546,15 @@ static void openssl_setup(void) turn_params.dtls_ctx = SSL_CTX_new(DTLSv1_server_method()); set_ctx(turn_params.dtls_ctx,"DTLS"); SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1); + +#if defined(SSL_OP_NO_DTLSv1_2) + turn_params.dtls_ctx_v1_2 = SSL_CTX_new(DTLSv1_2_server_method()); + set_ctx(turn_params.dtls_ctx_v1_2,"DTLS1,2"); + SSL_CTX_set_read_ahead(turn_params.dtls_ctx_v1_2, 1); +#endif + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list); + #endif } } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 0b684c95..06fbee72 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -188,6 +188,9 @@ typedef struct _turn_params_ { #endif SSL_CTX *dtls_ctx; +#if defined(SSL_OP_NO_DTLSv1_2) + SSL_CTX *dtls_ctx_v1_2; +#endif DH_KEY_SIZE dh_key_size; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 86ae4471..ca7073d2 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -947,7 +947,11 @@ static ioa_engine_handle create_new_listener_engine(void) turn_params.tls_ctx_v1_2, #endif #endif - turn_params.dtls_ctx); + turn_params.dtls_ctx +#if defined(SSL_OP_NO_DTLSv1_2) + ,turn_params.dtls_ctx_v1_2 +#endif + ); ioa_engine_set_rtcp_map(e, turn_params.listener.rtcpmap); return e; } @@ -997,7 +1001,11 @@ static void setup_listener(void) turn_params.tls_ctx_v1_2, #endif #endif - turn_params.dtls_ctx); + turn_params.dtls_ctx +#if defined(SSL_OP_NO_DTLSv1_2) + ,turn_params.dtls_ctx_v1_2 +#endif + ); turn_params.listener.rtcpmap = rtcp_map_create(turn_params.listener.ioa_eng); @@ -1565,7 +1573,11 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int turn_params.tls_ctx_v1_2, #endif #endif - turn_params.dtls_ctx); + turn_params.dtls_ctx +#if defined(SSL_OP_NO_DTLSv1_2) + ,turn_params.dtls_ctx_v1_2 +#endif + ); ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap); } diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 8990a000..7385881c 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -440,7 +440,11 @@ void set_ssl_ctx(ioa_engine_handle e, SSL_CTX *tls_ctx_v1_2, #endif #endif - SSL_CTX *dtls_ctx) + SSL_CTX *dtls_ctx +#if defined(SSL_OP_NO_DTLSv1_2) + ,SSL_CTX *dtls_ctx_v1_2 +#endif +) { e->tls_ctx_ssl23 = tls_ctx_ssl23; e->tls_ctx_v1_0 = tls_ctx_v1_0; @@ -451,6 +455,9 @@ void set_ssl_ctx(ioa_engine_handle e, #endif #endif e->dtls_ctx = dtls_ctx; +#if defined(SSL_OP_NO_DTLSv1_2) + e->dtls_ctx_v1_2 = dtls_ctx_v1_2; +#endif } void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap) diff --git a/src/apps/relay/ns_ioalib_impl.h b/src/apps/relay/ns_ioalib_impl.h index 998860a7..dbffaed5 100644 --- a/src/apps/relay/ns_ioalib_impl.h +++ b/src/apps/relay/ns_ioalib_impl.h @@ -150,6 +150,9 @@ struct _ioa_engine #endif #endif SSL_CTX *dtls_ctx; +#if defined(SSL_OP_NO_DTLSv1_2) + SSL_CTX *dtls_ctx_v1_2; +#endif turn_time_t jiffie; /* bandwidth check interval */ ioa_timer_handle timer_ev; s08bits cmsg[TURN_CMSG_SZ+1]; @@ -258,7 +261,11 @@ void set_ssl_ctx(ioa_engine_handle e, SSL_CTX *tls_ctx_v1_2, #endif #endif - SSL_CTX *dtls_ctx); + SSL_CTX *dtls_ctx +#if defined(SSL_OP_NO_DTLSv1_2) + ,SSL_CTX *dtls_ctx_v1_2 +#endif +); void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap); diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index ca7201ba..dbe41fdf 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -538,6 +538,11 @@ int main(int argc, char **argv) root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; +#if defined(SSL_OP_NO_DTLSv1_2) + root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_2_client_method()); + SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); + root_tls_ctx_num++; +#endif #endif } diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 6c0d366d..791d704a 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -79,7 +79,9 @@ static int get_allocate_address_family(ioa_addr *relay_addr) { static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle) { + int ctxtype = (int)(((unsigned long)random())%root_tls_ctx_num); + SSL *ssl; ssl = SSL_NEW(root_tls_ctx[ctxtype]); diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index bb136d3f..3a259ce2 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -31,7 +31,7 @@ #ifndef __IOADEFS__ #define __IOADEFS__ -#define TURN_SERVER_VERSION "4.3.1.3" +#define TURN_SERVER_VERSION "4.3.2.1" #define TURN_SERVER_VERSION_NAME "Tolomei" #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"