QUIC: Remove draft-10 support

Bug: 13881
Change-Id: I11270c6be4304a5d37216cb2e09ae0d4149091b0
Reviewed-on: https://code.wireshark.org/review/29603
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
Alexis La Goutte 2018-09-11 15:58:22 +02:00 committed by Peter Wu
parent 351ea5940e
commit c525578aff
1 changed files with 41 additions and 144 deletions

View File

@ -51,10 +51,7 @@ static int hf_quic_packet_number_full = -1;
static int hf_quic_version = -1;
static int hf_quic_supported_version = -1;
static int hf_quic_vn_unused = -1;
static int hf_quic_short_ocid_flag = -1;
static int hf_quic_short_kp_flag_draft10 = -1;
static int hf_quic_short_kp_flag = -1;
static int hf_quic_short_packet_type_draft10 = -1;
static int hf_quic_short_packet_type = -1;
static int hf_quic_initial_payload = -1;
static int hf_quic_handshake_payload = -1;
@ -227,10 +224,12 @@ static inline guint8 quic_draft_version(guint32 version) {
}
return 0;
}
#if 0
static inline gboolean is_quic_draft_max(guint32 version, guint8 max_version) {
guint8 draft_version = quic_draft_version(version);
return draft_version && draft_version <= max_version;
}
#endif
const value_string quic_version_vals[] = {
{ 0x00000000, "Version Negotiation" },
@ -251,9 +250,6 @@ static const value_string quic_short_long_header_vals[] = {
{ 0, NULL }
};
#define SH_OCID 0x40 /* until draft -10 */
#define SH_KP_10 0x20 /* until draft -10 */
#define SH_PT_10 0x07 /* until draft -10 */
#define SH_KP 0x40 /* since draft -11 */
#define SH_PT 0x03 /* since draft -11 */
@ -611,7 +607,7 @@ quic_connection_create(packet_info *pinfo, guint32 version, const quic_cid_t *sc
conn->server_port = pinfo->destport;
// Key connection by Client CID (if provided).
if (!is_quic_draft_max(version, 10) && scid->len) {
if (scid->len) {
memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
wmem_map_insert(quic_client_connections, &conn->client_cids.data, conn);
}
@ -653,14 +649,6 @@ quic_connection_create_or_update(quic_info_data_t **conn_p,
if (scid->len) {
wmem_map_insert(quic_server_connections, &conn->server_cids.data, conn);
}
// in draft -10, the Initial Packet CID is useless for tracking,
// instead the CID from this Handshake message is used.
if (is_quic_draft_max(version, 10)) {
DISSECTOR_ASSERT(scid->len);
memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
wmem_map_insert(quic_client_connections, &conn->client_cids.data, conn);
}
}
break;
}
@ -683,13 +671,11 @@ quic_connection_destroy(gpointer data, gpointer user_data _U_)
#ifdef HAVE_LIBGCRYPT_AEAD
static int
dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_packet_info_t *quic_packet)
dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_packet_info_t *quic_packet _U_)
{
proto_item *ti_ft, *ti_ftflags, *ti;
proto_tree *ft_tree, *ftflags_tree;
guint32 frame_type;
quic_info_data_t *conn = quic_packet->conn;
guint32 version = conn ? conn->version : 0;
ti_ft = proto_tree_add_item(quic_tree, hf_quic_frame, tvb, offset, 1, ENC_NA);
ft_tree = proto_item_add_subtree(ti_ft, ett_quic_ft);
@ -865,17 +851,13 @@ dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree
proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_nci_sequence, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_sequence);
offset += len_sequence;
if (is_quic_draft_max(version, 10)) {
nci_length = 8;
} else {
ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
offset++;
ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
offset++;
valid_cid = nci_length >= 4 && nci_length <= 18;
if (!valid_cid) {
expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
valid_cid = nci_length >= 4 && nci_length <= 18;
if (!valid_cid) {
expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
"Connection ID Length must be between 4 and 18 bytes");
}
}
proto_tree_add_item(ft_tree, hf_quic_frame_type_nci_connection_id, tvb, offset, nci_length, ENC_NA);
@ -1520,59 +1502,39 @@ dissect_quic_long_header_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *q
guint32 *version_out, quic_cid_t *dcid, quic_cid_t *scid)
{
guint32 version;
gboolean is_draft10 = FALSE;
guint32 dcil, scil;
version = tvb_get_ntohl(tvb, offset);
if (!(version == 0 || quic_draft_version(version) >= 11)) {
// not a draft -11 version negotiation packet nor draft -11 version,
// assume draft -10 or older. Its version comes after CID.
guint32 version10 = tvb_get_ntohl(tvb, offset + 8);
is_draft10 = is_quic_draft_max(version10, 10);
if (is_draft10) {
version = version10;
}
}
if (version_out) {
*version_out = version;
}
if (is_draft10) {
proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, 8, ENC_NA);
tvb_memcpy(tvb, dcid->cid, offset, 8);
dcid->len = 8;
offset += 8;
proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
} else {
// draft -11 and up.
proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
offset++;
proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
offset++;
if (dcil) {
dcil += 3;
proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
// TODO expert info on CID mismatch with connection
tvb_memcpy(tvb, dcid->cid, offset, dcil);
dcid->len = dcil;
offset += dcil;
}
if (scil) {
scil += 3;
proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
// TODO expert info on CID mismatch with connection
tvb_memcpy(tvb, scid->cid, offset, scil);
scid->len = scil;
offset += scil;
}
if (dcil) {
dcil += 3;
proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
// TODO expert info on CID mismatch with connection
tvb_memcpy(tvb, dcid->cid, offset, dcil);
dcid->len = dcil;
offset += dcil;
}
if (scil) {
scil += 3;
proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
// TODO expert info on CID mismatch with connection
tvb_memcpy(tvb, scid->cid, offset, scil);
scid->len = scil;
offset += scil;
}
if (dcid->len > 0) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", cid_to_string(dcid));
}
@ -1600,10 +1562,8 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre
offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, &version, &dcid, &scid);
if (!is_quic_draft_max(version, 10)) {
proto_tree_add_item_ret_varint(quic_tree, hf_quic_payload_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
offset += len_payload_length;
}
proto_tree_add_item_ret_varint(quic_tree, hf_quic_payload_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
offset += len_payload_length;
pkn = dissect_quic_packet_number(tvb, pinfo, quic_tree, offset, conn, quic_packet, 4);
offset += 4;
@ -1642,26 +1602,13 @@ dissect_quic_short_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tr
gboolean key_phase = FALSE;
tls13_cipher *cipher = NULL;
quic_info_data_t *conn = quic_packet->conn;
// Best-effort guess: if no connection is known, assume newer draft version.
gboolean is_draft10 = conn && is_quic_draft_max(conn->version, 10);
short_flags = tvb_get_guint8(tvb, offset);
if (is_draft10) {
gboolean omit_cid;
proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_ocid_flag, tvb, offset, 1, ENC_NA, &omit_cid);
dcid.len = omit_cid ? 0 : 8;
proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag_draft10, tvb, offset, 1, ENC_NA, &key_phase);
ti = proto_tree_add_item(quic_tree, hf_quic_short_packet_type_draft10, tvb, offset, 1, ENC_NA);
if ((short_flags & 0x18) != 0x10) {
expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
"Fourth bit (0x10) must be 1, fifth bit (0x8) must be set to 0.");
}
} else {
proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag, tvb, offset, 1, ENC_NA, &key_phase);
proto_tree_add_item(quic_tree, hf_quic_short_packet_type, tvb, offset, 1, ENC_NA);
if (conn) {
dcid.len = quic_packet->from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
}
proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag, tvb, offset, 1, ENC_NA, &key_phase);
proto_tree_add_item(quic_tree, hf_quic_short_packet_type, tvb, offset, 1, ENC_NA);
if (conn) {
dcid.len = quic_packet->from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
}
offset += 1;
@ -1751,23 +1698,9 @@ quic_extract_header(tvbuff_t *tvb, guint8 *long_packet_type, guint32 *version,
}
offset++;
guint32 maybe_version = tvb_get_ntohl(tvb, offset);
gboolean is_draft10 = FALSE;
if (!(maybe_version == 0 || quic_draft_version(maybe_version) >= 11)) {
// not a draft -11 version negotiation packet nor draft -11 version,
// assume draft -10 or older. Its version comes after CID.
guint32 version10 = tvb_get_ntohl(tvb, offset + 8);
is_draft10 = is_quic_draft_max(version10, 10);
if (is_draft10) {
maybe_version = version10;
}
}
*version = maybe_version;
*version = tvb_get_ntohl(tvb, offset);
if (is_draft10) {
tvb_memcpy(tvb, dcid->cid, offset, 8);
dcid->len = 8;
} else if (is_long_header) {
if (is_long_header) {
// skip version
offset += 4;
@ -1833,17 +1766,7 @@ dissect_quic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
quic_extract_header(tvb, &long_packet_type, &version, &dcid, &scid);
conn = quic_connection_find(pinfo, long_packet_type, &dcid, &from_server);
if (is_quic_draft_max(version, 10)) {
// In draft -10 and before, there is only a single CID.
if (long_packet_type == QUIC_LPT_HANDSHAKE && !conn) {
// the first handshake packet from server sets CID, only after
// that it will be possible to match by CID.
conn = quic_connection_find_dcid(pinfo, NULL, &from_server);
}
quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &dcid, &dcid, from_server);
} else {
quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
}
quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
quic_packet->conn = conn;
quic_packet->from_server = from_server;
#if 0
@ -1858,7 +1781,6 @@ dissect_quic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item_ret_uint(quic_tree, hf_quic_header_form, tvb, offset, 1, ENC_NA, &header_form);
if(header_form) {
gboolean is_vn = tvb_get_ntohl(tvb, offset + 1) == 0;
is_vn = is_vn || tvb_get_ntohl(tvb, offset + 1 + 8) == 0; // before draft -11
if (is_vn) {
offset = dissect_quic_version_negotiation(tvb, pinfo, quic_tree, offset, quic_packet);
return offset;
@ -1882,11 +1804,6 @@ static gboolean dissect_quic_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree
* (absolute minimum: 11 + payload)
* (for Version Negotiation, payload len + PKN + payload is replaced by
* Supported Version (multiple of 4 bytes.)
*
* Draft -10 and before:
* Flag (1 byte) + Connection ID (8 bytes) + Version (4 bytes) + packet
* number (4 bytes) + Payload.
* (absolute minimum: 17 + payload)
*/
conversation_t *conversation = NULL;
int offset = 0;
@ -1909,11 +1826,6 @@ static gboolean dissect_quic_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree
// check for draft QUIC version (for draft -11 and newer)
is_quic = quic_draft_version(tvb_get_ntohl(tvb, offset)) >= 11;
// check for draft QUIC version (after 8 byte CID) for draft -10 and older
if (!is_quic && tvb_bytes_exist(tvb, offset + 8, 4)) {
is_quic = is_quic_draft_max(tvb_get_ntohl(tvb, offset + 8), 10);
}
if (is_quic) {
conversation = find_or_create_conversation(pinfo);
conversation_set_dissector(conversation, quic_handle);
@ -2018,26 +1930,11 @@ proto_register_quic(void)
FT_UINT8, BASE_HEX, NULL, 0x7F,
NULL, HFILL }
},
{ &hf_quic_short_ocid_flag,
{ "Omit Connection ID Flag", "quic.short.ocid_flag",
FT_BOOLEAN, 8, NULL, SH_OCID,
NULL, HFILL }
},
{ &hf_quic_short_kp_flag_draft10,
{ "Key Phase Bit", "quic.short.kp_flag_draft10",
FT_BOOLEAN, 8, NULL, SH_KP_10,
NULL, HFILL }
},
{ &hf_quic_short_kp_flag,
{ "Key Phase Bit", "quic.short.kp_flag",
FT_BOOLEAN, 8, NULL, SH_KP,
NULL, HFILL }
},
{ &hf_quic_short_packet_type_draft10,
{ "Packet Type", "quic.short.packet_type_draft10",
FT_UINT8, BASE_DEC, VALS(quic_short_packet_type_vals), SH_PT_10,
"Short Header Packet Type", HFILL }
},
{ &hf_quic_short_packet_type,
{ "Packet Type", "quic.short.packet_type",
FT_UINT8, BASE_DEC, VALS(quic_short_packet_type_vals), SH_PT,