New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSL Error: bad handshake #3212
Comments
Could you please tell us how you've installed requests and what version you've installed? |
This is almost certainly an SNI problem, so depending on how the library was installed we may need to add some optional dependencies. |
requests was installed as dependency for smartsheet-python-sdk via pip:
|
Removed package in pip and installing from yum won't help... |
@pensnarik Can you try running |
Thak you, Lukasa, for your advice, but it did not help... [mutex@unica1 parser]$ sudo pip install -U requests[security]
[sudo] password for mutex:
Collecting requests[security]
Using cached requests-2.10.0-py2.py3-none-any.whl
Collecting pyOpenSSL>=0.13 (from requests[security])
Using cached pyOpenSSL-16.0.0-py2.py3-none-any.whl
Collecting ndg-httpsclient (from requests[security])
Requirement already up-to-date: pyasn1 in /usr/lib/python2.7/site-packages (from requests[security])
Collecting cryptography>=1.3 (from pyOpenSSL>=0.13->requests[security])
Using cached cryptography-1.3.2.tar.gz
Requirement already up-to-date: six>=1.5.2 in /usr/lib/python2.7/site-packages (from pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: idna>=2.0 in /usr/lib/python2.7/site-packages (from cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: setuptools>=11.3 in /usr/lib/python2.7/site-packages (from cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: enum34 in /usr/lib/python2.7/site-packages (from cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: ipaddress in /usr/lib/python2.7/site-packages (from cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: cffi>=1.4.1 in /usr/lib64/python2.7/site-packages (from cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Requirement already up-to-date: pycparser in /usr/lib/python2.7/site-packages (from cffi>=1.4.1->cryptography>=1.3->pyOpenSSL>=0.13->requests[security])
Building wheels for collected packages: cryptography
Running setup.py bdist_wheel for cryptography ... done
Stored in directory: /root/.cache/pip/wheels/14/df/02/611097a49d7739151deb68d0172dff5ae7cba01b82769e56ef
Successfully built cryptography
Installing collected packages: cryptography, pyOpenSSL, ndg-httpsclient, requests
Found existing installation: requests 2.6.0
DEPRECATION: Uninstalling a distutils installed project (requests) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
Uninstalling requests-2.6.0:
Successfully uninstalled requests-2.6.0
Successfully installed cryptography-1.3.2 ndg-httpsclient-0.4.0 pyOpenSSL-16.0.0 requests-2.10.0
You are using pip version 8.1.0, however version 8.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
[mutex@unica1 parser]$ ./update_region_price.py
Traceback (most recent call last):
File "./update_region_price.py", line 129, in <module>
sys.exit(app.run(sys.argv))
File "./update_region_price.py", line 122, in run
self.update_basic()
File "./update_region_price.py", line 65, in update_basic
sheet = self.sm.Sheets.get_sheet(self.sheet_id, page_size=5000)
File "/usr/lib/python2.7/site-packages/smartsheet/sheets.py", line 460, in get_sheet
response = self._base.request(prepped_request, expected, _op)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 178, in request
res = self.request_with_retry(prepped_request, operation)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 242, in request_with_retry
return self._request(prepped_request, operation)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 208, in _request
res = self._session.send(prepped_request, stream=stream)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 585, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 477, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)",) |
Are you able to show me what host you're connecting to? |
Lukasa, of course: https://api.smartsheet.com/2.0, I'm using python wrapper for smartsheet API (https://github.com/smartsheet-platform/smartsheet-python-sdk). |
And do you happen to have |
Yes, I have: [mutex@unica1 parser]$ pip show certifi
---
Metadata-Version: 2.0
Name: certifi
Version: 2016.2.28
Summary: Python package for providing Mozilla's CA Bundle.
Home-page: http://certifi.io/
Author: Kenneth Reitz
Author-email: me@kennethreitz.com
Installer: pip
License: ISC
Location: /usr/lib/python2.7/site-packages
Requires:
Classifiers:
Development Status :: 5 - Production/Stable
Intended Audience :: Developers
Natural Language :: English
Programming Language :: Python
Programming Language :: Python :: 2.5
Programming Language :: Python :: 2.6
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3.0
Programming Language :: Python :: 3.1
Programming Language :: Python :: 3.2
Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4 |
Aha, ok, we got there.
That's not normally a problem, except:
You can solve this in two ways. The first, better but more drastic way, is to upgrade your OpenSSL to 1.0.2 or later. This is hard to do on Centos, I'm afraid. The less good but more effective way is to get the output of running |
Argh, the smartsheet SDK overrides that environment variable by explicitly using certifi. New plan. Right at the start after you import smartsheet, before you do anything else, can you add the following lines? import smartsheet.session
import certifi
smartsheet.session._TRUSTED_CERT_FILE = certifi.old_where() That should hopefully help. You shouldn't need the environment variable with this approach. |
Unfortunately, it does not work even if I change this line in /usr/lib/python2.7/site-packages/smartsheet/session.py: _TRUSTED_CERT_FILE = certifi.where() to _TRUSTED_CERT_FILE = certifi.old_where() When I change this var from my code, It does not helps too... |
At this point, I'm pretty confident this is not a bug in requests and is in fact a problem with the smartsheet API wrapper. Have you tried reporting this to them? |
Hrm. Are you confident that that code is being executed? Can you use print statements to confirm that it's being used? |
Downgrading certifi from 2015.11.20.1 to 2015.4.28 fixes the problem! |
ubuntu@ip-172-31-58-148:
This is my input to this problem. It doe snot happen with every https request. |
@sProject You would need to resolve both of those warnings before we can determine if you have a new problem. If you got requests from pip, run |
This bug appears to have been resolved over two months ago. If I'm incorrect in this conclusion and there is still a bug to be found in requests, I'll be happy to reopen this. Thanks everyone for collaborating on requests! |
certifi==2015.4.28 https://github.com/kennethreitz/requests/issues/3212 Browsers and certificate authorities have concluded that 1024-bit keys are unacceptably weak for certificates, particularly root certificates. For this reason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its bundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key) certificate from the same CA.
The example from pygodaddy raises the same exception
Downgrading certifi as suggested by @pensnarik does not fix it. This is Fedora 24, Python 2.7.12.
|
GoDaddy is serving an incomplete certificate chain to you. That means we're missing one of the intermediate certificates and can't build up a trust chain. Either you'll need to add the missing intermediary certificate to the certifi trust store or you'll need to contact GoDaddy and tell them to sort their mess out. |
@Lukasa how can one check if the problem is with requests or certificate issuer? Full traceback
installed packages
Cert details
|
The problem is almost certainly not with the issuer, but with your server. Can you show me the output of running |
I am not sure that I used the command right, but that's someting:
|
Yup, so the server is wrong. This is a really common problem with TLS. A TLS certificate validation is performed by first building a certificate chain that takes us from a certificate the server can prove it has the private key for (the "leaf") to a certificate we trust (the "root"). For OpenSSL there is an additional rule: the root must be self-signed. In most cases, this chain is more than two steps long: that is, the leaf is not signed by the root, but is instead signed by a so-called intermediate certificate. That intermediate may itself be signed by the root, but may also be signed by other intermediates, until we eventually reach an intermediate that was signed by a root. For example, for https://python-hyper.org, the chain is as follows:
The correct chain for the site you're accessing should be:
For your use case, Requests ships with certificate number 3 in its trust database as a trusted root. However, your server is only sending certificate number 1. Requests cannot go from certificate 1 to certificate 3 without having certificate 2, and the server isn't sending it. Most browsers ship with commonly-used intermediate certs, or can maintain caches of them, but Requests cannot do that, so it has no way of getting hold of certificate 2. Without certificate 2, validation must fail. Properly-configured TLS servers send the leaf certificate and all of the necessary intermediaries. This is to ensure that clients that have never seen the intermediaries and that cannot dynamically fetch them are still able to validate the chain. As a comparison, check out the output of a command like yours run against
Note that the server sent two certificates in my case, whereas in yours it only sent one. This is the error. Please reconfigure your server to send all the relevant intermediaries as well as the leaf. While I'm here, I should note that running Qualys SSL Labs against your server would also have told you about this problem. =) |
Thanks @Lukasa for this educational reply you gave! Really appreciate and sorry for troubling with this, it was my TLS-knowledge-gap =) Mostly I went to issues because in was all good in browsers and didn't work in requests. But now its clear to me what is the root cause. I believe there is no workaround (download intermediate cert upfront) for this case, but to reconfigure the server? For the time being I will skip verification checks |
@hellt No need to apologise: this is a thing that is extremely non-obvious and it's a really common error to make, so you're in good company here. =) There is a workaround, in fact. You can pass a certificate bundle to |
Luka, Q |
Seems like you are having trouble validating the TLS certificates from PyPI. However, that error message is a bit surprising. I don't entirely know where it is coming from, but it suggests a problem either with the way your pip is configured or with your Python. Do you encounter similar errors with other python packages? |
Hello All, import requests SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",) Does any one know how to add certificates for Python ? Will that help to get this resolved? |
@ajitmuley5 while you're using Requests, questions such as yours belong on StackOverflow. Please post this there with the required amount of detail. There are people who will happily help you without starting discussions on old and closed issues. |
@Lukasa Thanks ! sudo pip install -U requests[security] worked for me. |
Thanks all, I got some ideas! |
I could not use your lib in CeontOS 7 with Python 2.7.5. I got this error:
Updating of Python or any SSL libs didn't help. I've got this error in CentOS and Ubuntu, in Arch Linux everything works well.
The text was updated successfully, but these errors were encountered: