From: Martin Panter Date: Thu, 14 Jan 2016 12:21:02 +0000 (+0000) Subject: Issue #25940: Merge self-signed.pythontest.net testing from 3.2 into 3.3 X-Git-Tag: v3.4.5rc1~25^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=73f55076f667c7678e422e7c85613ee6737a11bf;p=thirdparty%2FPython%2Fcpython.git Issue #25940: Merge self-signed.pythontest.net testing from 3.2 into 3.3 --- 73f55076f667c7678e422e7c85613ee6737a11bf diff --cc Lib/test/test_ssl.py index e52a71c24102,69a80d0a5728..03d40b22551c --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@@ -42,13 -43,12 +43,15 @@@ ONLYCERT = data_file("ssl_cert.pem" ONLYKEY = data_file("ssl_key.pem") BYTES_ONLYCERT = os.fsencode(ONLYCERT) BYTES_ONLYKEY = os.fsencode(ONLYKEY) +CERTFILE_PROTECTED = data_file("keycert.passwd.pem") +ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem") +KEY_PASSWORD = "somepass" CAPATH = data_file("capath") BYTES_CAPATH = os.fsencode(CAPATH) + CAFILE_CACERT = data_file("capath", "5ed36f99.0") - SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") + REMOTE_HOST = "self-signed.pythontest.net" + REMOTE_ROOT_CERT = data_file("selfsigned_pythontestdotnet.pem") EMPTYCERT = data_file("nullcert.pem") BADCERT = data_file("badcert.pem") @@@ -212,24 -157,16 +215,24 @@@ class BasicSocketTests(unittest.TestCas (('emailAddress', 'python-dev@python.org'),)) self.assertEqual(p['subject'], subject) self.assertEqual(p['issuer'], subject) - self.assertEqual(p['subjectAltName'], - (('DNS', 'altnull.python.org\x00example.com'), - ('email', 'null@python.org\x00user@example.org'), - ('URI', 'http://null.python.org\x00http://example.org'), - ('IP Address', '192.0.2.1'), - ('IP Address', '2001:DB8:0:0:0:0:0:1\n')) - ) + if ssl._OPENSSL_API_VERSION >= (0, 9, 8): + san = (('DNS', 'altnull.python.org\x00example.com'), + ('email', 'null@python.org\x00user@example.org'), + ('URI', 'http://null.python.org\x00http://example.org'), + ('IP Address', '192.0.2.1'), + ('IP Address', '2001:DB8:0:0:0:0:0:1\n')) + else: + # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName + san = (('DNS', 'altnull.python.org\x00example.com'), + ('email', 'null@python.org\x00user@example.org'), + ('URI', 'http://null.python.org\x00http://example.org'), + ('IP Address', '192.0.2.1'), + ('IP Address', '')) + + self.assertEqual(p['subjectAltName'], san) def test_DER_to_PEM(self): - with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f: + with open(CAFILE_CACERT, 'r') as f: pem = f.read() d1 = ssl.PEM_cert_to_DER_cert(pem) p2 = ssl.DER_cert_to_PEM_cert(d1) @@@ -592,61 -465,7 +595,61 @@@ class ContextTests(unittest.TestCase) # Mismatching key and cert ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"): - ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY) + ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY) + # Password protected key and cert + ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD) + ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode()) + ctx.load_cert_chain(CERTFILE_PROTECTED, + password=bytearray(KEY_PASSWORD.encode())) + ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD) + ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode()) + ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, + bytearray(KEY_PASSWORD.encode())) + with self.assertRaisesRegex(TypeError, "should be a string"): + ctx.load_cert_chain(CERTFILE_PROTECTED, password=True) + with self.assertRaises(ssl.SSLError): + ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass") + with self.assertRaisesRegex(ValueError, "cannot be longer"): + # openssl has a fixed limit on the password buffer. + # PEM_BUFSIZE is generally set to 1kb. + # Return a string larger than this. + ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400) + # Password callback + def getpass_unicode(): + return KEY_PASSWORD + def getpass_bytes(): + return KEY_PASSWORD.encode() + def getpass_bytearray(): + return bytearray(KEY_PASSWORD.encode()) + def getpass_badpass(): + return "badpass" + def getpass_huge(): + return b'a' * (1024 * 1024) + def getpass_bad_type(): + return 9 + def getpass_exception(): + raise Exception('getpass error') + class GetPassCallable: + def __call__(self): + return KEY_PASSWORD + def getpass(self): + return KEY_PASSWORD + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode) + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes) + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray) + ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable()) + ctx.load_cert_chain(CERTFILE_PROTECTED, + password=GetPassCallable().getpass) + with self.assertRaises(ssl.SSLError): + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass) + with self.assertRaisesRegex(ValueError, "cannot be longer"): + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge) + with self.assertRaisesRegex(TypeError, "must return a string"): + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type) + with self.assertRaisesRegex(Exception, "getpass error"): + ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception) + # Make sure the password function isn't called if it isn't needed + ctx.load_cert_chain(CERTFILE, password=getpass_exception) def test_load_verify_locations(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) @@@ -844,15 -602,13 +847,19 @@@ class NetworkedTests(unittest.TestCase) s.close() def test_connect_ex_error(self): - with support.transient_internet("svn.python.org"): + with support.transient_internet(REMOTE_HOST): s = ssl.wrap_socket(socket.socket(socket.AF_INET), cert_reqs=ssl.CERT_REQUIRED, - ca_certs=SVN_PYTHON_ORG_ROOT_CERT) + ca_certs=REMOTE_ROOT_CERT) try: - rc = s.connect_ex(("svn.python.org", 444)) + rc = s.connect_ex((REMOTE_HOST, 444)) - self.assertIn(rc, (errno.ECONNREFUSED, errno.EHOSTUNREACH)) + # Issue #19919: Windows machines or VMs hosted on Windows + # machines sometimes return EWOULDBLOCK. - self.assertIn(rc, (errno.ECONNREFUSED, errno.EWOULDBLOCK)) ++ errors = ( ++ errno.ECONNREFUSED, errno.EHOSTUNREACH, ++ errno.EWOULDBLOCK, ++ ) ++ self.assertIn(rc, errors) finally: s.close() @@@ -962,45 -721,40 +969,45 @@@ sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count) def test_get_server_certificate(self): - with support.transient_internet(REMOTE_HOST): - pem = ssl.get_server_certificate((REMOTE_HOST, 443), - ssl.PROTOCOL_SSLv23) - if not pem: - self.fail("No server certificate on REMOTE_HOST:443!") + def _test_get_server_certificate(host, port, cert=None): + with support.transient_internet(host): + pem = ssl.get_server_certificate((host, port), + ssl.PROTOCOL_SSLv23) + if not pem: + self.fail("No server certificate on %s:%s!" % (host, port)) - try: - pem = ssl.get_server_certificate((REMOTE_HOST, 443), + try: + pem = ssl.get_server_certificate((host, port), + ssl.PROTOCOL_SSLv23, + 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), ssl.PROTOCOL_SSLv23, - ca_certs=CERTFILE) - except ssl.SSLError as x: - #should fail + 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 REMOTE_HOST!" % pem) + sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem)) - _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT) - pem = ssl.get_server_certificate((REMOTE_HOST, 443), - ssl.PROTOCOL_SSLv23, - ca_certs=REMOTE_ROOT_CERT) - if not pem: - self.fail("No server certificate on REMOTE_HOST:443!") - if support.verbose: - sys.stdout.write("\nVerified certificate for REMOTE_HOST:443 is\n%s\n" % pem) ++ _test_get_server_certificate(REMOTE_HOST, 443, REMOTE_ROOT_CERT) + if support.IPV6_ENABLED: + _test_get_server_certificate('ipv6.google.com', 443) def test_ciphers(self): - remote = ("svn.python.org", 443) + remote = (REMOTE_HOST, 443) with support.transient_internet(remote[0]): - s = ssl.wrap_socket(socket.socket(socket.AF_INET), - cert_reqs=ssl.CERT_NONE, ciphers="ALL") - s.connect(remote) - s = ssl.wrap_socket(socket.socket(socket.AF_INET), - cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") - s.connect(remote) + with ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s: + s.connect(remote) + with ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s: + s.connect(remote) # Error checking can happen at instantiation or when connecting with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): with socket.socket(socket.AF_INET) as sock: diff --cc Misc/NEWS index 86d7c5ef834a,df54574058b2..183ddd0819c7 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -24,36 -19,17 +24,43 @@@ Core and Builtin Library ------- +- Issue #24521: Fix possible integer overflows in the pickle module. + - Issue #22931: Allow '[' and ']' in cookie values. +- Issue #24094: Fix possible crash in json.encode with poorly behaved dict + subclasses. + +- Issue #23367: Fix possible overflows in the unicodedata module. + +- Issue #23361: Fix possible overflow in Windows subprocess creation code. + +- Issue #23363: Fix possible overflow in itertools.permutations. + +- Issue #23364: Fix possible overflow in itertools.product. + +- Issue #23369: Fixed possible integer overflow in + _json.encode_basestring_ascii. + +- Issue #23366: Fixed possible integer overflow in itertools.combinations. + +- Issue #23365: Fixed possible integer overflow in + itertools.combinations_with_replacement. + +C API +----- + +- Issue #23998: PyImport_ReInitLock() now checks for lock allocation error + + Tests + ----- + + - Issue #25940: Changed test_ssl and test_httplib to use + self-signed.pythontest.net. This avoids relying on svn.python.org, which + recently changed root certificate. + -What's New in Python 3.2.6? +What's New in Python 3.3.6? =========================== *Release date: 11-Oct-2014*