TLS 1.3 second Key Update doesn't work
Summary
Wireshark cannot handle more than a single Key Update message per-session (and direction). This appears to be because when Wireshark handles a the Key Update message it fails to set the application secret on the new decoder object.
- Check to see that the application secret is present
- Set the application secret on the old decoder
- Call into tls13_generate_keys
- Create a new decoder
- Replace the old decoder with the new
This is different from when a keyfile is loaded when parsing the handshake and tls_change_key saves the application secret after creating and saving the decoder (in tls13_generate_keys
).
Sample capture file
If you look at the capture file you'll see that the server (src port 4433) sends a Key Update relatively quickly. The first sent is in packet 1922. Wireshark can still successfully decrypt information after that point. The second key update sent by the server is in packet 3926. You can see that wireshark is successfully decrypting application data before that point and fails to after that update.
NSS Key Log
CLIENT_HANDSHAKE_TRAFFIC_SECRET c7afaeb868b021512f9ca59aade42cdcc602c40cbf643f022e0ed052b9e1d018 ed3cac4ee57858dd51a34a9034962dcf672591cfc0b280cceb734900b397a3e09bce61c64cb71866689d5fc106547aa6
SERVER_HANDSHAKE_TRAFFIC_SECRET c7afaeb868b021512f9ca59aade42cdcc602c40cbf643f022e0ed052b9e1d018 febd64e39df8a02dbced10371c4ce7737d01ab32073e7cde0cbbeaa708859d7e9baf0f0f78240c7f826410e8870b2b02
SERVER_TRAFFIC_SECRET_0 c7afaeb868b021512f9ca59aade42cdcc602c40cbf643f022e0ed052b9e1d018 e8978018f203397402d057fb7039971c5b69bd6e829178682d84568b79fcb4c9e47653df44956e0a3489c41bb6e3b13b
CLIENT_TRAFFIC_SECRET_0 c7afaeb868b021512f9ca59aade42cdcc602c40cbf643f022e0ed052b9e1d018 7084a0b4eabb988d273c6efe8a8b34a5afb26c635e56e735e4d0e9b6b473f7799d2be6c5f2e4c73487681843a6775c74
Steps to reproduce
Capture any valid TLS 1.3 session with two or more key updates and you have access to an NSS Key Log file to decrypt packets. You'll see that Wireshark fails to decrypt any packets after the second key update.
In TLS 1.3, using an AES-GCM ciphersuite, the recommendation (RFC 8446, Section 5.5) is to send a KeyUpdate every 2^24.5 full-size (2^14 byte) records, or approximately every 388 gigabytes, while a ChaCha20/Poly1305 would be able to send a full 2^64 records, or 302 zetabytes, so multiple KeyUpdates over a single connection is likely a rare case. However, some implementations, such as Java, allow users to customize those limits, and TLS 1.3 allows either peer to request a KeyUpdate (e.g. a recipient/client can request the sender/server perform a KeyUpdate), so this can be programmatically induced by configuring lower limits.
What is the current bug behavior?
Wireshark fails to decrypt any traffic after the second key update in a given direction.
What is the expected correct behavior?
Wireshark should continue being able to decrypt TLS 1.3 traffic.
Build information
Version 4.0.5 (v4.0.5-0-ge556162d8da3).
Compiled (64-bit) using Clang 13.0.0 (clang-1300.0.29.30), with GLib 2.68.4,
with PCRE2, with zlib 1.2.11, with Qt 6.2.4, with libpcap, without POSIX
capabilities, with Lua 5.2.4, with GnuTLS 3.6.15 and PKCS #11 support, with
Gcrypt 1.8.7, with Kerberos (MIT), with MaxMind, with nghttp2 1.46.0, with
brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.9.9, with libsmi
0.4.8, with QtMultimedia, with automatic updates using Sparkle, with SpeexDSP
(using system library), with Minizip, with binary plugins.
Running on macOS 13.1, build 22C61 (Darwin 22.2.0), with Apple M1 Max, with
65536 MB of physical memory, with GLib 2.68.4, with PCRE2 10.39 2021-10-29, with
zlib 1.2.11, with Qt 6.2.4, with libpcap 1.10.1, with c-ares 1.15.0, with GnuTLS
3.6.15, with Gcrypt 1.8.7, with nghttp2 1.46.0, with brotli 1.0.9, with LZ4
1.9.2, with Zstandard 1.4.2, with libsmi 0.4.8, with light display mode, with
mixed DPI, with LC_TYPE=C, binary plugins supported.