forked from osmocom/wireshark
Add support for dissecting UDT over DTLS
Includes adding per-conversation data to store whether we are over DTLS or UDP and registering as a heuristic sub-dissector for DTLS. Future changes will add more use of the conversation structure. Also included is a capture of UDT over DTLS in test/captures/udt-dtls.pcapng.gz, the associated private key for the session in test/keys/udt-dtls.key and a new test in the decryption suite to check this works. Change-Id: I76826d3b35768d0b58f5335063884616968e5784 Reviewed-on: https://code.wireshark.org/review/22533 Reviewed-by: Peter Wu <peter@lekensteyn.nl> Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
723c76b12c
commit
ffb8bbd372
|
@ -31,6 +31,13 @@
|
|||
#include <epan/conversation.h>
|
||||
#include <epan/expert.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -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-----
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue