[Python-checkins] bpo-45847: Port _ssl and _hashlib to PY_STDLIB_MOD (GH-29727)

tiran webhook-mailer at python.org
Tue Nov 23 16:58:23 EST 2021


https://github.com/python/cpython/commit/b9e9292d75fdea621e05e39b8629e6935d282d0d
commit: b9e9292d75fdea621e05e39b8629e6935d282d0d
branch: main
author: Christian Heimes <christian at python.org>
committer: tiran <christian at python.org>
date: 2021-11-23T22:58:13+01:00
summary:

bpo-45847: Port _ssl and _hashlib to PY_STDLIB_MOD (GH-29727)

files:
M Modules/Setup.stdlib.in
M configure
M configure.ac
M setup.py

diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 7422ddb59e309..9f66d531fef0f 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -123,6 +123,11 @@
 #
 @MODULE__SQLITE3_TRUE at _sqlite3 _sqlite/connection.c _sqlite/cursor.c _sqlite/microprotocols.c _sqlite/module.c _sqlite/prepare_protocol.c _sqlite/row.c _sqlite/statement.c _sqlite/util.c
 
+# needs -lssl and -lcrypt
+ at MODULE__SSL_TRUE@_ssl _ssl.c
+# needs -lcrypt
+ at MODULE__HASHLIB_TRUE@_hashlib _hashopenssl.c
+
 
 ############################################################################
 # macOS specific modules
diff --git a/configure b/configure
index 01aa80091cd49..ac0a1f320b2a7 100755
--- a/configure
+++ b/configure
@@ -642,6 +642,10 @@ MODULE__TESTINTERNALCAPI_FALSE
 MODULE__TESTINTERNALCAPI_TRUE
 MODULE__TESTCAPI_FALSE
 MODULE__TESTCAPI_TRUE
+MODULE__HASHLIB_FALSE
+MODULE__HASHLIB_TRUE
+MODULE__SSL_FALSE
+MODULE__SSL_TRUE
 MODULE__LZMA_FALSE
 MODULE__LZMA_TRUE
 MODULE__BZ2_FALSE
@@ -20297,6 +20301,16 @@ rm -f core conftest.err conftest.$ac_objext \
 
 
 # rpath to libssl and libcrypto
+if test "x$GNULD" = xyes; then :
+
+  rpath_arg="-Wl,--enable-new-dtags,-rpath="
+
+else
+
+  rpath_arg="-Wl,-rpath="
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-openssl-rpath" >&5
 $as_echo_n "checking for --with-openssl-rpath... " >&6; }
 
@@ -20310,12 +20324,26 @@ fi
 
 case $with_openssl_rpath in #(
   auto|yes) :
-    OPENSSL_RPATH=auto ;; #(
+
+      OPENSSL_RPATH=auto
+            for arg in "$OPENSSL_LDFLAGS"; do
+        case $arg in #(
+  -L*) :
+    OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)"
+         ;; #(
+  *) :
+     ;;
+esac
+      done
+     ;; #(
   no) :
     OPENSSL_RPATH= ;; #(
   *) :
     if test -d "$with_openssl_rpath"; then :
-  OPENSSL_RPATH="$with_openssl_rpath"
+
+          OPENSSL_RPATH="$with_openssl_rpath"
+          OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath"
+
 else
   as_fn_error $? "--with-openssl-rpath \"$with_openssl_rpath\" is not a directory" "$LINENO" 5
 fi
@@ -20326,71 +20354,163 @@ esac
 $as_echo "$OPENSSL_RPATH" >&6; }
 
 
+# This static linking is NOT OFFICIALLY SUPPORTED and not advertised.
+# Requires static OpenSSL build with position-independent code. Some features
+# like DSO engines or external OSSL providers don't work. Only tested with GCC
+# and clang on X86_64.
+if test "x$PY_UNSUPPORTED_OPENSSL_BUILD" = xstatic; then :
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsupported static openssl build" >&5
+$as_echo_n "checking for unsupported static openssl build... " >&6; }
+  new_OPENSSL_LIBS=
+  for arg in $OPENSSL_LIBS; do
+    case $arg in #(
+  -l*) :
+
+        libname=$(echo $arg | cut -c3-)
+        new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a"
+       ;; #(
+  *) :
+    new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg"
+     ;;
+esac
+  done
+    OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_LIBS" >&5
+$as_echo "$OPENSSL_LIBS" >&6; }
+
+fi
+
+LIBCRYPTO_LIBS=
+for arg in $OPENSSL_LIBS; do
+  case $arg in #(
+  -l*ssl*|-Wl*ssl*) :
+     ;; #(
+  *) :
+    LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg"
+   ;;
+esac
+done
+
 # check if OpenSSL libraries work as expected
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required APIs" >&5
-$as_echo_n "checking whether OpenSSL provides required APIs... " >&6; }
-if ${ac_cv_working_openssl+:} false; then :
+save_CFLAGS=$CFLAGS
+save_CPPFLAGS=$CPPFLAGS
+save_LDFLAGS=$LDFLAGS
+save_LIBS=$LIBS
+
+
+  LIBS="$LIBS $OPENSSL_LIBS"
+  CFLAGS="$CFLAGS $OPENSSL_INCLUDES"
+  LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required ssl module APIs" >&5
+$as_echo_n "checking whether OpenSSL provides required ssl module APIs... " >&6; }
+if ${ac_cv_working_openssl_ssl+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
-save_LIBS="$LIBS"
-save_CFLAGS="$CFLAGS"
-save_LDFLAGS="$LDFLAGS"
-LIBS="$LIBS $OPENSSL_LIBS"
-CFLAGS="$CFLAGS_NODIST $OPENSSL_INCLUDES"
-LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#include <openssl/opensslv.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
+      #include <openssl/opensslv.h>
+      #include <openssl/ssl.h>
+      #if OPENSSL_VERSION_NUMBER < 0x10101000L
+        #error "OpenSSL >= 1.1.1 is required"
+      #endif
+      static void keylog_cb(const SSL *ssl, const char *line) {}
 
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
-#error "OpenSSL >= 1.1.1 is required"
-#endif
+int
+main ()
+{
+
+      SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
+      SSL_CTX_set_keylog_callback(ctx, keylog_cb);
+      SSL *ssl = SSL_new(ctx);
+      X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
+      X509_VERIFY_PARAM_set1_host(param, "python.org", 0);
+      SSL_free(ssl);
+      SSL_CTX_free(ctx);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_openssl_ssl=yes
+else
+  ac_cv_working_openssl_ssl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_ssl" >&5
+$as_echo "$ac_cv_working_openssl_ssl" >&6; }
+
+CFLAGS=$save_CFLAGS
+CPPFLAGS=$save_CPPFLAGS
+LDFLAGS=$save_LDFLAGS
+LIBS=$save_LIBS
+
+
+
+save_CFLAGS=$CFLAGS
+save_CPPFLAGS=$CPPFLAGS
+save_LDFLAGS=$LDFLAGS
+save_LIBS=$LIBS
+
+
+  LIBS="$LIBS $LIBCRYPTO_LIBS"
+  CFLAGS="$CFLAGS $OPENSSL_INCLUDES"
+  LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hashlib module APIs" >&5
+$as_echo_n "checking whether OpenSSL provides required hashlib module APIs... " >&6; }
+if ${ac_cv_working_openssl_hashlib+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-static void keylog_cb(const SSL *ssl, const char *line) {}
+      #include <openssl/opensslv.h>
+      #include <openssl/evp.h>
+      #if OPENSSL_VERSION_NUMBER < 0x10101000L
+        #error "OpenSSL >= 1.1.1 is required"
+      #endif
 
 int
 main ()
 {
 
-/* SSL APIs */
-SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
-SSL_CTX_set_keylog_callback(ctx, keylog_cb);
-SSL *ssl = SSL_new(ctx);
-X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
-X509_VERIFY_PARAM_set1_host(param, "python.org", 0);
-SSL_free(ssl);
-SSL_CTX_free(ctx);
-
-/* hashlib APIs */
-OBJ_nid2sn(NID_md5);
-OBJ_nid2sn(NID_sha1);
-OBJ_nid2sn(NID_sha3_512);
-OBJ_nid2sn(NID_blake2b512);
-EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0);
+      OBJ_nid2sn(NID_md5);
+      OBJ_nid2sn(NID_sha1);
+      OBJ_nid2sn(NID_sha3_512);
+      OBJ_nid2sn(NID_blake2b512);
+      EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0);
 
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_working_openssl=yes
+  ac_cv_working_openssl_hashlib=yes
 else
