diff --git a/epan/dissectors/packet-udt.c b/epan/dissectors/packet-udt.c index 92b364bc87..a9f2d06e42 100644 --- a/epan/dissectors/packet-udt.c +++ b/epan/dissectors/packet-udt.c @@ -31,6 +31,13 @@ #include #include +/* + * Per-conversation information + */ +typedef struct _udt_conversation { + gboolean is_dtls; +} udt_conversation; + /* * based on http://tools.ietf.org/html/draft-gg-udt-03 */ @@ -111,10 +118,10 @@ static int dissect_udt(tvbuff_t *tvb, packet_info* pinfo, proto_tree *parent_tree, void *data _U_) { - proto_tree *tree; - proto_item *udt_item; - int is_control, type; - guint i; + proto_tree *tree; + proto_item *udt_item; + int is_control, type; + guint i; col_set_str(pinfo->cinfo, COL_PROTOCOL, "UDT"); col_clear(pinfo->cinfo, COL_INFO); @@ -312,34 +319,65 @@ dissect_udt(tvbuff_t *tvb, packet_info* pinfo, proto_tree *parent_tree, } static gboolean -dissect_udt_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +dissect_udt_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data, gboolean is_dtls) { conversation_t *conv; - - /* Must have at least 24 captured bytes for heuristic check */ - if (tvb_captured_length(tvb) < 24) - return FALSE; - - /* detect handshake control packet */ - if (tvb_get_ntohl(tvb, 0) != (0x80000000 | UDT_PACKET_TYPE_HANDSHAKE)) - return FALSE; - - /* must be version 4 */ - if ((tvb_get_ntohl(tvb, 16) != 4)) - return FALSE; - - /* must be datagram or stream */ - if ((tvb_get_ntohl(tvb, 20) != UDT_HANDSHAKE_TYPE_DGRAM) - && (tvb_get_ntohl(tvb, 20) != UDT_HANDSHAKE_TYPE_STREAM)) - return FALSE; + udt_conversation *udt_conv; conv = find_or_create_conversation(pinfo); - conversation_set_dissector(conv, udt_handle); - dissect_udt(tvb, pinfo, tree, data); + udt_conv = (udt_conversation *)conversation_get_proto_data(conv, proto_udt); + if (udt_conv) { + // Already identified conversation as UDT - BUT we might have been called from + // the other dissector. + if (is_dtls != udt_conv->is_dtls) + return FALSE; + dissect_udt(tvb, pinfo, tree, data); + } else { + // Check if this is UDT... + + /* Must have at least 24 captured bytes for heuristic check */ + if (tvb_captured_length(tvb) < 24) + return FALSE; + + /* detect handshake control packet */ + if (tvb_get_ntohl(tvb, 0) != (0x80000000 | UDT_PACKET_TYPE_HANDSHAKE)) + return FALSE; + + /* must be version 4 */ + if ((tvb_get_ntohl(tvb, 16) != 4)) + return FALSE; + + /* must be datagram or stream */ + if ((tvb_get_ntohl(tvb, 20) != UDT_HANDSHAKE_TYPE_DGRAM) + && (tvb_get_ntohl(tvb, 20) != UDT_HANDSHAKE_TYPE_STREAM)) + return FALSE; + + /* This looks like UDT! */ + udt_conv = wmem_new0(wmem_file_scope(), udt_conversation); + udt_conv->is_dtls = is_dtls; + conversation_add_proto_data(conv, proto_udt, udt_conv); + // DTLS should remain the dissector of record for encrypted conversations + if (!is_dtls) + conversation_set_dissector(conv, udt_handle); + + dissect_udt(tvb, pinfo, tree, data); + } return TRUE; } +static gboolean +dissect_udt_heur_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + return dissect_udt_heur(tvb, pinfo, tree, data, FALSE /* Not DTLS */); +} + +static gboolean +dissect_udt_heur_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + return dissect_udt_heur(tvb, pinfo, tree, data, TRUE /* Is DTLS */); +} + void proto_register_udt(void) { expert_module_t *expert_udt; @@ -493,13 +531,16 @@ void proto_register_udt(void) expert_udt = expert_register_protocol(proto_udt); expert_register_field_array(expert_udt, ei, array_length(ei)); + + register_dissector("udt", dissect_udt, proto_udt); } void proto_reg_handoff_udt(void) { udt_handle = create_dissector_handle(dissect_udt, proto_udt); - heur_dissector_add("udp", dissect_udt_heur, "UDT over UDP", "udt_udp", proto_udt, HEURISTIC_ENABLE); + heur_dissector_add("udp", dissect_udt_heur_udp, "UDT over UDP", "udt_udp", proto_udt, HEURISTIC_ENABLE); + heur_dissector_add("dtls", dissect_udt_heur_dtls, "UDT over DTLS", "udt_dtls", proto_udt, HEURISTIC_ENABLE); dissector_add_for_decode_as_with_preference("udp.port", udt_handle); } diff --git a/test/captures/udt-dtls.pcapng.gz b/test/captures/udt-dtls.pcapng.gz new file mode 100644 index 0000000000..67750f3729 Binary files /dev/null and b/test/captures/udt-dtls.pcapng.gz differ diff --git a/test/keys/udt-dtls.key b/test/keys/udt-dtls.key new file mode 100644 index 0000000000..b4db542e94 --- /dev/null +++ b/test/keys/udt-dtls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDg/jR4vVFNpBta +s1uv4IXhqpePHIIuOoOnb2sK6G8gXdCxKm406JLecNuIqq0eUydH6oawar96vYGM +lLKTfvMnN3RgL3wNG6G+x+zYPjMaS6G+X8SPAG/XtlIxzDFdzliJT4WpKw1nNa7V +sryYTYLZ4aX0hbbETuvXhdZTqCUYX8t2TYyTjeTBybWLyXcWZReGShHPlThn55b0 +rtUXkUQoTl3iv330jvJX8MN8haRLwr4+s2jYIGhsINdvMziGo89Eh1FYJXeC4en0 +FTEzIx9XA8FiVA8Rf1EEJv6syIvE11GGBCrX0Hu1brg7n6Y0TvkQGcL8tbrFDKlE +W7HlQk9TAgMBAAECggEBALfNk8orRxc5gItJSRbWQilH9saYEJV5ggIv2G+x0M7N +NWb2dc/NS+ZipkXwwLqsTcPHiT7oBgNce1AATh6GsFeSSwUk5Z/DuhAkPY2uyoqp +zLm8fNQiFDxSGrXJzW6H2vZZu6Smoi11wp2bhcyaTdJ3L98huVyH6M1J7fyruZo9 +Z8GssyCSujfze7cIc7Py1wEEC0+LzGijkc70HDgsxwj6TXKx/ifXi+5tCCesA3z1 +6AIe0zMTcwpXRbdEZGO9fvBxGoK9hwiVJ6/sPmxFXWpBfu6TMLJjLcwwvnoNuWdH +83+PfD+sdE7zo6CUEGDHPvJ/Fyq5lIGjEP0ErruGKPkCgYEA9PyUvC3nHkGN+5t9 +JNDaNZWEaiBW7w5yQN5MnQCwK3I8ajE+EDoPl0YDhJW4HFS/iwu8WZeb4pN0WLkT +C2K7Tfb+9G7ebLoQ997l0zEcnHqiKA1CqGpu/g0mcVlGFExthvgv9rmt+1QLTXHJ +F/YirWCTyyIgw11iY2ap8u7kSK0CgYEA6xuHHFTtH2pjRXxuOBhwsvA+8oNd/4A8 +phNfJgS7t9LYDMqzyer0ixdkae1vH4peZ1USn6326Vx53hYulH0A69iNM7zrNWM7 +JI+y0ftyb/Ji7CwpQAd3JVjUjvoQljrpPqrArm8fGhTucqS8E1fY1u98b3N85RrY +u3uAcwGb9/8CgYAys08ovqs1FMYIiz5T7zEpo77ao8S6BphYmmjqmSjcZPDh3T0F +6K4vVVsHBmEq49McOJqLRBgLxQ5wCiVJ1u4CjZpoBcXcZIl8ctHHakOMksiaV1wz +NIux4hDRpnMdYk/MffKXMggymksYhPLkFZlJnlIX2QFEzT++aJHFZ/EwpQKBgCs8 +QLiBFao1UlQw8cP3GqKNc8X9Sof1+TFBVroTHMJNT9XqYO28+4OopZqlQ041j+7I +wkgDIekATJj+00oTQtwcUrs0/rwup22tz2C2MPFNTcvIwz03Ij4H++7fJbW617Hi +jNSHMt0FBGSozr1v5jyAhg2o20r2iOzRZWnA3gHZAoGAXkvhtQxD5sdypzUhs6uS +d3PgKTbQK8PLU5KGl7DZ2oaemQ2QUQw0J9tlEQRItTxB+MDf21FddD8n6c1a3zJa +gay7xiarE8JN0pHoQ1qCqZBwWXQRSPiNu8Bxu2oPpUi2iQdBVQG1bACQOToVUDpv +wCW2aisjPbg71ZkZEvhk2cg= +-----END PRIVATE KEY----- diff --git a/test/suite-decryption.sh b/test/suite-decryption.sh index a5774708a8..8f81812252 100755 --- a/test/suite-decryption.sh +++ b/test/suite-decryption.sh @@ -176,6 +176,25 @@ decryption_step_dtls_psk_aes128ccm8() { test_step_ok } +# UDT over DTLS 1.2 with RSA key +decryption_step_udt_dtls() { + TEST_KEYS_FILE="$TESTS_DIR/keys/udt-dtls.key" + if [ "$WS_SYSTEM" == "Windows" ] ; then + TEST_KEYS_FILE="`cygpath -w $TEST_KEYS_FILE`" + fi + $TESTS_DIR/run_and_catch_crashes env $TS_DC_ENV $TSHARK $TS_DC_ARGS \ + -o dtls.keys_list:"0.0.0.0,0,data,$TEST_KEYS_FILE" \ + -Y "dtls && udt.type==ack" \ + -r "$CAPTURE_DIR/udt-dtls.pcapng.gz" \ + | grep UDT > /dev/null + RETURNVALUE=$? + if [ ! $RETURNVALUE -eq $EXIT_OK ]; then + test_step_failed "Failed to decrypt UDT/DTLS using the server's RSA private key" + return + fi + test_step_ok +} + # IPsec ESP # https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12671 decryption_step_ipsec_esp() { @@ -633,6 +652,7 @@ tshark_decryption_suite() { test_step_add "IEEE 802.11 WPA TDLS Decryption" decryption_step_80211_wpa_tdls test_step_add "DTLS Decryption" decryption_step_dtls test_step_add "DTLS 1.2 Decryption (PSK AES-128-CCM-8)" decryption_step_dtls_psk_aes128ccm8 + test_step_add "UDT over DTLS 1.2 Decryption" decryption_step_udt_dtls test_step_add "IPsec ESP Decryption" decryption_step_ipsec_esp test_step_add "SSL Decryption (private key)" decryption_step_ssl test_step_add "SSL Decryption (RSA private key with p smaller than q)" decryption_step_ssl_rsa_pq