diff options
author | Peter Wu <peter@lekensteyn.nl> | 2019-06-08 22:10:46 -0700 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-06-09 23:18:30 +0000 |
commit | 13fc8302e09d1b9885d4d853aeb40b27c549b33c (patch) | |
tree | 14bb80c966646749622a2112f712fb66d720f266 /epan | |
parent | 6476ec79aaea3f90fa840c787dbe1bfeb0b01176 (diff) |
QUIC: fix decryption after Version Negotiation
After a Version Negotiation, the handshake starts over with a new Client
Initial that have different DCID and SCID. Be sure not to link these
subsequent packets to the first session as that would break decryption.
Tested with a QUANT capture provided by Lars Eggert. Regression tested
against ngtcp2-19-dsb.pcapng, decryption still works there.
Bug: 13881
Change-Id: Ia6253c1f2ff39fbe5ce130966129215be479a20a
Reviewed-on: https://code.wireshark.org/review/33525
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-quic.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c index 3a717309ba..23d95bc10a 100644 --- a/epan/dissectors/packet-quic.c +++ b/epan/dissectors/packet-quic.c @@ -711,14 +711,26 @@ quic_connection_find(packet_info *pinfo, guint8 long_packet_type, gboolean is_long_packet = long_packet_type != QUIC_SHORT_PACKET; quic_info_data_t *conn = NULL; - if ((long_packet_type == QUIC_LPT_INITIAL || long_packet_type == QUIC_LPT_0RTT) && dcid->len > 0) { + if (long_packet_type == QUIC_LPT_0RTT && dcid->len > 0) { + // The 0-RTT packet always matches the SCID/DCID of the Client Initial conn = (quic_info_data_t *) wmem_map_lookup(quic_initial_connections, dcid); - // Both the client and server can send Initial (since draft -13). - if (!conn && long_packet_type == QUIC_LPT_INITIAL) { - conn = quic_connection_find_dcid(pinfo, dcid, from_server); - } + *from_server = FALSE; } else { + // Find a connection for Handshake and Server Initial packets by + // matching their DCID against the SCIDs of the original Initial packets + // from the peer. For Client Initial packets, match DCID of the first + // Client Initial (these may contain ACK frames). conn = quic_connection_find_dcid(pinfo, dcid, from_server); + if (long_packet_type == QUIC_LPT_INITIAL && conn && !*from_server && dcid->len > 0 && + memcmp(dcid, &conn->client_dcid_initial, sizeof(quic_cid_t)) && + !quic_cids_has_match(&conn->server_cids, dcid)) { + // If the Initial Packet is from the client, it must either match + // the DCID from the first Client Initial, or the DCID that was + // assigned by the server. Otherwise this must be considered a fresh + // Client Initial, for example after the Version Negotiation packet, + // and the connection must be cleared to avoid decryption failure. + conn = NULL; + } } if (!is_long_packet && !conn) { |