简体   繁体   中英

OpenSSL s_client and Python SSL module disagree on the certificate for a hostname

I'm having an odd problem. It looks like OpenSSL's "s_client" tool doesn't like my AppEngine application's SSL certificate to the point of not even acknowledging it ("no peer certificate is available"), but Python's SSL module reports the issuer, date range, serial number, subjects, etc.., as if there was no problem at all.

I'd assume that there is some subtle misconfiguration with my SSL certificate, but, as AppEngine provides a very simple wizard for uploading certificates, saying that there is a misconfiguration is to say that Google's functionality is broken... Which I doubt is the case.

I'd love some insight into this if someone else has experienced it.

s_client:

openssl s_client -connect www.abc.com:443

s_client output:

CONNECTED(00000003)
3073997000:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 225 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

Python 3.3 test script:

import socket

from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
from ssl import SSLContext  # Modern SSL?
from ssl import HAS_SNI  # Has SNI?

from pprint import pprint

# Stole this from "requests" package.
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                    ca_certs=None, server_hostname=None,
                    ssl_version=None):

    context = SSLContext(ssl_version)
    context.verify_mode = cert_reqs

    if ca_certs:
        try:
            context.load_verify_locations(ca_certs)
        # Py32 raises IOError
        # Py33 raises FileNotFoundError
        except Exception as e:  # Reraise as SSLError
            raise SSLError(e)

    if certfile:
        # FIXME: This block needs a test.
        context.load_cert_chain(certfile, keyfile)

    if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
        return context.wrap_socket(sock, server_hostname=server_hostname)

    return context.wrap_socket(sock)

hostname = 'www.abc.com'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 443))

sslSocket = ssl_wrap_socket(s,
                            ssl_version=2, 
                            cert_reqs=2, 
                            ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem', 
                            server_hostname=hostname)

pprint(sslSocket.getpeercert())
s.close()

Test script output:

{'issuer': ((('countryName', 'US'),),
            (('organizationName', 'GeoTrust, Inc.'),),
            (('commonName', 'RapidSSL CA'),)),
 'notAfter': 'Oct  2 20:01:20 2014 GMT',
 'notBefore': 'Sep 29 02:17:38 2013 GMT',
 'serialNumber': '0E45AF',
 'subject': ((('serialNumber', 'd3tVuFeMunyn/gFFucMFHgZ2iBihdthR'),),
             (('organizationalUnitName', 'GT22884059'),),
             (('organizationalUnitName',
               'See www.rapidssl.com/resources/cps (c)13'),),
             (('organizationalUnitName',
               'Domain Control Validated - RapidSSL(R)'),),
             (('commonName', 'www.abc.com'),)),
 'subjectAltName': (('DNS', 'www.abc.com'),
                    ('DNS', 'abc.com')),
 'version': 3}

问题是我的“ s_client”调用中没有包含“ servername”参数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM