[3.8] bpo-37440: Enable TLS 1.3 post-handshake auth in http.client (GH-14448) (GH-14495)
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.
https://bugs.python.org/issue37440
(cherry picked from commit d1bd6e79da
)
Co-authored-by: Christian Heimes <christian@python.org>
https://bugs.python.org/issue37440
This commit is contained in:
parent
c2684c6d62
commit
ee72dda961
|
@ -94,6 +94,11 @@ The module provides the following classes:
|
|||
:func:`ssl._create_unverified_context` can be passed to the *context*
|
||||
parameter.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
This class now enables TLS 1.3
|
||||
:attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or
|
||||
when *cert_file* is passed with a custom *context*.
|
||||
|
||||
.. deprecated:: 3.6
|
||||
|
||||
*key_file* and *cert_file* are deprecated in favor of *context*.
|
||||
|
|
|
@ -1358,6 +1358,9 @@ else:
|
|||
self.cert_file = cert_file
|
||||
if context is None:
|
||||
context = ssl._create_default_https_context()
|
||||
# enable PHA for TLS 1.3 connections if available
|
||||
if context.post_handshake_auth is not None:
|
||||
context.post_handshake_auth = True
|
||||
will_verify = context.verify_mode != ssl.CERT_NONE
|
||||
if check_hostname is None:
|
||||
check_hostname = context.check_hostname
|
||||
|
@ -1366,6 +1369,10 @@ else:
|
|||
"either CERT_OPTIONAL or CERT_REQUIRED")
|
||||
if key_file or cert_file:
|
||||
context.load_cert_chain(cert_file, key_file)
|
||||
# cert and key file means the user wants to authenticate.
|
||||
# enable TLS 1.3 PHA implicitly even for custom contexts.
|
||||
if context.post_handshake_auth is not None:
|
||||
context.post_handshake_auth = True
|
||||
self._context = context
|
||||
if check_hostname is not None:
|
||||
self._context.check_hostname = check_hostname
|
||||
|
|
|
@ -1745,6 +1745,24 @@ class HTTPSTest(TestCase):
|
|||
self.assertEqual(h, c.host)
|
||||
self.assertEqual(p, c.port)
|
||||
|
||||
def test_tls13_pha(self):
|
||||
import ssl
|
||||
if not ssl.HAS_TLSv1_3:
|
||||
self.skipTest('TLS 1.3 support required')
|
||||
# just check status of PHA flag
|
||||
h = client.HTTPSConnection('localhost', 443)
|
||||
self.assertTrue(h._context.post_handshake_auth)
|
||||
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
self.assertFalse(context.post_handshake_auth)
|
||||
h = client.HTTPSConnection('localhost', 443, context=context)
|
||||
self.assertIs(h._context, context)
|
||||
self.assertFalse(h._context.post_handshake_auth)
|
||||
|
||||
h = client.HTTPSConnection('localhost', 443, context=context,
|
||||
cert_file=CERT_localhost)
|
||||
self.assertTrue(h._context.post_handshake_auth)
|
||||
|
||||
|
||||
class RequestBodyTest(TestCase):
|
||||
"""Test cases where a request includes a message body."""
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
http.client now enables TLS 1.3 post-handshake authentication for default
|
||||
context or if a cert_file is passed to HTTPSConnection.
|
Loading…
Reference in New Issue