Seeing SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib #557

Closed
stantonk opened this Issue Apr 19, 2012 · 34 comments

Projects

None yet
@stantonk

In our logs, I noticed this error when using requests to perform a POST to Facebook's Graph API using HTTPS:

File "/home/api/api/lib/python2.7/site-packages/requests/api.py", line 85, in post
    return request('post', url, data=data, **kwargs)
  File "/home/api/api/lib/python2.7/site-packages/requests/api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "/home/api/api/lib/python2.7/site-packages/requests/sessions.py", line 208, in request
    r.send(prefetch=prefetch)
  File "/home/api/api/lib/python2.7/site-packages/requests/models.py", line 584, in send
    raise SSLError(e)
SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

This is the first time I've seen it... could it be at all related to the cacerts file included in one of the dependencies of requests?

Is it related to this at all? #30

@kennethreitz

Do you have certifi installed?

@stantonk

Yessir. I just double checked on all our servers and ran pip freeze in each of our virtualenvs:

... snip ...
certifi==0.0.8
chardet==1.0.1
httplib2==0.7.2
requests==0.11.1
... snip ...

@kennethreitz

Hmm, can you do this?

import cerifi
print certifi.where()

And then make sure that file is readable?

@stantonk

I checked on all our servers:

import certifi
print certifi.where()
..snip../lib/python2.7/site-packages/certifi/cacert.pem

$ ll ../lib/python2.7/site-packages/certifi/cacert.pem
-rw-rw-r-- 1 ..snip.. Apr 19 18:29 ..snip../lib/python2.7/site-packages/certifi/cacert.pem

@kennethreitz

There shouldn't be a problem then :)

@kennethreitz

Is this when making any HTTPS request?

@stantonk

Sorry, I thought I mentioned earlier, this is the first time I've ever seen the issue in the logs, and we're doing an awful lot of https requests, so maybe it's just an anomaly, some malformed packet or something...maybe a neutrino ;-)

@stantonk stantonk closed this Apr 20, 2012
@stantonk

Letcha know if I see this more...

@gkappel

I am seeing this same error

SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

@gkappel

Clarification, For me error is only happening when program is packaged by pyinstaller

@gytisgreitai

I'm having the same problem. I'm using ActivePython and Windows 7 64 bit:

requests.exceptions.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509
certificate routines:X509_load_cert_crl_file:system lib

Program:

import requests
r = requests.get('https://github.com/timeline.json')
print r

i have all the packages mentioned in this thread and certifi.where() prints out
C:\Python27\lib\site-packages\certifi\cacert.pem
File exists and is readable.

Any ideas ?

@stantonk stantonk reopened this May 11, 2012
@sahilgupta

@gkappel:

I also faced a similar error when using pyinstaller with Httplib2.
You need to explicitly pass the path to ssl client cert file to the 'cert' argument http request. Also, you would need to package your. .pem file as a data file in pyinstaller.

Hope it helps!

@pjwerneck

@sahilgupta

That works! Thanks a lot.

@seanfisk

@sahilgupta Could you elaborate on how you fixed this? I'm having this problem as well and it would be great to know your solution.

@sahilgupta

I did something like this:

import certifi
print certifi.where()
..snip../lib/python2.7/site-packages/certifi/cacert.pem

to get a cert file and then copied it to somewhere in my python project directory.

h = httplib2.Http(ca_certs= '/this/new/path/to/cacert.pem')

To package this .pem file as a data file with pyinstaller, follow:
http://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile

I don't have the exact code lying around at the moment, so you might have to play a bit to get it working. I guess ideally we shouldn't need to do all this because httplib2 comes with a cert file of its own, but pyinstaller probably fails to pack this alongwith and hence the call fails from a binary compiled with pyinstaller.

Anyways, hope this helps!

@seanfisk

@sahilgupta Thanks for the help! I think I've figured out how to package the data file with PyInstaller, but I couldn't figure out how to pass that to requests to use, and I've already got enough code that uses requests that I'm not willing to switch to httplib2. For now, I've just disabled SSL verification.

@sahilgupta

@seanfisk Did some further digging. Specifying certificate is even easier in requests than with httplib2. Try something on the lines of :

os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/cacert.pem'

and enable SSL verification.
This would force requests to use this certificate instead of the default one as per http://kennethreitz.com/major-progress-for-requests.html

@seanfisk

@sahilgupta Thanks, that worked. It was actually a RTFM on my part. Checked the SSL Verification section in the requests documentation and it was right there, and now it works. I could swear I was passing the path to verify before, but it's working now, so who cares. Here's the code I used for future reference:

