-
Notifications
You must be signed in to change notification settings - Fork 897
Description
Version
5.8.2
Description
When receiving a HelloRetryRequest
(ServerHello with magic random value) which should trigger no change in the ClientHello (the HRR only contains a SupportedVersion
extension), WolfSSL TLS 1.3 client sends a ClientHello that is identical to its first ClientHello.
According to RFC 8446 section 4.1.4 : Clients MUST abort the handshake with an "illegal_parameter" alert if the HelloRetryRequest would not result in any change in the ClientHello.
Note that is some variants of our experiments, the two ClientHello had the same set of extensions with the same respective values but those extensions were in a different order.
Impact
Unknown, we were able to perform a full handshake after the second ClientHello but no other problem was detected.
Expected behavior
WolfSSL client should abort the handshake since the HRR doesn't cause any change in the ClientHello.
Reproduction steps
Here is an example of a TLS 1.3 HelloRetryRequest that triggers the described behavior
- Record Layer:
- ContentType: Handshake
- Version: TLS 1.2 (legacy marker)
- Length: 50
- Handshake:
- Type: ServerHello
- Length: 46
- Version: 0x0303
- Random: cf21ad74e59a6111be1d8c021e65b891c2a211167abb8c5e079e09e2c8a8339c (HelloRetryRequest magic value)
- SessionID: empty
- CipherSuite: TLS_AES_128_GCM_SHA256 (0x1301)
- Compression: null
- Extensions:
- supported_versions = TLS 1.3 (0x0304)
In raw hex :
16030300320200002e0303cf21ad74e59a6111be1d8c021e65b891c2a211167abb8c5e079e09e2c8a8339c001301000006002b00020304
Start the following Python TCP server :
import socket
HOST = "0.0.0.0"
PORT = 3000
payload = bytes.fromhex(
"16030300320200002e0303cf21ad74e59a6111be1d8c021e65b891c2a211167abb8c5e079e09e2c8a8339c001301000006002b00020304"
)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print(f"[*] Listening on {HOST}:{PORT} ...")
# Accept client connection
conn, addr = server_socket.accept()
with conn:
print(f"[+] Connection from {addr}")
data = conn.recv(1024)
print(f"[>] Received: {data.hex()}")
# Send decoded payload
conn.sendall(payload)
print(f"[<] Sent: {payload.hex()}")
while True:
data = conn.recv(1024)
print(f"[>] Received: {data.hex()}")
Then start TLS 1.3 handshake with WolfSSL client :
./build/examples/client/client -p 3000 -v 4
You should see two identical ClientHello sent by WolfSSL client.
Acknowledgements
This bug was found thanks to the tlspuffin fuzzer designed and developed by the tlspuffin team:
- Max Ammann
- Olivier Demengeon - Loria, Inria
- Tom Gouville - Loria, Inria
- Lucca Hirschi - Loria, Inria
- Steve Kremer - Loria, Inria
- Michael Mera - Loria, Inria