-  ac_cv_working_openssl=no
+  ac_cv_working_openssl_hashlib=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS="$save_LIBS"
-CFLAGS="$save_CFLAGS"
-LDFLAGS="$save_LDFLAGS"
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl" >&5
-$as_echo "$ac_cv_working_openssl" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hashlib" >&5
+$as_echo "$ac_cv_working_openssl_hashlib" >&6; }
+
+CFLAGS=$save_CFLAGS
+CPPFLAGS=$save_CPPFLAGS
+LDFLAGS=$save_LDFLAGS
+LIBS=$save_LIBS
+
+
 
 # ssl module default cipher suite string
 
@@ -21800,6 +21920,79 @@ $as_echo "$py_cv_module__lzma" >&6; }
 
 
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5
+$as_echo_n "checking for stdlib extension module _ssl... " >&6; }
+      case $py_stdlib_not_available in #(
+  *_ssl*) :
+    py_cv_module__ssl=n/a ;; #(
+  *) :
+    if true; then :
+  if test "$ac_cv_working_openssl_ssl" = yes; then :
+  py_cv_module__ssl=yes
+else
+  py_cv_module__ssl=missing
+fi
+else
+  py_cv_module__ssl=disabled
+fi
+   ;;
+esac
+  as_fn_append MODULE_BLOCK "MODULE__SSL=$py_cv_module__ssl$as_nl"
+  if test "x$py_cv_module__ssl" = xyes; then :
+
+    as_fn_append MODULE_BLOCK "MODULE__SSL_CFLAGS=$OPENSSL_INCLUDES$as_nl"
+    as_fn_append MODULE_BLOCK "MODULE__SSL_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS$as_nl"
+
+fi
+   if test "$py_cv_module__ssl" = yes; then
+  MODULE__SSL_TRUE=
+  MODULE__SSL_FALSE='#'
+else
+  MODULE__SSL_TRUE='#'
+  MODULE__SSL_FALSE=
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ssl" >&5
+$as_echo "$py_cv_module__ssl" >&6; }
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5
+$as_echo_n "checking for stdlib extension module _hashlib... " >&6; }
+      case $py_stdlib_not_available in #(
+  *_hashlib*) :
+    py_cv_module__hashlib=n/a ;; #(
+  *) :
+    if true; then :
+  if test "$ac_cv_working_openssl_hashlib" = yes; then :
+  py_cv_module__hashlib=yes
+else
+  py_cv_module__hashlib=missing
+fi
+else
+  py_cv_module__hashlib=disabled
+fi
+   ;;
+esac
+  as_fn_append MODULE_BLOCK "MODULE__HASHLIB=$py_cv_module__hashlib$as_nl"
+  if test "x$py_cv_module__hashlib" = xyes; then :
+
+    as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES$as_nl"
+    as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl"
+
+fi
+   if test "$py_cv_module__hashlib" = yes; then
+  MODULE__HASHLIB_TRUE=
+  MODULE__HASHLIB_FALSE='#'
+else
+  MODULE__HASHLIB_TRUE='#'
+  MODULE__HASHLIB_FALSE=
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hashlib" >&5
+$as_echo "$py_cv_module__hashlib" >&6; }
+
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5
 $as_echo_n "checking for stdlib extension module _testcapi... " >&6; }
       case $py_stdlib_not_available in #(
