[pypy-commit] pypy default: adapt patch from portable-pypy (thanks squeakypl)

mattip pypy.commits at gmail.com
Thu Dec 12 07:55:16 EST 2019


Author: Matti Picus <matti.picus at gmail.com>
Branch: 
Changeset: r98273:a5cd0e93d2fb
Date: 2019-12-12 13:09 +0200
http://bitbucket.org/pypy/pypy/changeset/a5cd0e93d2fb/

Log:	adapt patch from portable-pypy (thanks squeakypl)

diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -1,4 +1,5 @@
 import sys
+import os
 import time
 import thread as _thread
 import weakref
@@ -1205,6 +1206,10 @@
         return stats
 
     def set_default_verify_paths(self):
+        if not os.environ.get('SSL_CERT_FILE') and not os.environ.get('SSL_CERT_DIR'):
+            locations = get_default_verify_paths()
+            self.load_verify_locations(locations[1], locations[3])
+            return
         if not lib.SSL_CTX_set_default_verify_paths(self.ctx):
             raise ssl_error("")
 
@@ -1548,20 +1553,69 @@
     lib.RAND_add(buf, len(buf), entropy)
 
 def get_default_verify_paths():
+    '''
+    Find a certificate store and associated values
 
+    Returns something like 
+    `('SSL_CERT_FILE', '/usr/lib/ssl/cert.pem', 'SSL_CERT_DIR', '/usr/lib/ssl/certs')`
+    on Ubuntu and windows10
+
+    `('SSL_CERT_FILE', '/usr/local/cert.pem', 'SSL_CERT_DIR', '/usr/local/certs')`
+    on CentOS
+
+    `('SSL_CERT_FILE', '/Library/Frameworks/Python.framework/Versions/2.7/etc/openssl/cert.pem',
+      'SSL_CERT_DIR', '/Library/Frameworks/Python.framework/Versions/2.7/etc/openssl/certs')`
+    on Darwin
+
+    For portable builds (based on CentOS, but could be running on any glibc
+    linux) we need to check other locations. The list of places to try was taken
+    from golang in Dec 2018:
+     https://golang.org/src/crypto/x509/root_unix.go (for the directories),
+     https://golang.org/src/crypto/x509/root_linux.go (for the files)
+    '''
+    certFiles = [
+        "/etc/ssl/certs/ca-certificates.crt",                # Debian/Ubuntu/Gentoo etc.
+        "/etc/pki/tls/certs/ca-bundle.crt",                  # Fedora/RHEL 6
+        "/etc/ssl/ca-bundle.pem",                            # OpenSUSE
+        "/etc/pki/tls/cacert.pem",                           # OpenELEC
+        "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", # CentOS/RHEL 7
+        "/etc/ssl/cert.pem",                                 # Alpine Linux
+    ]
+    certDirectories = [
+        "/etc/ssl/certs",               # SLES10/SLES11
+        "/system/etc/security/cacerts", # Android
+        "/usr/local/share/certs",       # FreeBSD
+        "/etc/pki/tls/certs",           # Fedora/RHEL
+        "/etc/openssl/certs",           # NetBSD
+        "/var/ssl/certs",               # AIX
+    ]
+
+    # optimization: reuse the values from a local varaible
+    if getattr(get_default_verify_paths, 'retval', None):
+        return get_default_verify_paths.retval
+
+    # This should never fail, it should always return SSL_CERT_FILE and SSL_CERT_DIR
     ofile_env = _str_from_buf(lib.X509_get_default_cert_file_env())
-    if ofile_env is None:
-        return None
+    odir_env = _str_from_buf(lib.X509_get_default_cert_dir_env())
+
+    # Platform depenedent
     ofile = _str_from_buf(lib.X509_get_default_cert_file())
-    if ofile is None:
-        return None
-    odir_env = _str_from_buf(lib.X509_get_default_cert_dir_env())
-    if odir_env is None:
-        return None
     odir = _str_from_buf(lib.X509_get_default_cert_dir())
-    if odir is None:
-        return odir
-    return (ofile_env, ofile, odir_env, odir);
+
+    if os.path.exists(ofile) and os.path.exists(odir):
+        get_default_verify_paths.retval = (ofile_env, ofile, odir_env, odir)
+        return get_default_verify_paths.retval
+
+    # OpenSSL didn't supply the goods. Try some other options
+    for f in certFiles:
+        if os.path.exists(f):
+            ofile = f 
+    for f in certDirectories:
+        if os.path.exists(f):
+            odir = f 
+    get_default_verify_paths.retval = (ofile_env, ofile, odir_env, odir)
+    return get_default_verify_paths.retval
+
 
 @ffi.callback("int(SSL*,unsigned char **,unsigned char *,const unsigned char *,unsigned int,void *)")
 def select_alpn_callback(ssl, out, outlen, client_protocols, client_protocols_len, args):


More information about the pypy-commit mailing list