changeset: 90360:55f62fa5bebc user: Antoine Pitrou date: Wed Apr 16 18:56:28 2014 +0200 files: Doc/library/ssl.rst Lib/ssl.py Lib/test/test_ssl.py Misc/NEWS description: Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not PROTOCOL_SSLv3, for maximum compatibility. diff -r 1305410bff2d -r 55f62fa5bebc Doc/library/ssl.rst --- a/Doc/library/ssl.rst Wed Apr 16 18:34:01 2014 +0200 +++ b/Doc/library/ssl.rst Wed Apr 16 18:56:28 2014 +0200 @@ -387,7 +387,7 @@ >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT")) 'Wed May 9 00:00:00 2007' -.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None) +.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None) Given the address ``addr`` of an SSL-protected server, as a (*hostname*, *port-number*) pair, fetches the server's certificate, and returns it as a @@ -401,6 +401,10 @@ .. versionchanged:: 3.3 This function is now IPv6-compatible. + .. versionchanged:: 3.5 + The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to + :data:`PROTOCOL_SSLv23` for maximum compatibility with modern servers. + .. function:: DER_cert_to_PEM_cert(DER_cert_bytes) Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded diff -r 1305410bff2d -r 55f62fa5bebc Lib/ssl.py --- a/Lib/ssl.py Wed Apr 16 18:34:01 2014 +0200 +++ b/Lib/ssl.py Wed Apr 16 18:56:28 2014 +0200 @@ -922,7 +922,7 @@ d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] return base64.decodebytes(d.encode('ASCII', 'strict')) -def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): +def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None): """Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. diff -r 1305410bff2d -r 55f62fa5bebc Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Wed Apr 16 18:34:01 2014 +0200 +++ b/Lib/test/test_ssl.py Wed Apr 16 18:56:28 2014 +0200 @@ -1371,14 +1371,12 @@ def test_get_server_certificate(self): def _test_get_server_certificate(host, port, cert=None): with support.transient_internet(host): - pem = ssl.get_server_certificate((host, port), - ssl.PROTOCOL_SSLv23) + pem = ssl.get_server_certificate((host, port)) if not pem: self.fail("No server certificate on %s:%s!" % (host, port)) try: pem = ssl.get_server_certificate((host, port), - ssl.PROTOCOL_SSLv23, ca_certs=CERTFILE) except ssl.SSLError as x: #should fail @@ -1388,7 +1386,6 @@ self.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) pem = ssl.get_server_certificate((host, port), - ssl.PROTOCOL_SSLv23, ca_certs=cert) if not pem: self.fail("No server certificate on %s:%s!" % (host, port)) diff -r 1305410bff2d -r 55f62fa5bebc Misc/NEWS --- a/Misc/NEWS Wed Apr 16 18:34:01 2014 +0200 +++ b/Misc/NEWS Wed Apr 16 18:56:28 2014 +0200 @@ -50,6 +50,9 @@ Library ------- +- Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not + PROTOCOL_SSLv3, for maximum compatibility. + - Issue #21239: patch.stopall() didn't work deterministically when the same name was patched more than once.