@@ -22481,6 +22674,14 @@ if test -z "${MODULE__LZMA_TRUE}" && test -z "${MODULE__LZMA_FALSE}"; then
   as_fn_error $? "conditional \"MODULE__LZMA\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${MODULE__SSL_TRUE}" && test -z "${MODULE__SSL_FALSE}"; then
+  as_fn_error $? "conditional \"MODULE__SSL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MODULE__HASHLIB_TRUE}" && test -z "${MODULE__HASHLIB_FALSE}"; then
+  as_fn_error $? "conditional \"MODULE__HASHLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MODULE__TESTCAPI_TRUE}" && test -z "${MODULE__TESTCAPI_FALSE}"; then
   as_fn_error $? "conditional \"MODULE__TESTCAPI\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index 0008e8a746c7b..92afdf39fefc0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5891,6 +5891,12 @@ ac_includes_default="$save_includes_default"
 AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no])
 
 # rpath to libssl and libcrypto
+AS_VAR_IF([GNULD], [yes], [
+  rpath_arg="-Wl,--enable-new-dtags,-rpath="
+], [
+  rpath_arg="-Wl,-rpath="
+])
+
 AC_MSG_CHECKING(for --with-openssl-rpath)
 AC_ARG_WITH(openssl-rpath,
     AS_HELP_STRING([--with-openssl-rpath=@<:@DIR|auto|no@:>@],
@@ -5903,58 +5909,104 @@ AC_ARG_WITH(openssl-rpath,
     [with_openssl_rpath=no]
 )
 AS_CASE($with_openssl_rpath,
-    [auto|yes],[OPENSSL_RPATH=auto],
-    [no],[OPENSSL_RPATH=],
+    [auto|yes], [
+      OPENSSL_RPATH=auto
+      dnl look for linker directories
+      for arg in "$OPENSSL_LDFLAGS"; do
+        AS_CASE([$arg],
+          [-L*], [OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)"]
+        )
+      done
+    ],
+    [no], [OPENSSL_RPATH=],
     [AS_IF(
         [test -d "$with_openssl_rpath"],
-        [OPENSSL_RPATH="$with_openssl_rpath"],
+        [
+          OPENSSL_RPATH="$with_openssl_rpath"
+          OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath"
+        ],
         AC_MSG_ERROR([--with-openssl-rpath "$with_openssl_rpath" is not a directory]))
     ]
 )
 AC_MSG_RESULT($OPENSSL_RPATH)
 AC_SUBST([OPENSSL_RPATH])
 
+# This static linking is NOT OFFICIALLY SUPPORTED and not advertised.
+# Requires static OpenSSL build with position-independent code. Some features
+# like DSO engines or external OSSL providers don't work. Only tested with GCC
+# and clang on X86_64.
+AS_VAR_IF([PY_UNSUPPORTED_OPENSSL_BUILD], [static], [
+  AC_MSG_CHECKING([for unsupported static openssl build])
+  new_OPENSSL_LIBS=
+  for arg in $OPENSSL_LIBS; do
+    AS_CASE([$arg],
+      [-l*], [
+        libname=$(echo $arg | cut -c3-)
+        new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a"
+      ],
+      [new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg"]
+    )
+  done
+  dnl include libz for OpenSSL build flavors with compression support
+  OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS"
+  AC_MSG_RESULT([$OPENSSL_LIBS])
+])
+
+dnl AX_CHECK_OPENSSL does not export libcrypto-only libs
+LIBCRYPTO_LIBS=
+for arg in $OPENSSL_LIBS; do
+  AS_CASE([$arg],
+    [-l*ssl*|-Wl*ssl*], [],
+    [LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg"]
+  )
+done
+
 # check if OpenSSL libraries work as expected
-AC_CACHE_CHECK([whether OpenSSL provides required APIs], [ac_cv_working_openssl], [
-save_LIBS="$LIBS"
-save_CFLAGS="$CFLAGS"
-save_LDFLAGS="$LDFLAGS"
-LIBS="$LIBS $OPENSSL_LIBS"
-CFLAGS="$CFLAGS_NODIST $OPENSSL_INCLUDES"
-LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
+WITH_SAVE_ENV([
+  LIBS="$LIBS $OPENSSL_LIBS"
+  CFLAGS="$CFLAGS $OPENSSL_INCLUDES"
+  LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH"
 
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#include <openssl/opensslv.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
+  AC_CACHE_CHECK([whether OpenSSL provides required ssl module APIs], [ac_cv_working_openssl_ssl], [
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([
+      #include <openssl/opensslv.h>
+      #include <openssl/ssl.h>
+      #if OPENSSL_VERSION_NUMBER < 0x10101000L
+        #error "OpenSSL >= 1.1.1 is required"
+      #endif
+      static void keylog_cb(const SSL *ssl, const char *line) {}
+    ], [
+      SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
+      SSL_CTX_set_keylog_callback(ctx, keylog_cb);
+      SSL *ssl = SSL_new(ctx);
+      X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
+      X509_VERIFY_PARAM_set1_host(param, "python.org", 0);
+      SSL_free(ssl);
+      SSL_CTX_free(ctx);
+    ])], [ac_cv_working_openssl_ssl=yes], [ac_cv_working_openssl_ssl=no])
+  ])
+])
 
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
-#error "OpenSSL >= 1.1.1 is required"
-#endif
+WITH_SAVE_ENV([
+  LIBS="$LIBS $LIBCRYPTO_LIBS"
+  CFLAGS="$CFLAGS $OPENSSL_INCLUDES"
+  LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH"
 
-static void keylog_cb(const SSL *ssl, const char *line) {}
-]], [[
-/* SSL APIs */
-SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
-SSL_CTX_set_keylog_callback(ctx, keylog_cb);
-SSL *ssl = SSL_new(ctx);
-X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
-X509_VERIFY_PARAM_set1_host(param, "python.org", 0);
-SSL_free(ssl);
-SSL_CTX_free(ctx);
-
-/* hashlib APIs */
-OBJ_nid2sn(NID_md5);
-OBJ_nid2sn(NID_sha1);
-OBJ_nid2sn(NID_sha3_512);
-OBJ_nid2sn(NID_blake2b512);
-EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0);
-]])],
-  [ac_cv_working_openssl=yes],
-  [ac_cv_working_openssl=no])
-LIBS="$save_LIBS"
-CFLAGS="$save_CFLAGS"
-LDFLAGS="$save_LDFLAGS"
+  AC_CACHE_CHECK([whether OpenSSL provides required hashlib module APIs], [ac_cv_working_openssl_hashlib], [
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([
+      #include <openssl/opensslv.h>
+      #include <openssl/evp.h>
+      #if OPENSSL_VERSION_NUMBER < 0x10101000L
+        #error "OpenSSL >= 1.1.1 is required"
+      #endif
+    ], [
+      OBJ_nid2sn(NID_md5);
+      OBJ_nid2sn(NID_sha1);
+      OBJ_nid2sn(NID_sha3_512);
+      OBJ_nid2sn(NID_blake2b512);
+      EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0);
+    ])], [ac_cv_working_openssl_hashlib=yes], [ac_cv_working_openssl_hashlib=no])
+  ])
 ])
 
 # ssl module default cipher suite string
