From 15399c3f09cfe779c1d55c0773db31824504ea31 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 28 Apr 2011 19:23:55 +0200 Subject: [PATCH] =?UTF-8?q?Issue=20#11811:=20ssl.get=5Fserver=5Fcertificat?= =?UTF-8?q?e()=20is=20now=20IPv6-compatible.=20=20Patch=20by=20Charles-Fra?= =?UTF-8?q?n=C3=A7ois=20Natali.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/library/ssl.rst | 3 +++ Lib/ssl.py | 6 +++--- Lib/test/test_ssl.py | 39 ++++++++++++++++++++++----------------- Misc/NEWS | 3 +++ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 011d37806fe..a20cabcc9ff 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -239,6 +239,9 @@ Certificate handling will attempt to validate the server certificate against that set of root certificates, and will fail if the validation attempt fails. + .. versionchanged:: 3.3 + This function is now IPv6-compatible. + .. function:: DER_cert_to_PEM_cert(DER_cert_bytes) Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded diff --git a/Lib/ssl.py b/Lib/ssl.py index 84aa6dc3bf7..6d3828d7e60 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -81,7 +81,7 @@ from _ssl import HAS_SNI from socket import getnameinfo as _getnameinfo from socket import error as socket_error -from socket import socket, AF_INET, SOCK_STREAM +from socket import socket, AF_INET, SOCK_STREAM, create_connection import base64 # for DER-to-PEM translation import traceback import errno @@ -543,9 +543,9 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): cert_reqs = CERT_REQUIRED else: cert_reqs = CERT_NONE - s = wrap_socket(socket(), ssl_version=ssl_version, + s = create_connection(addr) + s = wrap_socket(s, ssl_version=ssl_version, cert_reqs=cert_reqs, ca_certs=ca_certs) - s.connect(addr) dercert = s.getpeercert(True) s.close() return DER_cert_to_PEM_cert(dercert) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 164b6c262a5..71eebde4d91 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -604,25 +604,30 @@ class NetworkedTests(unittest.TestCase): sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count) def test_get_server_certificate(self): - with support.transient_internet("svn.python.org"): - pem = ssl.get_server_certificate(("svn.python.org", 443)) - if not pem: - self.fail("No server certificate on svn.python.org:443!") - - try: - pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE) - except ssl.SSLError as x: - #should fail + def _test_get_server_certificate(host, port, cert=None): + with support.transient_internet(host): + 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), ca_certs=CERTFILE) + except ssl.SSLError as x: + #should fail + if support.verbose: + sys.stdout.write("%s\n" % x) + else: + self.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) + + pem = ssl.get_server_certificate((host, port), ca_certs=cert) + if not pem: + self.fail("No server certificate on %s:%s!" % (host, port)) if support.verbose: - sys.stdout.write("%s\n" % x) - else: - self.fail("Got server certificate %s for svn.python.org!" % pem) + sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem)) - pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT) - if not pem: - self.fail("No server certificate on svn.python.org:443!") - if support.verbose: - sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem) + _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT) + if support.IPV6_ENABLED: + _test_get_server_certificate('ipv6.google.com', 443) def test_ciphers(self): remote = ("svn.python.org", 443) diff --git a/Misc/NEWS b/Misc/NEWS index fb063f3bae2..cb575d18631 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -127,6 +127,9 @@ Core and Builtins Library ------- +- Issue #11811: ssl.get_server_certificate() is now IPv6-compatible. Patch + by Charles-François Natali. + - Issue #11763: don't use difflib in TestCase.assertMultiLineEqual if the strings are too long.