[Asterisk-code-review] res/res rtp asterisk: Add ECDH support (asterisk[11])

Matt Jordan asteriskteam at digium.com
Mon Aug 3 09:55:59 CDT 2015


Matt Jordan has uploaded a new change for review.

  https://gerrit.asterisk.org/1029

Change subject: res/res_rtp_asterisk: Add ECDH support
......................................................................

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
---
M configure
M configure.ac
M include/asterisk/autoconfig.h.in
M res/res_rtp_asterisk.c
4 files changed, 203 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/29/1029/1

diff --git a/configure b/configure
index a5d6ca28..8e64553 100755
--- a/configure
+++ b/configure
@@ -1050,6 +1050,14 @@
 DAHDI_DIR
 DAHDI_INCLUDE
 DAHDI_LIB
+PBX_OPENSSL_ECDH_AUTO
+OPENSSL_ECDH_AUTO_DIR
+OPENSSL_ECDH_AUTO_INCLUDE
+OPENSSL_ECDH_AUTO_LIB
+PBX_OPENSSL_EC
+OPENSSL_EC_DIR
+OPENSSL_EC_INCLUDE
+OPENSSL_EC_LIB
 PBX_OPENSSL_SRTP
 OPENSSL_SRTP_DIR
 OPENSSL_SRTP_INCLUDE
@@ -8510,6 +8518,30 @@
 OPENSSL_SRTP_DIR=${CRYPTO_DIR}
 
 PBX_OPENSSL_SRTP=0
+
+
+
+
+
+
+
+OPENSSL_EC_DESCRIP="OpenSSL Elliptic Curve Support"
+OPENSSL_EC_OPTION=crypto
+OPENSSL_EC_DIR=${CRYPTO_DIR}
+
+PBX_OPENSSL_EC=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
 
 
 
@@ -28327,6 +28359,161 @@
 
 fi
 
+if test "$PBX_OPENSSL" = "1";
+then
+
+if test "x${PBX_OPENSSL_EC}" != "x1" -a "${USE_OPENSSL_EC}" != "no"; then
+   pbxlibdir=""
+   # if --with-OPENSSL_EC=DIR has been specified, use it.
+   if test "x${OPENSSL_EC_DIR}" != "x"; then
+      if test -d ${OPENSSL_EC_DIR}/lib; then
+         pbxlibdir="-L${OPENSSL_EC_DIR}/lib"
+      else
+         pbxlibdir="-L${OPENSSL_EC_DIR}"
+      fi
+   fi
+   pbxfuncname="EC_KEY_new_by_curve_name"
+   if test "x${pbxfuncname}" = "x" ; then   # empty lib, assume only headers
+      AST_OPENSSL_EC_FOUND=yes
+   else
+      ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
+      CFLAGS="${CFLAGS} "
+      as_ac_Lib=`$as_echo "ac_cv_lib_ssl_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lssl" >&5
+$as_echo_n "checking for ${pbxfuncname} in -lssl... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lssl ${pbxlibdir} -lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ${pbxfuncname} ();
+int
+main ()
+{
+return ${pbxfuncname} ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+  AST_OPENSSL_EC_FOUND=yes
+else
+  AST_OPENSSL_EC_FOUND=no
+fi
+
+      CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
+   fi
+
+   # now check for the header.
+   if test "${AST_OPENSSL_EC_FOUND}" = "yes"; then
+      OPENSSL_EC_LIB="${pbxlibdir} -lssl -lcrypto"
+      # if --with-OPENSSL_EC=DIR has been specified, use it.
+      if test "x${OPENSSL_EC_DIR}" != "x"; then
+         OPENSSL_EC_INCLUDE="-I${OPENSSL_EC_DIR}/include"
+      fi
+      OPENSSL_EC_INCLUDE="${OPENSSL_EC_INCLUDE} "
+      if test "xopenssl/ec.h" = "x" ; then	# no header, assume found
+         OPENSSL_EC_HEADER_FOUND="1"
+      else				# check for the header
+         ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
+         CPPFLAGS="${CPPFLAGS} ${OPENSSL_EC_INCLUDE}"
+         ac_fn_c_check_header_mongrel "$LINENO" "openssl/ec.h" "ac_cv_header_openssl_ec_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_ec_h" = xyes; then :
+  OPENSSL_EC_HEADER_FOUND=1
+else
+  OPENSSL_EC_HEADER_FOUND=0
+fi
+
+
+         CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
+      fi
+      if test "x${OPENSSL_EC_HEADER_FOUND}" = "x0" ; then
+         OPENSSL_EC_LIB=""
+         OPENSSL_EC_INCLUDE=""
+      else
+         if test "x${pbxfuncname}" = "x" ; then		# only checking headers -> no library
+            OPENSSL_EC_LIB=""
+         fi
+         PBX_OPENSSL_EC=1
+         cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENSSL_EC 1
+_ACEOF
+
+      fi
+   fi
+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 3ab2524..0791046 100644
--- a/configure.ac
+++ b/configure.ac
@@ -392,6 +392,7 @@
 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 @@
         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 b32817c..66c40b2 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 68b00d9..d3c704c 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -1270,6 +1270,13 @@
 
 	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) ?

-- 
To view, visit https://gerrit.asterisk.org/1029
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8c13b33a2a79c0bde2e69e4ba6afa5ab9351465b
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 11
Gerrit-Owner: Matt Jordan <mjordan at digium.com>
Gerrit-Reviewer: Mark Duncan <mark at syon.co.jp>



More information about the asterisk-code-review mailing list