@@ -6245,6 +6297,12 @@ PY_STDLIB_MOD([_bz2], [], [test "$have_bzip2" = yes],
 PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes],
   [$LIBLZMA_CFLAGS], [$LIBLZMA_LIBS])
 
+dnl OpenSSL bindings
+PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes],
+  [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS])
+PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes],
+  [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS])
+
 dnl test modules
 PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes])
 PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes])
diff --git a/setup.py b/setup.py
index 721103e7fceb7..7972bac46c106 100644
--- a/setup.py
+++ b/setup.py
@@ -1883,81 +1883,8 @@ def detect_decimal(self):
         )
 
     def detect_openssl_hashlib(self):
-        # Detect SSL support for the socket module (via _ssl)
-        config_vars = sysconfig.get_config_vars()
-
-        def split_var(name, sep):
-            # poor man's shlex, the re module is not available yet.
-            value = config_vars.get(name)
-            if not value:
-                return ()
-            # This trick works because ax_check_openssl uses --libs-only-L,
-            # --libs-only-l, and --cflags-only-I.
-            value = ' ' + value
-            sep = ' ' + sep
-            return [v.strip() for v in value.split(sep) if v.strip()]
-
-        openssl_includes = split_var('OPENSSL_INCLUDES', '-I')
-        openssl_libdirs = split_var('OPENSSL_LDFLAGS', '-L')
-        openssl_libs = split_var('OPENSSL_LIBS', '-l')
-        openssl_rpath = config_vars.get('OPENSSL_RPATH')
-        if not openssl_libs:
-            # libssl and libcrypto not found
-            self.missing.extend(['_ssl', '_hashlib'])
-            return None, None
-
-        # Find OpenSSL includes
-        ssl_incs = find_file(
-            'openssl/ssl.h', self.inc_dirs, openssl_includes
-        )
-        if ssl_incs is None:
-            self.missing.extend(['_ssl', '_hashlib'])
-            return None, None
-
-        if openssl_rpath == 'auto':
-            runtime_library_dirs = openssl_libdirs[:]
-        elif not openssl_rpath:
-            runtime_library_dirs = []
-        else:
-            runtime_library_dirs = [openssl_rpath]
-
-        openssl_extension_kwargs = dict(
-            include_dirs=openssl_includes,
-            library_dirs=openssl_libdirs,
-            libraries=openssl_libs,
-            runtime_library_dirs=runtime_library_dirs,
-        )
-
-        # This static linking is NOT OFFICIALLY SUPPORTED.
-        # Requires static OpenSSL build with position-independent code. Some
-        # features like DSO engines or external OSSL providers don't work.
-        # Only tested on GCC and clang on X86_64.
-        if os.environ.get("PY_UNSUPPORTED_OPENSSL_BUILD") == "static":
-            extra_linker_args = []
-            for lib in openssl_extension_kwargs["libraries"]:
-                # link statically
-                extra_linker_args.append(f"-l:lib{lib}.a")
-                # don't export symbols
-                extra_linker_args.append(f"-Wl,--exclude-libs,lib{lib}.a")
-            openssl_extension_kwargs["extra_link_args"] = extra_linker_args
-            # don't link OpenSSL shared libraries.
-            # include libz for OpenSSL build flavors with compression support
-            openssl_extension_kwargs["libraries"] = ["z"]
-
-        self.add(
-            Extension(
-                '_ssl',
-                ['_ssl.c'],
-                **openssl_extension_kwargs
-            )
-        )
-        self.add(
-            Extension(
-                '_hashlib',
-                ['_hashopenssl.c'],
-                **openssl_extension_kwargs,
-            )
-        )
+        self.addext(Extension('_ssl', ['_ssl.c']))
+        self.addext(Extension('_hashlib', ['_hashopenssl.c']))
 
     def detect_hash_builtins(self):
         # By default we always compile these even when OpenSSL is available



More information about the Python-checkins mailing list