Repository: pypa/pip

Issue:
Pip 8.0.1 throws SSL: CERTIFICATE_VERIFY_FAILED
Upgrade to pip 8.0.1 on Python 2.7.5 and can no longer use pip install...

Example:

```
Collecting pip
  Using cached pip-8.0.1-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 8.0.0
    Uninstalling pip-8.0.0:
      Successfully uninstalled pip-8.0.0
Successfully installed pip-8.0.1
Could not fetch URL https://pypi.python.org/simple/setuptools/: There was a problem confirming the ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:765) - skipping
Requirement already up-to-date: setuptools in ./env/lib/python2.7/site-packages
Collecting flasgger==0.5.10 (from -r scripts/requirements.txt (line 2))
  Could not fetch URL https://pypi.python.org/simple/flasgger/: There was a problem confirming the ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:765) - skipping
  Could not find a version that satisfies the requirement flasgger==0.5.10 (from -r scripts/requirements.txt (line 2)) (from versions: )
No matching distribution found for flasgger==0.5.10 (from -r scripts/requirements.txt (line 2))
```



Discussion:
What OS?

This is on CentOS Linux release 7.2.1511 (Core)

I see the same issue on CentOS Linux release 7.2.1511 (Core) (as a docker container).

What does `python -c "import ssl; print(ssl.get_default_verify_paths())"` give you?

[root@a81f5f2b0fe8 /]# python -c "import ssl; print(ssl.get_default_verify_paths())"
DefaultVerifyPaths(cafile='/etc/pki/tls/cert.pem', capath='/etc/pki/tls/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/etc/pki/tls/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/etc/pki/tls/certs')

Look the same for me as well:

```
DefaultVerifyPaths(cafile='/etc/pki/tls/cert.pem', capath='/etc/pki/tls/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/etc/pki/tls/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/etc/pki/tls/certs')
```

Is anything in `/etc/pki/tls/certs`?

```
[root@ac3505a069c3 /]# ls -la /etc/pki/tls/certs
total 8
drwxr-xr-x 2 root root 4096 Jan  7 18:37 .
drwxr-xr-x 8 root root 4096 Jan 21 20:35 ..
lrwxrwxrwx 1 root root   49 Dec 23 18:08 ca-bundle.crt -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
lrwxrwxrwx 1 root root   55 Dec 23 18:08 ca-bundle.trust.crt -> /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
```

Ugh.

So CentOS ships with a broken OpenSSL CAPath value set (I think? that or request's ability to us a CAPath is broken), which 8.0.1 switched to trusting a CAPath because Debian ships a broken CAFile. 

That would make some sense... have a project using requests 2.9.1 and have to manually specify path to a pem containing cert chain with '''verify=''' key word argument. Even after running the pem through update-ca-trust...

Jumping into requests rabbit hole now...

I'm seeing this on Fedora 22 as well as centos7. @dstufft 

I'm going to be cutting a new 8.0.2 and we're just going to stop trying to trust the OS provided SSL certificates, because apparently nobody can manage to ship an unbroken OpenSSL.


Resolving patch:
diff --git a/pip/cmdoptions.py b/pip/cmdoptions.py
--- a/pip/cmdoptions.py
+++ b/pip/cmdoptions.py
@@ -17,7 +17,7 @@
     FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary,
     fmt_ctl_no_use_wheel)
 from pip.models import PyPI
-from pip.locations import CA_BUNDLE_PATH, USER_CACHE_DIR, src_prefix
+from pip.locations import USER_CACHE_DIR, src_prefix
 from pip.utils.hashes import STRONG_HASHES
 
 
@@ -197,7 +197,6 @@ def exists_action():
     '--cert',
     dest='cert',
     type='str',
-    default=CA_BUNDLE_PATH,
     metavar='path',
     help="Path to alternate CA bundle.")
 
diff --git a/pip/locations.py b/pip/locations.py
--- a/pip/locations.py
+++ b/pip/locations.py
@@ -4,7 +4,6 @@
 import os
 import os.path
 import site
-import ssl
 import sys
 
 from distutils import sysconfig
@@ -14,52 +13,6 @@
 from pip.utils import appdirs
 
 
-# if the Python we're running on is new enough to have the needed API then
-# we'll ask OpenSSL to give us the path to the default CA Bundle. If this API
-# doesn't exist or we cannot resolve the path to an existing file, then we will
-# simply set this to None. Setting this to None will have requests fall back
-# and use it's default CA Bundle logic.
-# Ever since requests 2.9.0, requests has supported a CAPath in addition to a
-# CAFile, because some systems (such as Debian) have a broken CAFile currently
-# we'll go ahead and support both, prefering CAPath over CAfile.
-if getattr(ssl, "get_default_verify_paths", None):
-    _ssl_paths = ssl.get_default_verify_paths()
-
-    # Ok, this is a little hairy because system trust stores are randomly
-    # broken in different and exciting ways and this should help fix that.
-    # Ideally we'd just not trust the system store, however that leads end
-    # users to be confused on systems like Debian that patch python-pip, even
-    # inside of a virtual environment, to support the system store. This would
-    # lead to pip trusting the system store when creating the virtual
-    # environment, but then switching to not doing that when upgraded to a
-    # version from PyPI. However, we can't *only* rely on the system store
-    # because not all systems actually have one, so at the end of the day we
-    # still need to fall back to trusting the bundled copy.
-    #
-    # Resolution Method:
-    #
-    # 1. We prefer a CAPath, however we will *only* prefer a CAPath if the
-    #    directory exists and it is not empty. This works around systems like
-    #    Homebrew which have an empty CAPath but a populated CAFile.
-    # 2. Failing that, we prefer a CAFile, however again we will *only* prefer
-    #    it if it exists on disk and if it is not empty. This will work around
-    #    systems that have an empty CAFile sitting around for no good reason.
-    # 3. Finally, we'll just fall back to letting requests use it's bundled
-    #    CAFile, which can of course be overriden by the end user installing
-    #    certifi.
-    if _ssl_paths.capath is not None and os.listdir(_ssl_paths.capath):
-        CA_BUNDLE_PATH = _ssl_paths.capath
-    elif _ssl_paths.cafile is not None and os.path.getsize(_ssl_paths.cafile):
-        CA_BUNDLE_PATH = _ssl_paths.cafile
-    else:
-        CA_BUNDLE_PATH = None
-else:
-    # If we aren't running on a copy of Python that is new enough to be able
-    # to query OpenSSL for it's default locations, then we'll only support
-    # using the built in CA Bundle by default.
-    CA_BUNDLE_PATH = None
-
-
 # Application Directories
 USER_CACHE_DIR = appdirs.user_cache_dir("pip")
 


Test patch: