I came across some interesting results when researching this problem. It seems to me that this could be the problem. Let me know.
TL;DR
Try using certifi.old_where()
. If that works, then you really should upgrade to a newer version of OpenSSL on your server.
Sources
GitHub:
https://github.com/certifi/python-certifi/issues/32
From @Lukasa
Can you confirm whether or not this is the same problem as #26? That is, try passing certifi.old_where() to the verify argument of requests.
...
To be clear, there is no fix for this from Python-land other than using certifi.old_where() or upgrading OpenSSL. The OpenSSL on your system is too old to properly verify cross-signed TLS certificates, and three is no way for that problem to be resolved on my end. Your system is being put at significant risk if you use certifi.old_where() because you are continuing to base your trust on 1024-bit RSA certificates, which have been being deprecated since 2012 and are subject to several known attacks already.
certifi Docs:
https://pypi.python.org/pypi/certifi
1024-bit Root Certificates
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. Because Mozilla removed these certificates from its bundle, certifi removed them as well.
Unfortunately, old versions of OpenSSL (less than 1.0.2) sometimes fail to validate certificate chains that use the strong roots. For this reason, if you fail to validate a certificate using the certifi.where() mechanism, you can intentionally re-add the 1024-bit roots back into your bundle by calling certifi.old_where() instead. This is not recommended in production: if at all possible you should upgrade to a newer OpenSSL. However, if you have no other option, this may work for you.