Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #85733 > unrolled thread
| Started by | John Nagle <nagle@animats.com> |
|---|---|
| First post | 2015-02-16 23:05 -0800 |
| Last post | 2015-02-17 14:57 -0800 |
| Articles | 7 — 2 participants |
Back to article view | Back to comp.lang.python
Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" John Nagle <nagle@animats.com> - 2015-02-16 23:05 -0800
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" Laura Creighton <lac@openend.se> - 2015-02-17 09:00 +0100
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" John Nagle <nagle@animats.com> - 2015-02-17 14:57 -0800
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" Laura Creighton <lac@openend.se> - 2015-02-18 00:42 +0100
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" John Nagle <nagle@animats.com> - 2015-02-17 16:28 -0800
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" Laura Creighton <lac@openend.se> - 2015-02-18 08:49 +0100
Re: Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" John Nagle <nagle@animats.com> - 2015-02-17 14:57 -0800
| From | John Nagle <nagle@animats.com> |
|---|---|
| Date | 2015-02-16 23:05 -0800 |
| Subject | Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com" |
| Message-ID | <mbup6k$vgt$1@dont-email.me> |
Python 2.7.9, Windows 7 x64.
(also 3.4.2 on Win7, and 3.4.0 on Ubuntu 14.04)
There's something about the SSL cert for "https://www.verisign.com"
that won't verify properly from Python. The current code looks
like this:
def testurlopen(host, certfile) :
port = httplib.HTTPS_PORT
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
context = ssl.create_default_context(cafile=certfile)
sock = context.wrap_socket(sk, server_hostname=host)
try:
sock.connect((host,port))
except EnvironmentError as message :
print("Connection to \"%s\" failed: %s." % (host, message))
return False
print("Connection to \"%s\" succeeded." % (host,))
return True
Works for "python.org", "google.com", etc. I can connect to and
dump the server's certificate for those sites. But for "verisign.com"
and "www.verisign.com", I get
Connection to "verisign.com" failed: [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed (_ssl.c:581).
The certificate file, "cacert.pem", comes from Mozila's list of
approved certificates, obtained from here:
http://curl.haxx.se/ca/cacert.pem
It has the cert for
"VeriSign Class 3 Public Primary Certification Authority - G5"
which is the root cert for "verisign.com".
After loading that cert file into an SSL context, I can dump the
context from Python with context.get_ca_certs()
and get this dict for that cert:
Cert: {'notBefore': u'Nov 8 00:00:00 2006 GMT',
'serialNumber': u'18DAD19E267DE8BB4A2158CDCC6B3B4A',
'notAfter': 'Jul 16 23:59:59 2036 GMT',
'version': 3L,
'subject': ((('countryName', u'US'),), (('organizationName', u'VeriSign,
Inc.'),),
(('organizationalUnitName', u'VeriSign Trust Network'),),
(('organizationalUnitName', u'(c) 2006 VeriSign, Inc. - For authorized
use only'),),
(('commonName', u'VeriSign Class 3 Public Primary Certification
Authority - G5'),)),
'issuer': ((('countryName', u'US
'),), (('organizationName', u'VeriSign, Inc.'),),
(('organizationalUnitName', u'VeriSign Trust Network'),),
(('organizationalUnitName', u'(c) 2006 VeriSign, Inc. - For authorized
use only'),), (('commonName', u'VeriSign Class 3 Public Primary
Certification Authority - G5'),))}
Firefox is happy with that cert. The serial number of the root
cert matches the root cert Firefox displays. So the root cert file
being used has the right cert for the cert chain back from
"www.verisign.com".
If I dump ssl.OPENSSL_VERSION from Python, I get "OpenSSL 1.0.1j 15 Oct
2014". That's an OK version.
Something about that cert is unacceptable to the Python SSL module, but
what? "CERTIFICATE VERIFY FAILED" doesn't tell me enough to
diagnose the problem.
John Nagle
[toc] | [next] | [standalone]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-02-17 09:00 +0100 |
| Message-ID | <mailman.18781.1424160053.18130.python-list@python.org> |
| In reply to | #85733 |
I've seen something like this: The requests module http://docs.python-requests.org/en/latest/ ships with its own set of certificates "cacert.pem" and ignores the system wide ones -- so, for instance, adding certificates to /etc/ssl/certs on your debian or ubuntu system won't work. I edited it by hand and then changed the REQUESTS_CA_BUNDLE environment variable to point to it. Perhaps your problem is along the same lines? Laura
[toc] | [prev] | [next] | [standalone]
| From | John Nagle <nagle@animats.com> |
|---|---|
| Date | 2015-02-17 14:57 -0800 |
| Message-ID | <54E3C75F.80307@animats.com> |
| In reply to | #85734 |
If I remove certs from my "cacert.pem" file passed to
create_default_context, the Python test program rejects domains
it will pass with the certs present. It's using that file.
So that's not it. It seems to be an OpenSSL or cert file
problem. I can reproduce the problem with the OpenSSL command
line client:
openssl s_client -connect www.verisign.com:443 -CAfile cacert.pem
fails for "www.verisign.com", where "cacert.pem" has been extracted
from Firefox's cert store.
The error message from OpenSSL
Verify return code: 20 (unable to get local issuer certificate)
Try the same OpenSSL command for other domains ("google.com",
"python.org") and no errors are reported. More later on this.
So it's not a Python level issue. The only Python-specific
problem is that the Python library doesn't pass detailed
OpenSSL error codes through in exceptions. The Python exception
text is "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
(_ssl.c:581).", which is a generic message for most OpenSSL errors.
John Nagle
On 2/17/2015 12:00 AM, Laura Creighton wrote:
> I've seen something like this:
>
> The requests module http://docs.python-requests.org/en/latest/
> ships with its own set of certificates "cacert.pem"
> and ignores the system wide ones -- so, for instance, adding certificates
> to /etc/ssl/certs on your debian or ubuntu system won't work. I edited
> it by hand and then changed the REQUESTS_CA_BUNDLE environment variable
> to point to it.
>
> Perhaps your problem is along the same lines?
>
> Laura
>
[toc] | [prev] | [next] | [standalone]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-02-18 00:42 +0100 |
| Message-ID | <mailman.18796.1424216562.18130.python-list@python.org> |
| In reply to | #85755 |
Possibly this bug? https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1014640 Laura
[toc] | [prev] | [next] | [standalone]
| From | John Nagle <nagle@animats.com> |
|---|---|
| Date | 2015-02-17 16:28 -0800 |
| Message-ID | <mailman.18797.1424220117.18130.python-list@python.org> |
| In reply to | #85755 |
On 2/17/2015 3:42 PM, Laura Creighton wrote: > Possibly this bug? > https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1014640 > > Laura Probably that bug in OpenSSL. Some versions of OpenSSL are known to be broken for cases where there multiple valid certificate trees. Python ships with its own copy of OpenSSL on Windows. Tests for "www.verisign.com" Win7, x64: Python 2.7.9 with OpenSSL 1.0.1j 15 Oct 2014. FAIL Python 3.4.2 with OpenSSL 1.0.1i 6 Aug 2014. FAIL openssl s_client -OpenSSL 1.0.1h 5 Jun 2014 FAIL Ubuntu 14.04 LTS, using distro's versions of Python: Python 2.7.6 - test won't run, needs create_default_context Python 3.4.0 with OpenSSL 1.0.1f 6 Jan 2014. FAIL openssl s_client OpenSSL 1.0.1f 6 Jan 2014 PASS That's with the same cert file in all cases. The OpenSSL version for Python programs comes from ssl.OPENSSL_VERSION. The Linux situation has me puzzled. On Linux, Python is supposedly using the system version of OpenSSL. The versions match. Why do Python and the command line client disagree? Different options passed to OpenSSL by Python? Here's the little test program: http://www.animats.com/private/sslbug Please try that and let me know what happens on other platforms. Works with Python 2.7.9 or 3.x. John Nagle
[toc] | [prev] | [next] | [standalone]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-02-18 08:49 +0100 |
| Message-ID | <mailman.18807.1424245798.18130.python-list@python.org> |
| In reply to | #85755 |
I am away on a consulting gig, so I really only have my laptop to test on. Python 2.7.8 (default, Nov 18 2014, 14:57:17) debian version jessie/sid SSL test, with OpenSSL version OpenSSL 1.0.1j 15 Oct 2014. Connection to "verisign.com" failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581). Connection to "www.verisign.com" failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581). Connection to "python.org" succeeded. --------------------- Python 3.4.2 (default, Nov 13 2014, 07:01:52) debian version jessie/sid SSL test, with OpenSSL version OpenSSL 1.0.1j 15 Oct 2014. Connection to "verisign.com" failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581). Connection to "www.verisign.com" failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581). Connection to "python.org" succeeded. --------------- openssl s_client -connect www.verisign.com:443 -CAfile cacert.pem succeeds ..... So whatever problem there is, I have it too. Laura
[toc] | [prev] | [next] | [standalone]
| From | John Nagle <nagle@animats.com> |
|---|---|
| Date | 2015-02-17 14:57 -0800 |
| Message-ID | <mailman.18795.1424214533.18130.python-list@python.org> |
| In reply to | #85734 |
If I remove certs from my "cacert.pem" file passed to
create_default_context, the Python test program rejects domains
it will pass with the certs present. It's using that file.
So that's not it. It seems to be an OpenSSL or cert file
problem. I can reproduce the problem with the OpenSSL command
line client:
openssl s_client -connect www.verisign.com:443 -CAfile cacert.pem
fails for "www.verisign.com", where "cacert.pem" has been extracted
from Firefox's cert store.
The error message from OpenSSL
Verify return code: 20 (unable to get local issuer certificate)
Try the same OpenSSL command for other domains ("google.com",
"python.org") and no errors are reported. More later on this.
So it's not a Python level issue. The only Python-specific
problem is that the Python library doesn't pass detailed
OpenSSL error codes through in exceptions. The Python exception
text is "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
(_ssl.c:581).", which is a generic message for most OpenSSL errors.
John Nagle
On 2/17/2015 12:00 AM, Laura Creighton wrote:
> I've seen something like this:
>
> The requests module http://docs.python-requests.org/en/latest/
> ships with its own set of certificates "cacert.pem"
> and ignores the system wide ones -- so, for instance, adding certificates
> to /etc/ssl/certs on your debian or ubuntu system won't work. I edited
> it by hand and then changed the REQUESTS_CA_BUNDLE environment variable
> to point to it.
>
> Perhaps your problem is along the same lines?
>
> Laura
>
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web