Skip to content

Commit 10be52f

Browse files
committed
Clean up the docs.
1 parent 25e4827 commit 10be52f

2 files changed

Lines changed: 57 additions & 64 deletions

File tree

‎Doc/library/ssl.rst‎

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ Exceptions
332332

333333
.. attribute:: retry_config
334334

335-
The server's ECH retry configuration as a binary-encoded ECHConfigList,
336-
or empty :class:`bytes` if the server did not provide one or the server
335+
The server's ECH retry configuration as an ECHConfigList,
336+
or ``b""`` if the server did not provide one or the server
337337
could not be authenticated under the outer server name.
338338

339339
.. versionadded:: next
@@ -1443,14 +1443,8 @@ SSL sockets also have the following additional methods and attributes:
14431443

14441444
.. method:: SSLSocket.get_ech_retry_config()
14451445

1446-
Return the server's ECH retry configuration as :class:`bytes`, or empty
1447-
bytes if no retry configuration is available. When the status returned by
1448-
:meth:`SSLSocket.get_ech_status` after the handshake is
1449-
:attr:`ECHStatus.ECH_STATUS_GREASE_ECH`, the configuration can be used
1450-
for a new connection using ECH. When the server rejects a real ECH
1451-
attempt, the handshake raises :exc:`SSLECHRejectedError`, which carries
1452-
the same configuration in its :attr:`~SSLECHRejectedError.retry_config`
1453-
attribute.
1446+
Return the server's ECH retry configuration as :class:`bytes`, or ``b""``
1447+
if no retry configuration is available.
14541448

14551449
Only available when :data:`HAS_ECH` is ``True``.
14561450

@@ -1470,16 +1464,11 @@ SSL sockets also have the following additional methods and attributes:
14701464
Set the Encrypted Client Hello (ECH) configuration for this connection
14711465
only, replacing any configuration set on the context with
14721466
:meth:`SSLContext.set_ech_config`. The *ech_config* parameter accepts the
1473-
same values. Unlike the context's configuration, which applies to every
1474-
connection made from it, a connection's configuration is only used by that
1475-
connection and can therefore be chosen per destination host, which is how
1476-
ECH configurations are published in DNS.
1467+
same values.
14771468

14781469
The configuration must be set before the handshake starts, so this is
14791470
mostly useful with ``do_handshake_on_connect=False`` or on a socket that
1480-
is not connected yet. :meth:`SSLContext.wrap_socket` and
1481-
:meth:`SSLContext.wrap_bio` accept the configuration as their *ech_config*
1482-
argument instead.
1471+
is not connected yet.
14831472

14841473
Only available when :data:`HAS_ECH` is ``True``.
14851474

@@ -1560,8 +1549,8 @@ SSL sockets also have the following additional methods and attributes:
15601549
.. attribute:: SSLSocket.outer_server_hostname
15611550

15621551
Hostname of the server name used in the outer ClientHello when Encrypted Client
1563-
Hello (ECH) is used: :class:`str` type, or ``None`` for server-side socket or
1564-
if no outer server name is available.
1552+
Hello (ECH) is used, or ``None`` for server-side socket or if no outer
1553+
server name is available.
15651554

15661555
Only available when :data:`HAS_ECH` is ``True``.
15671556

@@ -1753,25 +1742,16 @@ to speed up repeated connections from the same clients.
17531742

17541743
Load a server's Encrypted Client Hello (ECH) private key and configuration.
17551744
The *keyfile* must be the path to a PEM file containing a private key
1756-
followed by its matching ECHConfigList. Load the server's TLS
1757-
certificate and private key separately with :meth:`load_cert_chain`.
1745+
followed by its matching ECHConfigList.
17581746

17591747
The *password* argument is used to decrypt encrypted private keys. It accepts
17601748
a string, bytes, bytearray, or a callable returning one of those types, as in
1761-
:meth:`load_cert_chain`. Passwords are never requested interactively.
1749+
:meth:`load_cert_chain`.
17621750

17631751
Each call adds keys and configurations to those already loaded into the
17641752
context. If *for_retry* is true, the new configurations are included in
17651753
ECH retry configurations sent to clients.
17661754

1767-
Configure ECH keys on the initial server context before accepting
1768-
connections. After successful ECH decryption, :attr:`sni_callback`
1769-
receives the inner server name.
1770-
1771-
Invalid or missing keys or configurations, or a key that does not match
1772-
its configuration, raise :exc:`SSLError`. File access errors raise
1773-
:exc:`OSError`.
1774-
17751755
Only available when :data:`HAS_ECH` is ``True``.
17761756

17771757
.. versionadded:: next
@@ -1974,7 +1954,6 @@ to speed up repeated connections from the same clients.
19741954

19751955
Sets an Encrypted Client Hello (ECH) configuration, which may be discovered from
19761956
an HTTPS resource record in DNS or from :meth:`SSLSocket.get_ech_retry_config`.
1977-
Each call replaces the context's previous configuration.
19781957

19791958
The configuration applies to every connection made from the context, and a
19801959
server that cannot decrypt it rejects the connection with
@@ -1984,7 +1963,7 @@ to speed up repeated connections from the same clients.
19841963
pass it as the *ech_config* argument of :meth:`wrap_socket` or
19851964
:meth:`wrap_bio` instead.
19861965

