|
57 | 57 | CAN_GET_SELECTED_OPENSSL_SIGALG = ssl.OPENSSL_VERSION_INFO >= (3, 5) |
58 | 58 | PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') |
59 | 59 |
|
| 60 | +HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') |
| 61 | +requires_keylog = unittest.skipUnless( |
| 62 | + HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback') |
| 63 | +CAN_SET_KEYLOG = HAS_KEYLOG and os.name != "nt" |
| 64 | +requires_keylog_setter = unittest.skipUnless( |
| 65 | + CAN_SET_KEYLOG, |
| 66 | + "cannot set 'keylog_filename' on Windows" |
| 67 | +) |
| 68 | + |
| 69 | + |
60 | 70 | PROTOCOL_TO_TLS_VERSION = {} |
61 | 71 | for proto, ver in ( |
62 | 72 | ("PROTOCOL_SSLv3", "SSLv3"), |
@@ -266,34 +276,69 @@ def utc_offset(): #NOTE: ignore issues like #1647654 |
266 | 276 | ) |
267 | 277 |
|
268 | 278 |
|
269 | | -def test_wrap_socket(sock, *, |
270 | | - cert_reqs=ssl.CERT_NONE, ca_certs=None, |
271 | | - ciphers=None, ciphersuites=None, |
272 | | - min_version=None, max_version=None, |
273 | | - certfile=None, keyfile=None, |
274 | | - **kwargs): |
275 | | - if not kwargs.get("server_side"): |
276 | | - kwargs["server_hostname"] = SIGNED_CERTFILE_HOSTNAME |
277 | | - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) |
278 | | - else: |
| 279 | +def make_test_context( |
| 280 | + *, |
| 281 | + server_side=False, |
| 282 | + check_hostname=None, |
| 283 | + cert_reqs=ssl.CERT_NONE, |
| 284 | + ca_certs=None, certfile=None, keyfile=None, |
| 285 | + ciphers=None, ciphersuites=None, |
| 286 | + min_version=None, max_version=None, |
| 287 | +): |
| 288 | + if server_side: |
279 | 289 | context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) |
280 | | - if cert_reqs is not None: |
| 290 | + else: |
| 291 | + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) |
| 292 | + |
| 293 | + if check_hostname is None: |
281 | 294 | if cert_reqs == ssl.CERT_NONE: |
282 | 295 | context.check_hostname = False |
| 296 | + else: |
| 297 | + context.check_hostname = check_hostname |
| 298 | + |
| 299 | + if cert_reqs is not None: |
283 | 300 | context.verify_mode = cert_reqs |
| 301 | + |
284 | 302 | if ca_certs is not None: |
285 | 303 | context.load_verify_locations(ca_certs) |
286 | 304 | if certfile is not None or keyfile is not None: |
287 | 305 | context.load_cert_chain(certfile, keyfile) |
| 306 | + |
288 | 307 | if ciphers is not None: |
289 | 308 | context.set_ciphers(ciphers) |
290 | 309 | if ciphersuites is not None: |
291 | 310 | context.set_ciphersuites(ciphersuites) |
| 311 | + |
292 | 312 | if min_version is not None: |
293 | 313 | context.minimum_version = min_version |
294 | 314 | if max_version is not None: |
295 | 315 | context.maximum_version = max_version |
296 | | - return context.wrap_socket(sock, **kwargs) |
| 316 | + |
| 317 | + return context |
| 318 | + |
| 319 | + |
| 320 | +def test_wrap_socket( |
| 321 | + sock, |
| 322 | + *, |
| 323 | + server_side=False, |
| 324 | + check_hostname=None, |
| 325 | + cert_reqs=ssl.CERT_NONE, |
| 326 | + ca_certs=None, certfile=None, keyfile=None, |
| 327 | + ciphers=None, ciphersuites=None, |
| 328 | + min_version=None, max_version=None, |
| 329 | + **kwargs, |
| 330 | +): |
| 331 | + context = make_test_context( |
| 332 | + server_side=server_side, |
| 333 | + check_hostname=check_hostname, |
| 334 | + cert_reqs=cert_reqs, |
| 335 | + ca_certs=ca_certs, certfile=certfile, keyfile=keyfile, |
| 336 | + ciphers=ciphers, ciphersuites=ciphersuites, |
| 337 | + min_version=min_version, max_version=max_version, |
| 338 | + ) |
| 339 | + if not server_side: |
| 340 | + kwargs.setdefault("server_hostname", SIGNED_CERTFILE_HOSTNAME) |
| 341 | + return context.wrap_socket(sock, server_side=server_side, **kwargs) |
297 | 342 |
|
298 | 343 |
|
299 | 344 | USE_SAME_TEST_CONTEXT = False |
@@ -1741,6 +1786,39 @@ def test_num_tickest(self): |
1741 | 1786 | with self.assertRaises(ValueError): |
1742 | 1787 | ctx.num_tickets = 1 |
1743 | 1788 |
|
| 1789 | + @support.cpython_only |
| 1790 | + def test_refcycle_msg_callback(self): |
| 1791 | + # See https://github.com/python/cpython/issues/142516. |
| 1792 | + ctx = make_test_context() |
| 1793 | + def msg_callback(*args, _=ctx, **kwargs): ... |
| 1794 | + ctx._msg_callback = msg_callback |
| 1795 | + |
| 1796 | + @support.cpython_only |
| 1797 | + @requires_keylog_setter |
| 1798 | + def test_refcycle_keylog_filename(self): |
| 1799 | + # See https://github.com/python/cpython/issues/142516. |
| 1800 | + self.addCleanup(os_helper.unlink, os_helper.TESTFN) |
| 1801 | + ctx = make_test_context() |
| 1802 | + class KeylogFilename(str): ... |
| 1803 | + ctx.keylog_filename = KeylogFilename(os_helper.TESTFN) |
| 1804 | + ctx.keylog_filename._ = ctx |
| 1805 | + |
| 1806 | + @support.cpython_only |
| 1807 | + @unittest.skipUnless(ssl.HAS_PSK, 'requires TLS-PSK') |
| 1808 | + def test_refcycle_psk_client_callback(self): |
| 1809 | + # See https://github.com/python/cpython/issues/142516. |
| 1810 | + ctx = make_test_context() |
| 1811 | + def psk_client_callback(*args, _=ctx, **kwargs): ... |
| 1812 | + ctx.set_psk_client_callback(psk_client_callback) |
| 1813 | + |
| 1814 | + @support.cpython_only |
| 1815 | + @unittest.skipUnless(ssl.HAS_PSK, 'requires TLS-PSK') |
| 1816 | + def test_refcycle_psk_server_callback(self): |
| 1817 | + # See https://github.com/python/cpython/issues/142516. |
| 1818 | + ctx = make_test_context(server_side=True) |
| 1819 | + def psk_server_callback(*args, _=ctx, **kwargs): ... |
| 1820 | + ctx.set_psk_server_callback(psk_server_callback) |
| 1821 | + |
1744 | 1822 |
|
1745 | 1823 | class SSLErrorTests(unittest.TestCase): |
1746 | 1824 |
|
@@ -5174,10 +5252,6 @@ def test_internal_chain_server(self): |
5174 | 5252 | self.assertEqual(res, b'\x02\n') |
5175 | 5253 |
|
5176 | 5254 |
|
5177 | | -HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') |
5178 | | -requires_keylog = unittest.skipUnless( |
5179 | | - HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback') |
5180 | | - |
5181 | 5255 | class TestSSLDebug(unittest.TestCase): |
5182 | 5256 |
|
5183 | 5257 | def keylog_lines(self, fname=os_helper.TESTFN): |
|
0 commit comments