8

This is a followup to SSLError using requests for python:

I have just installed requests on a Mac OSX 10.8.5. My first attempt at doing requests.get failed on missing certificate:

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

  • The thread above says to look for /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/re‌​quests/cacert.pem but actually I don't even have a .../site-packages/requests directory. It's not clear to me if this should have been added by the installation (I used pip)

  • Further threads and the requests docs say to install certifi, so I did. But now I get a different error:

    python -c 'import requests; requests.get("https://api.github.com/events")'    /usr/lib/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
      InsecurePlatformWarning
    Traceback (most recent call last):
    ...
      File "/usr/lib/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
        raise SSLError(e, request=request)
    requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
    

Thanks!

Community
  • 1
  • 1
Gideon Av
  • 111
  • 1
  • 1
  • 7

1 Answers1

9

Notice that you're using HTTPS. As mentioned in the Requests manual

To check a host’s SSL certificate, you can use the verify argument [...] By default, verify is set to True

Here are few ways to fix that:

Update OpenSSL (probably will solve your problem)

Taken from here:

If you encounter one of the following errors:

error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm
The software you are using might be compiled with a version too old of OpenSSL that does not take certificates signed with sha256WithRSAEncryption into account.

It requires at least OpenSSL 0.9.8o for a total management of SHA256. OpenSSl 0.9.7m only assures a partial management, for server mode only.

Check your openssl version by

openssl version
OpenSSL 1.0.1k-fips 8 Jan 2015

If you have a smaller version than OpenSSL0.9.8o, you have to update its version (OS X):

brew update
brew install openssl
brew link --force openssl

If that doesn't work, try this way:

brew uninstall openssl
rm -rf /usr/local/openssl
brew install openssl
  • there's an issue with openssl installed before OS X 10.10.3 and reinstalling it fixes it
  • these command lines will uninstall openssl, remove its folder from your hard-disk and install it again (the updated version)

Install certifi

Taken from here

By default Requests bundles a set of root CAs that it trusts, sourced from the Mozilla trust store. However, these are only updated once for each Requests version. This means that if you pin a Requests version your certificates can become extremely out of date.

From Requests version 2.4.0 onwards, Requests will attempt to use certificates from certifi if it is present on the system. This allows for users to update their trusted certificates without having to change the code that runs on their system.

For the sake of security we recommend upgrading certifi frequently!

In other word, try to install certifi, if you have Request 2.4.0 or newer:

pip install certifi

Hopefully, this will fix the problem.

Use different version of OpenSSL and Requests

Looking into it using Google, I have found that there is a problem with OpenSSL in Python 2:

However, I am using Python 2.7.6, Requests 2.2.1 and OpenSSL 1.0.1f 6 Jan 2014 and everything runs correctly.

Pass the certificate

In other cases, you may need to tell requests.get the path to the certificate file, if the host's certificate was signed by you.

requests.get("https://api.github.com/events", verify=True, cert=['/path/to/my/ca.crt'])

Set the verify argument to False (NOT RECOMMENDED!)

In case you want to avoid the certificate verification, you have to pass verify=False to the request.get method.

python -c 'import requests; requests.get("https://api.github.com/events", verify=False)'

or from script.py file:

import requests
res = requests.get("https://api.github.com/events", verify=False)
print res

terminal:

$ python script.py
<Response [200]>

Important: Very bad idea; You can be MITM attacked, which is a critical security vulnerability.

boaz_shuster
  • 2,825
  • 20
  • 26
  • 2
    Please never suggest to disable certificate validation without describing the negative effects (man-in-the-middle attack) and that it should only be used for testing or if security is otherwise not relevant. – Steffen Ullrich Jun 14 '15 at 16:11
  • @SteffenUllrich but that's what I did. I didn't mention MITMA but I did say "*trust* the host". Isn't that good enough? – boaz_shuster Jun 14 '15 at 16:14
  • 1
    That's not the question of trusting the host. TLS does not say anything about how trusted the host is, only if the certificate matches the hostname and was issued by a trusted CA. You might not trust `attacker.example.com` but the certificate might still be fine. The problem with disabling validation is that you don't know if you talk to the host at all. – Steffen Ullrich Jun 14 '15 at 16:15
  • @SteffenUllrich, can you review my updated post, please? 10x. – boaz_shuster Jun 14 '15 at 16:40
  • Yes I was using https -- that's the example in the requests doc. – Gideon Av Jun 15 '15 at 22:56
  • @GideonAv, that's great. Then, I am guessing the problem is that you have an old version of `openssl`. did you read my post and update it? – boaz_shuster Jun 16 '15 at 06:22
  • See above: version appears to be up to date: `OpenSSL 0.9.8y 5 Feb 2013` – Gideon Av Jun 17 '15 at 10:33
  • @GideonAv, read https://github.com/docker/docker-py/issues/465#issuecomment-76520363, https://github.com/Homebrew/homebrew/issues/38226 and https://github.com/docker/compose/issues/1484. It seems Requests 2.5.x has problems with different versions of OpenSSL. But I am running Requests 2.2.1 and OpenSSL 1.0.1k and it works fine... so try to use these versions and let me know. – boaz_shuster Jun 17 '15 at 15:52
  • @GideonAv, hey! I was wondering if my answer helped you resolve the problem. Notice, I have updated it more than once, since the last time. Please, let me know. – boaz_shuster Jun 21 '15 at 06:31
  • I gave up, because it looks like keeping OpenSSL up-to-date is too much of a hassle. But thanks for the suggestions of course. – Gideon Av Jun 22 '15 at 10:50
  • @GideonAv sorry for bothering you but as i suggested in my answer, you can use a newer version of Requests (2.4.0+) and install certifi too. this will take the updating OpenSSL out of the equation. Did you try it? – boaz_shuster Jun 22 '15 at 11:33
  • @bshuster13 as far as I can tell this is the newest version -- I used 'pip install' on June 14 and checked again with --upgrade today. I just noticed this: `/usr/lib/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.` – Gideon Av Jun 24 '15 at 02:37
  • So, now you don't get any certification error, right? To fix this insecure warning, read these threads: http://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package and http://stackoverflow.com/questions/29134512/insecureplatformwarning-a-true-sslcontext-object-is-not-available-this-prevent – boaz_shuster Jun 24 '15 at 11:24
  • @GideonAv -- hey! Just wanted to know if there is anything new? Did you check my comment above? did it fix your problem? Thanks. – boaz_shuster Jun 29 '15 at 11:08
  • @bshuster13 Like I said, I gave up on this package. (I was able to do what I needed with urllib2.Request) – Gideon Av Jun 30 '15 at 11:38