#!/usr/bin/env python
# requests_ssl.py
# main script

import requests
import os
import sys

# stolen and adpated from <http://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile>
def resource_path(relative):
    return os.path.join(getattr(sys, '_MEIPASS', os.path.abspath(".")),
                        relative)

cert_path = resource_path('cacert.pem')
# this would also work, but I'd rather not set unnecessary env vars
# os.environ['REQUESTS_CA_BUNDLE'] = cert_path
print requests.get('https://www.google.com/', verify=cert_path).text
# PyInstaller spec file
a = Analysis(
    ['requests_ssl.py'],
    pathex=['.'],
    hiddenimports=[],
    hookspath=None)
a.datas.append(('cacert.pem', 'cacert.pem', 'DATA'))
pyz = PYZ(a.pure)
exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    name=os.path.join('dist', 'requests_ssl'),
    debug=False,
    strip=None,
    upx=True,
    console=True)

Thanks for your help!

@sahilgupta

Cool! Glad that you got it working :)

@viciu

I had the same error on fedora based system and pip install certifi solved the issue.
I had installed requests via pip before, but on that particular machine certifi was not installed automatically when pip install requests.

Versions:

requests==0.14.2
certifi==0.0.8

Note, that on debian squeeze or mac I didn't have this issue and I didn't need to install certifi by hand.

@sigmavirus24
Collaborator
@slingamn

This is unfortunate; Requests is now supposed to use the system certificate bundle /etc/pki/tls/certs/ca-bundle.crt on Fedora by default, without requiring certifi.

@sigmavirus24
Collaborator

@slingamn is it possible @viciu doesn't have that path? Maybe some other package he's installed removed it/replaced it/moved it?

@slingamn

Yeah, that's possible. This can be tested by inspecting the following values:

import requests.utils
# this is the theoretical OS-packaged CA bundle, if available
print requests.utils.get_os_ca_bundle_path()
# this is the path that is used in practice
print requests.utils.DEFAULT_CA_BUNDLE_PATH
@slingamn

Actually, heh. Ever since c3ad7af, the OS bundle path is a no-op since a CA bundle (requests/cacert.pem) is versioned together with Requests.

@slingamn slingamn reopened this Dec 17, 2012
@Lukasa
Collaborator

@slingamn: Given #1065 (which was opened after a discussion on #1033), can we close this?

@sigmavirus24
Collaborator

@Lukasa I'm for closing it.

@Lukasa
Collaborator

Let's do it. We can always reopen it.

@Lukasa Lukasa closed this Jan 26, 2013
@zopyx

I see a similar problem while running bandersnatcher on Ubuntu 10.04 LTS
bandersnatch==1.0dev
cov-core==1.7
coverage==3.6
distribute==0.6.35
mercurial==2.5.2
mock==1.0.1
py==1.4.13
pytest==2.3.4
pytest-cov==1.6
requests==1.1.0
virtualenv==1.6.1
wsgiref==0.1.2

2013-03-26 17:25:49,493 ERROR: Error syncing package: OpenCorePaste
Traceback (most recent call last):
File "/srv/pypi/lib/python2.7/site-packages/bandersnatch-1.0dev-py2.7.egg/bandersnatch/package.py", line 56, in sync
self.sync_release_files()
File "/srv/pypi/lib/python2.7/site-packages/bandersnatch-1.0dev-py2.7.egg/bandersnatch/package.py", line 74, in sync_release_files
self.download_file(release_file['url'], release_file['md5_digest'])
File "/srv/pypi/lib/python2.7/site-packages/bandersnatch-1.0dev-py2.7.egg/bandersnatch/package.py", line 137, in download_file
r = requests.get(url, stream=True)
File "/srv/pypi/lib/python2.7/site-packages/requests-1.1.0-py2.7.egg/requests/api.py", line 55, in get
return request('get', url, *kwargs)
File "/srv/pypi/lib/python2.7/site-packages/requests-1.1.0-py2.7.egg/requests/api.py", line 44, in request
return session.request(method=method, url=url, *
kwargs)
File "/srv/pypi/lib/python2.7/site-packages/requests-1.1.0-py2.7.egg/requests/sessions.py", line 279, in request
resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
File "/srv/pypi/lib/python2.7/site-packages/requests-1.1.0-py2.7.egg/requests/sessions.py", line 374, in send
r = adapter.send(request, **kwargs)
File "/srv/pypi/lib/python2.7/site-packages/requests-1.1.0-py2.7.egg/requests/adapters.py", line 213, in send
raise SSLError(e)
SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

The error happens with https downloads from PyPI.

@hbrls

