I'm stuck on a persistent SSL verification issue.
SSL: CERTIFICATE_VERIFY_FAILED
I discovered the error while building a Django app that had users authenticate using Mozilla Persona.
(python3.4)> import requests
(python3.4)> requests.get('https://verifier.login.persona.org')
I get a SSL: CERTIFICATE_VERIFY_FAILED tracing back from requests to urllib3 to ssl:
...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/ssl.py", line 805, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)
...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/requests-2.4.1-py3.4.egg/requests/packages/urllib3/connectionpool.py", line 543, in urlopen
raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)
...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/requests-2.4.1-py3.4.egg/requests/adapters.py", line 420, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)
Difference between python3 and python2
Here's where it starts to get interesting: I don't get the same issue when using python2.7:
(python2.7)> import requests
(python2.7)> requests.get('https://verifier.login.persona.org')
<Response [200]>
My first thought was that the two versions of requests might be using different certs[1], so I was pretty surprised to find the two files were exactly the same:
(bash)$ diff `python3.4 -c "import requests; print(requests.certs.where())"` \
`python2.7 -c "import requests; print requests.certs.where()"`
# no diff
Error recreated in openssl and solved using -CAFile
Interestingly, the issue is not limited to python3.4[2].
(bash)$ openssl s_client -connect github.com:443
...
Verify return code: 20 (unable to get local issuer certificate)
Edit A comment from Steffen informed me that this "debugging" method isn't actually informative, as s_client expects a -CApath in order to verify. However, the fact that I can specify the same certificate that the requests package is using and I don't get the same error is still interesting:
(bash)$ openssl s_client -connect github.com:443 \
-CAfile `python3 -c 'import requests; print(requests.certs.where())'`
...
Verify return code: 0 (ok)
At this point, I'm completely out of my element. I don't know is if this is really an openssl issue, or something about OSX Mavericks[3]. Here's the version of openssl I'm using:
(bash)$ openssl version
OpenSSL 1.0.1f 6 Jan 2014
Mavericks KeyChain.app
For OS-specific solutions, I've tried clearing my login KeyChain[4], to no avail.
Issues with pip
There's one last bit of evidence that may or may not be relevant. python3.4 ships with pip intact. However, the pip3 command is useless to me. No matter what I try to install:
(bash)$ pip3 install [new-lib] # pip 1.5.6
I get:
Downloading/unpacking [new-lib]
Cannot fetch index base URL https://pypi.python.org/simple/
Could not find any downloads that satisfy the requirement [new-lib]
Cleaning up...
No distributions at all found for [new-lib]
Storing debug log for failure in ~/.pip/pip.log
Although this isn't (explicitly) an SSL error, it seems similar[5] and a successful workaround has been to install an older version of pip using easy_install in my virtualenvs[5]. I'm crossing my fingers that the two issues are related.
Recap:
- Seeking possible solutions for SSL certificate failure error (without using
verify = Falsein therequestscalls). - I get the error in python3.4 but not python2.7 even though the cert.pem used in both cases is exactly the same.
- Though I can recreate an SSL error using
openssl s_client -connectI can avoid it by specifying-CAFileto the cert.pem used by the requests library. - My best guess is that this is an issue particular to Mavericks, but I have no idea how to proceed.
- I'm hoping to find a solution that also allows me to use pip3 to install python3.4 packages as expected.
Thanks for your help!
[1]: python2.7 on my machine was installed using Enthought. But installing a system version of python2.7 and the requests library works too.
[2]: See openssl, python requests error: "certificate verify failed" for a similar problem using python 2.7
[3]: It seems Mavericks introduced a change in openssl? http://curl.haxx.se/mail/archive-2013-10/0036.html
[4]: Clearning KeyChain.app from here: https://superuser.com/a/721629/261875
[5]: SSL error with pip3: https://stackoverflow.com/a/22051466/2506078