From 2d2e7419054cb4b837fa9113f0f309e19fc690ee Mon Sep 17 00:00:00 2001
From: Mark Duncan <mark@syon.co.jp>
Date: Tue, 28 Jul 2015 19:33:39 +0900
Subject: [PATCH] res/res_rtp_asterisk: Add ECDH support

This will add ECDH support to Asterisk. It will
detect auto ECDH support in OpenSSL
(1.0.2b and above) during ./configure. If this is
available, it will use it,
otherwise it will fall back to prime256v1 (this
behavior is consistent with
other projects such as Apache and nginx).

This fixes WebRTC being broken in Firefox 38+ due
to Firefox now only supporting
ciphers with perfect forward secrecy.

ASTERISK-25265 #close

Change-Id: I8c13b33a2a79c0bde2e69e4ba6afa5ab9351465b
---
 configure                        | 63 ++++++++++++++++++++++++++++++++
 configure.ac                     |  6 +++
 include/asterisk/autoconfig.h.in |  3 ++
 res/res_rtp_asterisk.c           |  7 ++++
 4 files changed, 79 insertions(+)

diff --git a/configure b/configure
index a5d6ca28b5..261f586562 100755
--- a/configure
+++ b/configure
@@ -1050,6 +1050,10 @@ PBX_DAHDI
 DAHDI_DIR
 DAHDI_INCLUDE
 DAHDI_LIB
+PBX_OPENSSL_ECDH_AUTO
+OPENSSL_ECDH_AUTO_DIR
+OPENSSL_ECDH_AUTO_INCLUDE
+OPENSSL_ECDH_AUTO_LIB
 PBX_OPENSSL_SRTP
 OPENSSL_SRTP_DIR
 OPENSSL_SRTP_INCLUDE
@@ -8517,6 +8521,18 @@ PBX_OPENSSL_SRTP=0
 
 
 
+OPENSSL_ECDH_AUTO_DESCRIP="OpenSSL Auto ECDH Support"
+OPENSSL_ECDH_AUTO_OPTION=crypto
+OPENSSL_ECDH_AUTO_DIR=${CRYPTO_DIR}
+
+PBX_OPENSSL_ECDH_AUTO=0
+
+
+
+
+
+
+
     DAHDI_DESCRIP="DAHDI"
     DAHDI_OPTION="dahdi"
     PBX_DAHDI=0
@@ -28327,6 +28343,53 @@ fi
 
 fi
 
+if test "$PBX_OPENSSL" = "1";
+then
+
+    if test "x${PBX_OPENSSL_ECDH_AUTO}" != "x1" -a "${USE_OPENSSL_ECDH_AUTO}" != "no"; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h" >&5
+$as_echo_n "checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h... " >&6; }
+        saved_cppflags="${CPPFLAGS}"
+        if test "x${OPENSSL_ECDH_AUTO_DIR}" != "x"; then
+            OPENSSL_ECDH_AUTO_INCLUDE="-I${OPENSSL_ECDH_AUTO_DIR}/include"
+        fi
+        CPPFLAGS="${CPPFLAGS} ${OPENSSL_ECDH_AUTO_INCLUDE}"
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+ #include <openssl/ssl.h>
+int
+main ()
+{
+#if !defined(SSL_CTX_set_ecdh_auto)
+                                    (void) SSL_CTX_set_ecdh_auto;
+                                #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                PBX_OPENSSL_ECDH_AUTO=1
+
+$as_echo "#define HAVE_OPENSSL_ECDH_AUTO 1" >>confdefs.h
+
+
+
+else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+        CPPFLAGS="${saved_cppflags}"
+    fi
+
+fi
+
 
 if test "x${PBX_SRTP}" != "x1" -a "${USE_SRTP}" != "no"; then
    pbxlibdir=""
diff --git a/configure.ac b/configure.ac
index 3ab2524f58..0791046d11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -392,6 +392,7 @@ AST_EXT_LIB_SETUP_OPTIONAL([COROSYNC_CFG_STATE_TRACK], [A callback only in coros
 AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
 AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto])
 AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_SRTP], [OpenSSL SRTP Extension Support], [CRYPTO], [crypto])
+AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_ECDH_AUTO], [OpenSSL Auto ECDH Support], [CRYPTO], [crypto])
 AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi])
 AST_EXT_LIB_SETUP([FFMPEG], [Ffmpeg and avcodec], [avcodec])
 AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise])
@@ -2164,6 +2165,11 @@ then
         AST_EXT_LIB_CHECK([OPENSSL_SRTP], [ssl], [SSL_CTX_set_tlsext_use_srtp], [openssl/ssl.h], [-lcrypto])
 fi
 
+if test "$PBX_OPENSSL" = "1";
+then
+        AST_C_DECLARE_CHECK([OPENSSL_ECDH_AUTO], [SSL_CTX_set_ecdh_auto], [openssl/ssl.h])
+fi
+
 AST_EXT_LIB_CHECK([SRTP], [srtp], [srtp_init], [srtp/srtp.h])
 
 if test "$PBX_SRTP" = "1";
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index b32817cf6c..66c40b2975 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -530,6 +530,9 @@
 /* Define to 1 if you have the OpenSSL Secure Sockets Layer library. */
 #undef HAVE_OPENSSL
 
+/* Define if your system has SSL_CTX_set_ecdh_auto declared. */
+#undef HAVE_OPENSSL_ECDH_AUTO
+
 /* Define to 1 if CRYPTO has the OpenSSL SRTP Extension Support feature. */
 #undef HAVE_OPENSSL_SRTP
 
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 68b00d981d..d3c704c25d 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -1270,6 +1270,13 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
 
 	SSL_CTX_set_read_ahead(rtp->ssl_ctx, 1);
 
+#ifdef HAVE_OPENSSL_ECDH_AUTO
+	SSL_CTX_set_ecdh_auto(rtp->ssl_ctx, 1);
+#else
+	SSL_CTX_set_tmp_ecdh(rtp->ssl_ctx,
+		EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+#endif
+
 	rtp->dtls_verify = dtls_cfg->verify;
 
 	SSL_CTX_set_verify(rtp->ssl_ctx, (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) || (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) ?
-- 
GitLab