If I run the following command from my development box:
$ openssl s_client -connect github.com:443
I get the following last line of output:
Verify return code: 20 (unable to get local issuer certificate)
If I try to do this with requests I get another failed request:
>>> import requests
>>> r = requests.get('https://github.com/', verify=True)
With an exception raised:
SSLError: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I can also run the first command with the verify flag and get similar output:
$ openssl s_client -connect github.com:443 -verify 9
...
Verify return code: 27 (certificate not trusted)
Basically this is telling me that there is a problem with the certificates. I can specify a specific certificate with both methods and it will work:
$ openssl s_client -connect github.com:443 -CAfile /etc/ssl/certs/DigiCert_High_Assurance_EV_Root_CA.pem -verify 9
...
Verify return code: 0 (ok)
and:
>>> r = requests.get('https://github.com/', verify='/etc/ssl/certs/DigiCert...pem')
<Response [200]>
So, to my question, what exactly is wrong here? Shouldn't requests/openssl already know where to find valid certs?
Other Info:
- Python==2.7.6
- requests==2.2.1
- openssl 0.9.8h
Also, I know passing verify=False
to the requests.get
method will work too, but I do want to verify.
EDIT
I've confirmed that, as @Heikki Toivonen indicated in an answer, specifying the -CAfile flag for the version of openssl that I'm running works.
$ openssl s_client -connect github.com:443 -CAfile `python -c 'import requests; print(requests.certs.where())'`
...
Verify return code: 0 (ok)
So there is nothing wrong with the version of openssl that I'm running, and there is nothing wrong with the default cacert.pem file that requests provides.
Now that I know openssl is meant to work that way, that the CAfile or the place to find certs has to be specified, I'm more concerned about getting requests to work.
If I run:
>>> r = requests.get('https://github.com/', verify='path to cacert.pem file')
I'm still getting the same error as before. I even tried downloading the cacert.pem file from http://curl.haxx.se/ca and it still didn't work. requests only seems to work (on this specific machine) if I specify a specific vendor cert file.
A side note: On my local machine everything is working as expected. There are several difference between the two machines though. I so far haven't been able to determine what the specific difference is that causes this issue.
See Question&Answers more detail:
os