I'm experiencing this when import from a zip file. Copy the cacert.pem to approot will solve it:

os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(app_root, 'cacert.pem')

I have not set up a clean env to reproduce it, but I have tested it in my app and narrow down it to be zip related.

FYI, the zip file way is how my cloud-host suggested to upload virtualenv packages. It's like:

# bundle_it.sh
cp ./virtualenv.bundle/requests/cacert.pem ./cacert.pem
cd virtualenv.bundle/
zip -r ../virtualenv.bundle.zip .
# index.wsgi
sys.path.insert(0, os.path.join(app_root, 'virtualenv.bundle.zip'))
@mgoveas

I had the same issue while trying to get data from Google API. I have Tornado and installed the google python api client and was working my way through the calendar api example on localhost.
File "app.py", line 2716, in handle_redirected_url
credentials = ImportContactHandler.flow.step2_exchange(code)
File "build/bdist.macosx-10.7-intel/egg/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(args, *kwargs)
File "build/bdist.macosx-10.7-intel/egg/oauth2client/client.py", line 1283, in step2_exchange
headers=headers)
File "/Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 1570, in request
(response, content) = self.request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/__init_
.py", line 1317, in request
(response, content) = self.conn_request(conn, request_uri, method, body, headers)
File "/Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/__init
.py", line 1252, in conn_request
conn.connect()
File "/Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/__init_
.py", line 1021, in connect
self.disable_ssl_certificate_validation, self.ca_certs)
File "/Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 80, in ssl_wrap_socket
cert_reqs=cert_reqs, ca_certs=ca_certs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 346, in wrap_socket
ciphers=ciphers)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 121, in __init_

ciphers)
SSLError: [Errno 185090050] _ssl.c:336: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

To fix it I changed the permission of this file /Library/Python/2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/cacerts.txt after figuring out which ca_certs was being used to contact the Google API

@cdujeu cdujeu referenced this issue in pydio/pydio-sync Jun 27, 2014
Closed

Cannot log to an HTTPS server #33

@rwolst

I got the issue when using py2exe. To fix it, in httplib2/__init__.py around line 40 I added a check to see whether cacerts.txt is in the current directory and if it is, use that version:

try:
    import ssl # python 2.6
    ssl_SSLError = ssl.SSLError
    def _ssl_wrap_socket(sock, key_file, cert_file,
                         disable_validation, ca_certs):
        if disable_validation:
            cert_reqs = ssl.CERT_NONE
        else:
            cert_reqs = ssl.CERT_REQUIRED
        # We should be specifying SSL version 3 or TLS v1, but the ssl module
        # doesn't expose the necessary knobs. So we need to go with the default
        # of SSLv23.

        ############Added myself###########
        #We look for cacerts.pem in current directory
        if os.path.exists('./cacerts.txt'):
            #print 'ca_certs in directory'
            ca_certs = './cacerts.txt'
        ##################################

        return ssl.wrap_socket(sock, keyfile=key_file, certfile=cert_file,
                               cert_reqs=cert_reqs, ca_certs=ca_certs)

All you need to do now is copy the cacerts.txt from the http2 folder into your project directory, include it in your setup.py and then run the py2exe converter.

@sigmavirus24
Collaborator

@rwolst I think you have the wrong project altogether.

@dersteppenwolf dersteppenwolf referenced this issue in gkudos/qgis-cartodb Sep 20, 2014
Merged

Fix certificate error on mac #3

@AlexVonB

@rwolst Thank you! Your addition to httplib2/__init__.py did the trick for me!

@Lukasa Lukasa locked and limited conversation to collaborators Oct 15, 2014
@tomoemon tomoemon added a commit to tomoemon/zaffy that referenced this issue Dec 13, 2014
@tomoemon tomoemon fix ssl verification error 7200181
@hamstah hamstah added a commit to hamstah/mallard that referenced this issue Feb 24, 2015
@hamstah hamstah Added certifi to requirements 423798b
@degemer degemer added a commit to DataDog/dd-agent that referenced this issue Jul 16, 2015
@degemer degemer [windows] add flare function
Add a Windows flare function inside the GUI, using only popups (because it's
the easiest way to do this).

Drawback: disable SSL verification (was somehow
failing with an error like
kennethreitz/requests#557)
7df479b
@degemer degemer added a commit to DataDog/dd-agent that referenced this issue Jul 16, 2015
@degemer degemer [windows] add flare function
Add a Windows flare function inside the GUI, using only popups (because it's
the easiest way to do this).

Drawback: disable SSL verification (was somehow
failing with an error like
kennethreitz/requests#557)
812d1bb
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.