]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11730 Add support for DTLSv1.2 and make default
authorPiotr Gregor <piotr@dataandsignal.com>
Mon, 18 Mar 2019 23:13:19 +0000 (23:13 +0000)
committerMike Jerris <mike@signalwire.com>
Thu, 6 Jun 2019 16:05:11 +0000 (12:05 -0400)
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

configure.ac
src/include/switch_rtp.h
src/include/switch_types.h
src/switch_core_media.c
src/switch_rtp.c

index 1e70495fa202af1de5368dfdc9de5e88729e8ac6..be354f41bfcb20aa4cdd949a630bed6977054883 100644 (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
index 41e863768397be8d952fd7f6a4590b5711d1a2db..a16c5f6d5a7502cf6bac007c8e9de74b37e5505d 100644 (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);
 
index 52c2fef3b73ed09d5c4ce7477204d21fffb53e0a..1ccc893b1b5cda592d09e7424ccb480ec620d967 100644 (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
index ff5300537c997a2a7a4d5f9b8c7f3a32968da0bb..48861b1e3d64a83ad68cf39191060378cd4b49e3 100644 (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;
+                       
+
+                                       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);
+                                       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);
                                        }
                                }
 
index 39e509e850e9f242bff82ad1fec54b5e8e6d8269..0609906ad790aef2aae6bf9d35fe33df6fcc36ef 100644 (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);