1987-
If the input value provided contains no suitable value (e.g. if it only contains
1966+
If the input value provided contains no suitable value (such as if it only contains
19881967
ECH configuration versions that are not supported), an :class:`SSLError` will be
19891968
raised.
19901969

@@ -3207,31 +3186,52 @@ ECHConfigList discovered through DNS and retries once with the server's retry
32073186
configuration. If no configuration is supplied, it enables ECH GREASE, which a
32083187
server may answer with a retry configuration for a later connection::
32093188

3210-
import socket
3211-
import ssl
3189+
import http.client
3190+
import socket
3191+
import ssl
32123192

32133193

3214-
def connect_with_tls_ech(hostname, ech_config=None, retry=True):
3215-
context = ssl.create_default_context()
3216-
if ech_config is None:
3217-
context.options |= ssl.OP_ECH_GREASE
3218-
sock = socket.create_connection((hostname, 443))
3219-
try:
3220-
return context.wrap_socket(sock, server_hostname=hostname,
3221-
ech_config=ech_config)
3222-
except ssl.SSLECHRejectedError as exc:
3223-
if retry and exc.retry_config:
3224-
return connect_with_tls_ech(hostname, exc.retry_config,
3225-
retry=False)
3226-
raise
3227-
3228-
hostname = "www.python.org"
3229-
ech_config = None # Replace with an ECHConfigList discovered through DNS.
3230-
3231-
with connect_with_tls_ech(hostname, ech_config) as ssock:
3232-
print(ssock.get_ech_status())
3233-
if ssock.get_ech_status() == ssl.ECHStatus.ECH_STATUS_GREASE_ECH:
3234-
print("retry configuration:", ssock.get_ech_retry_config())
3194+
def connect_with_tls_ech(hostname, ech_config=None, use_retry_config=True):
3195+
context = ssl.create_default_context()
3196+
if ech_config is not None:
3197+
context.set_ech_config(ech_config)
3198+
else:
3199+
context.options |= ssl.OP_ECH_GREASE
3200+
sock = socket.create_connection((hostname, 443), timeout=10)
3201+
try:
3202+
ssock = context.wrap_socket(sock, server_hostname=hostname)
3203+
except BaseException:
3204+
sock.close()
3205+
raise
3206+
if (use_retry_config
3207+
and ssock.get_ech_status()
3208+
== ssl.ECHStatus.ECH_STATUS_GREASE_ECH):
3209+
try:
3210+
retry_config = ssock.get_ech_retry_config()
3211+
finally:
3212+
ssock.close()
3213+
return connect_with_tls_ech(hostname, retry_config, False)
3214+
return ssock
3215+
3216+
hostname = "python.org"
3217+
ech_config = None # Replace with an ECHConfigList discovered through DNS.
3218+
3219+
with connect_with_tls_ech(hostname, ech_config) as ssock:
3220+
print("ECH status:", ssock.get_ech_status().name)
3221+
request = (
3222+
"GET / HTTP/1.1\r\n"
3223+
f"Host: {hostname}\r\n"
3224+
"Connection: close\r\n\r\n"
3225+
)
3226+
ssock.sendall(request.encode("ascii"))
3227+
with http.client.HTTPResponse(ssock) as response:
3228+
response.begin()
3229+
print(f"HTTP {response.status} {response.reason}")
3230+
for name, value in response.getheaders():
3231+
print(f"{name}: {value}")
3232+
print()
3233+
print(response.read().decode("utf-8", errors="replace"))
3234+
32353235

32363236
The following classes, methods, and attributes will be useful for using ECH:
32373237

‎Doc/whatsnew/3.16.rst‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -693,17 +693,10 @@ ssl
693693
discovered through DNS, for example using a third-party library such as
694694
``dnspython`` to query HTTPS or SVCB records, as the *ech_config* argument
695695
of :meth:`~ssl.SSLContext.wrap_socket` and :meth:`~ssl.SSLContext.wrap_bio`
696-
or with :meth:`~ssl.SSLContext.set_ech_config`. A rejected ECH attempt
697-
raises :exc:`~ssl.SSLECHRejectedError`, which carries the server's retry
698-
configuration. Clients can also enable :data:`~ssl.OP_ECH_GREASE` and
699-
retrieve a server's retry configuration with
700-
:meth:`~ssl.SSLSocket.get_ech_retry_config` for a subsequent connection.
696+
or with :meth:`~ssl.SSLContext.set_ech_config`.
701697
Servers can use :meth:`~ssl.SSLContext.load_ech_keys` to load ECH private
702698
keys and their configurations from PEM files.
703-
:data:`~ssl.HAS_ECH` indicates whether ECH is available, and
704-
:meth:`~ssl.SSLSocket.get_ech_status` reports the status as an
705-
:class:`~ssl.ECHStatus` member.
706-
(Contributed by Iain R. Learmonth and Peter Bierma in :gh:`89730`.)
699+
(Contributed by Peter Bierma and Iain R. Learmonth in :gh:`89730`.)
707700

708701
* :const:`ssl.OPENSSL_VERSION_INFO` is now a named tuple.
709702
Added :const:`~ssl.OPENSSL_API_VERSION_INFO` which provides information

0 commit comments

Comments
 (0)