Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #85733 > unrolled thread

Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com"

Started byJohn Nagle <nagle@animats.com>
First post2015-02-16 23:05 -0800
Last post2015-02-17 14:57 -0800
Articles 7 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  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

#85733 — Python 2.7.9, 3.4.2 won't verify SSL cert for "verisign.com"

FromJohn Nagle <nagle@animats.com>
Date2015-02-16 23:05 -0800
SubjectPython 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]


#85734

FromLaura Creighton <lac@openend.se>
Date2015-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]


#85755

FromJohn Nagle <nagle@animats.com>
Date2015-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]


#85757

FromLaura Creighton <lac@openend.se>
Date2015-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]


#85759

FromJohn Nagle <nagle@animats.com>
Date2015-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]


#85773

FromLaura Creighton <lac@openend.se>
Date2015-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]


#85756

FromJohn Nagle <nagle@animats.com>
Date2015-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