FS-11730 Add support for DTLSv1.2 and make default

Needed in Chrome version >= 74 as Chrome dropped support for v1.0:
https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/discuss-webrtc/yr6gbAgWsKo/9X5vQb8kGAAJ

Using old v1.0 DTLS if 1.2 is not available or legacy DTLS
wanted explicitly. To request old DTLS set variable

	<action application="set" data="legacyDTLS=1"/>

Note: requires openssl 1.0.2 or later for DTLS v1.2 support
This commit is contained in:
Piotr Gregor 2019-03-18 23:13:19 +00:00 committed by Mike Jerris
parent a095c83ecc
commit 9682d2c2c9
5 changed files with 56 additions and 12 deletions

View File

@ -1594,6 +1594,7 @@ if test x$HAVE_OPENSSL = x1; then
APR_ADDTO(SWITCH_AM_CFLAGS, -DHAVE_OPENSSL)
AC_CHECK_LIB(ssl, SSL_CTX_set_tlsext_use_srtp, AC_DEFINE_UNQUOTED(HAVE_OPENSSL_DTLS_SRTP, 1, HAVE_OPENSSL_DTLS_SRTP), AC_MSG_ERROR([OpenSSL >= 1.0.1e and associated developement headers required]))
AC_CHECK_LIB(ssl, DTLSv1_method, AC_DEFINE_UNQUOTED(HAVE_OPENSSL_DTLS, 1, HAVE_OPENSSL_DTLS), AC_MSG_ERROR([OpenSSL >= 1.0.1e and associaed developement headers required]))
AC_CHECK_LIB(ssl, DTLSv1_2_method, AC_DEFINE_UNQUOTED(HAVE_OPENSSL_DTLSv1_2_method, 1, [DTLS version 1.2 is available]))
else
AC_MSG_ERROR([OpenSSL >= 1.0.1e and associated developement headers required])
fi

View File

@ -578,7 +578,7 @@ SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_sess
SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_set_interdigit_delay(switch_rtp_t *rtp_session, uint32_t delay);
SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type);
SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type, uint8_t want_DTLSv1_2);
SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, dtls_type_t type);
SWITCH_DECLARE(dtls_state_t) switch_rtp_dtls_state(switch_rtp_t *rtp_session, dtls_type_t type);

View File

@ -1577,6 +1577,7 @@ typedef enum {
CF_STREAM_CHANGED,
CF_ARRANGED_BRIDGE,
CF_STATE_REPEAT,
CF_WANT_DTLSv1_2,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX

View File

@ -8388,6 +8388,13 @@ static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engin
if (switch_channel_test_flag(session->channel, CF_REINVITE) && engine->new_dtls) {
if (!zstr(engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(session)) {
#ifdef HAVE_OPENSSL_DTLSv1_2_method
uint8_t want_DTLSv1_2 = 1;
#else
uint8_t want_DTLSv1_2 = 0;
#endif // HAVE_OPENSSL_DTLSv1_2_method
dtls_type_t xtype, dtype = engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "RE-SETTING %s DTLS\n", type2str(engine->type));
@ -8395,11 +8402,16 @@ static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engin
xtype = DTLS_TYPE_RTP;
if (engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP;
switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype);
if (switch_channel_var_true(session->channel, "legacyDTLS")) {
switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
want_DTLSv1_2 = 0;
}
switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
if (engine->rtcp_mux < 1) {
xtype = DTLS_TYPE_RTCP;
switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype);
switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
}
}
@ -8422,6 +8434,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_media_handle_t *smh;
int is_reinvite = 0;
#ifdef HAVE_OPENSSL_DTLSv1_2_method
uint8_t want_DTLSv1_2 = 1;
#else
uint8_t want_DTLSv1_2 = 0;
#endif
switch_assert(session);
if (!(smh = session->media_handle)) {
@ -8450,6 +8468,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
if (a_engine->crypto_type != CRYPTO_INVALID) {
switch_channel_set_flag(session->channel, CF_SECURE);
}
if (want_DTLSv1_2) {
switch_channel_set_flag(session->channel, CF_WANT_DTLSv1_2);
}
if (switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
status = SWITCH_STATUS_SUCCESS;
@ -8806,11 +8828,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
xtype = DTLS_TYPE_RTP;
if (a_engine->rtcp_mux > 0 && smh->mparams->rtcp_audio_interval_msec) xtype |= DTLS_TYPE_RTCP;
switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
if (switch_channel_var_true(session->channel, "legacyDTLS")) {
switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
want_DTLSv1_2 = 0;
}
switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
if (a_engine->rtcp_mux < 1 && smh->mparams->rtcp_audio_interval_msec) {
xtype = DTLS_TYPE_RTCP;
switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
}
}
@ -9166,12 +9193,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
dtype = t_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
xtype = DTLS_TYPE_RTP;
if (t_engine->rtcp_mux > 0 && smh->mparams->rtcp_text_interval_msec) xtype |= DTLS_TYPE_RTCP;
if (switch_channel_var_true(session->channel, "legacyDTLS")) {
switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
want_DTLSv1_2 = 0;
}
switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype);
switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
if (t_engine->rtcp_mux < 1 && smh->mparams->rtcp_text_interval_msec) {
xtype = DTLS_TYPE_RTCP;
switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype);
switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
}
}
@ -9493,12 +9525,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
dtype = v_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
xtype = DTLS_TYPE_RTP;
if (v_engine->rtcp_mux > 0 && smh->mparams->rtcp_video_interval_msec) xtype |= DTLS_TYPE_RTCP;
switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
if (switch_channel_var_true(session->channel, "legacyDTLS")) {
switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
want_DTLSv1_2 = 0;
}
switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
if (v_engine->rtcp_mux < 1 && smh->mparams->rtcp_video_interval_msec) {
xtype = DTLS_TYPE_RTCP;
switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
}
}

View File

@ -3201,7 +3201,7 @@ static int dtls_state_handshake(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
case SSL_ERROR_NONE:
break;
default:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s Handshake failure %d\n", rtp_type(rtp_session), ret);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s Handshake failure %d. This may happen when you use legacy DTLS v1.0 (legacyDTLS channel var is set) but endpoint requires DTLS v1.2.\n", rtp_type(rtp_session), ret);
dtls_set_state(dtls, DS_FAIL);
return -1;
}
@ -3634,7 +3634,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, d
return status;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type)
SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type, uint8_t want_DTLSv1_2)
{
switch_dtls_t *dtls;
const char *var;
@ -3695,7 +3695,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
#if OPENSSL_VERSION_NUMBER >= 0x10100000
dtls->ssl_ctx = SSL_CTX_new((type & DTLS_TYPE_SERVER) ? DTLS_server_method() : DTLS_client_method());
#else
dtls->ssl_ctx = SSL_CTX_new((type & DTLS_TYPE_SERVER) ? DTLSv1_server_method() : DTLSv1_client_method());
#ifdef HAVE_OPENSSL_DTLSv1_2_method
dtls->ssl_ctx = SSL_CTX_new((type & DTLS_TYPE_SERVER) ? (want_DTLSv1_2 ? DTLSv1_2_server_method() : DTLSv1_server_method()) : (want_DTLSv1_2 ? DTLSv1_2_client_method() : DTLSv1_client_method()));
#else
dtls->ssl_ctx = SSL_CTX_new((type & DTLS_TYPE_SERVER) ? DTLSv1_server_method() : DTLSv1_client_method());
#endif // HAVE_OPENSSL_DTLSv1_2_method
#endif
switch_assert(dtls->ssl_ctx);