2006-06-27 13:36:10 +00:00
/* packet-dtls.c
* Routines for dtls dissection
* Copyright ( c ) 2006 , Authesserre Samuel < sauthess @ gmail . com >
2007-11-05 23:05:20 +00:00
* Copyright ( c ) 2007 , Mikael Magnusson < mikma @ users . sourceforge . net >
2013-12-08 00:58:06 +00:00
* Copyright ( c ) 2013 , Hauke Mehrtens < hauke @ hauke - m . de >
2006-06-27 13:36:10 +00:00
*
2006-08-02 08:15:51 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2006-06-27 13:36:10 +00:00
* Copyright 1998 Gerald Combs
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
2012-06-28 23:18:38 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
2006-06-27 13:36:10 +00:00
*
2006-08-02 08:15:51 +00:00
*
* DTLS dissection and decryption .
* See RFC 4347 for details about DTLS specs .
*
2007-03-24 13:21:08 +00:00
* Notes :
2011-12-29 20:23:18 +00:00
* This dissector is based on the TLS dissector ( packet - ssl . c ) ; Because of the similarity
* of DTLS and TLS , decryption works like TLS with RSA key exchange .
* This dissector uses the sames things ( file , libraries ) as the SSL dissector ( gnutls , packet - ssl - utils . h )
* to make it easily maintainable .
2006-08-02 08:15:51 +00:00
*
2011-12-29 20:23:18 +00:00
* It was developed to dissect and decrypt the OpenSSL v 0.9 .8f DTLS implementation .
* It is limited to this implementation ; there is no complete implementation .
2007-03-24 13:21:08 +00:00
*
2006-08-02 08:15:51 +00:00
* Implemented :
* - DTLS dissection
* - DTLS decryption ( openssl one )
2007-03-24 13:21:08 +00:00
*
2006-08-02 08:15:51 +00:00
* Todo :
2007-03-24 13:21:08 +00:00
* - activate correct Mac calculation when openssl will be corrected
* ( or if an other implementation works ) ,
2006-08-02 08:15:51 +00:00
* corrected code is ready and commented in packet - ssl - utils . h file .
2013-02-23 01:57:15 +00:00
* - add missing things ( desegmentation , reordering . . . that aren ' t present in actual OpenSSL implementation )
2006-06-27 13:36:10 +00:00
*/
2012-09-20 02:03:38 +00:00
# include "config.h"
2006-06-27 13:36:10 +00:00
2011-12-29 21:08:53 +00:00
# include <epan/packet.h>
2013-12-21 17:23:17 +00:00
# include <epan/to_str.h>
2007-05-13 20:58:29 +00:00
# include <epan/asn1.h>
2006-06-27 13:36:10 +00:00
# include <epan/tap.h>
2007-11-05 23:05:20 +00:00
# include <epan/reassemble.h>
2011-04-26 21:59:11 +00:00
# include <epan/uat.h>
2012-08-15 16:02:01 +00:00
# include <epan/sctpppids.h>
2013-06-18 01:13:07 +00:00
# include <epan/exported_pdu.h>
2015-11-04 08:45:54 +00:00
# include <wsutil/str_util.h>
2014-12-20 21:23:59 +00:00
# include "packet-ssl-utils.h"
2015-11-09 11:10:22 +00:00
# include "packet-dtls.h"
2011-04-26 21:59:11 +00:00
2013-03-16 16:25:41 +00:00
void proto_register_dtls ( void ) ;
2011-04-26 21:59:11 +00:00
/* DTLS User Access Table */
static ssldecrypt_assoc_t * dtlskeylist_uats = NULL ;
static guint ndtlsdecrypt = 0 ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* we need to remember the top tree so that subdissectors we call are created
* at the root and not deep down inside the DTLS decode
*/
static proto_tree * top_tree ;
2006-06-27 13:36:10 +00:00
/*********************************************************************
*
* Protocol Constants , Variables , Data Structures
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Initialize the protocol and registered fields */
2011-12-29 20:23:18 +00:00
static gint dtls_tap = - 1 ;
2013-06-18 01:13:07 +00:00
static gint exported_pdu_tap = - 1 ;
2011-12-29 20:23:18 +00:00
static gint proto_dtls = - 1 ;
static gint hf_dtls_record = - 1 ;
static gint hf_dtls_record_content_type = - 1 ;
static gint hf_dtls_record_version = - 1 ;
static gint hf_dtls_record_epoch = - 1 ;
static gint hf_dtls_record_sequence_number = - 1 ;
static gint hf_dtls_record_length = - 1 ;
static gint hf_dtls_record_appdata = - 1 ;
static gint hf_dtls_alert_message = - 1 ;
static gint hf_dtls_alert_message_level = - 1 ;
static gint hf_dtls_alert_message_description = - 1 ;
static gint hf_dtls_handshake_protocol = - 1 ;
static gint hf_dtls_handshake_type = - 1 ;
static gint hf_dtls_handshake_length = - 1 ;
static gint hf_dtls_handshake_message_seq = - 1 ;
static gint hf_dtls_handshake_fragment_offset = - 1 ;
static gint hf_dtls_handshake_fragment_length = - 1 ;
2012-02-26 13:50:52 +00:00
static gint hf_dtls_heartbeat_message = - 1 ;
static gint hf_dtls_heartbeat_message_type = - 1 ;
static gint hf_dtls_heartbeat_message_payload_length = - 1 ;
static gint hf_dtls_heartbeat_message_payload = - 1 ;
static gint hf_dtls_heartbeat_message_padding = - 1 ;
2011-12-29 20:23:18 +00:00
static gint hf_dtls_fragments = - 1 ;
static gint hf_dtls_fragment = - 1 ;
static gint hf_dtls_fragment_overlap = - 1 ;
static gint hf_dtls_fragment_overlap_conflicts = - 1 ;
static gint hf_dtls_fragment_multiple_tails = - 1 ;
static gint hf_dtls_fragment_too_long_fragment = - 1 ;
static gint hf_dtls_fragment_error = - 1 ;
static gint hf_dtls_fragment_count = - 1 ;
static gint hf_dtls_reassembled_in = - 1 ;
static gint hf_dtls_reassembled_length = - 1 ;
2007-11-05 23:05:20 +00:00
2014-07-19 08:54:19 +00:00
/* header fields used in ssl-utils, but defined here. */
static dtls_hfs_t dtls_hfs = { - 1 , - 1 } ;
2006-06-27 13:36:10 +00:00
/* Initialize the subtree pointers */
static gint ett_dtls = - 1 ;
static gint ett_dtls_record = - 1 ;
static gint ett_dtls_alert = - 1 ;
static gint ett_dtls_handshake = - 1 ;
2012-02-26 13:50:52 +00:00
static gint ett_dtls_heartbeat = - 1 ;
2006-06-27 13:36:10 +00:00
static gint ett_dtls_certs = - 1 ;
2007-11-05 23:05:20 +00:00
static gint ett_dtls_fragment = - 1 ;
static gint ett_dtls_fragments = - 1 ;
2013-06-09 03:28:05 +00:00
static expert_field ei_dtls_handshake_fragment_length_too_long = EI_INIT ;
2015-07-17 14:31:32 +00:00
static expert_field ei_dtls_handshake_fragment_length_zero = EI_INIT ;
2013-06-09 03:28:05 +00:00
static expert_field ei_dtls_handshake_fragment_past_end_msg = EI_INIT ;
static expert_field ei_dtls_msg_len_diff_fragment = EI_INIT ;
2014-04-11 11:13:42 +00:00
static expert_field ei_dtls_heartbeat_payload_length = EI_INIT ;
2013-06-09 03:28:05 +00:00
2014-07-19 09:06:25 +00:00
static ssl_master_key_map_t dtls_master_key_map ;
2011-12-29 20:23:18 +00:00
static GHashTable * dtls_key_hash = NULL ;
2015-11-06 04:20:45 +00:00
static wmem_stack_t * key_list_stack = NULL ;
2013-03-22 23:59:54 +00:00
static reassembly_table dtls_reassembly_table ;
2015-11-06 04:20:45 +00:00
static dissector_table_t dtls_associations = NULL ;
2011-12-29 20:23:18 +00:00
static dissector_handle_t dtls_handle = NULL ;
static StringInfo dtls_compressed_data = { NULL , 0 } ;
static StringInfo dtls_decrypted_data = { NULL , 0 } ;
static gint dtls_decrypted_data_avail = 0 ;
2014-07-25 11:19:14 +00:00
static FILE * dtls_keylog_file = NULL ;
2011-12-29 20:23:18 +00:00
static uat_t * dtlsdecrypt_uat = NULL ;
2012-04-30 19:14:14 +00:00
static const gchar * dtls_keys_list = NULL ;
2013-12-06 23:55:08 +00:00
static ssl_common_options_t dtls_options = { NULL , NULL } ;
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# ifdef HAVE_LIBGCRYPT
2012-04-30 19:14:14 +00:00
static const gchar * dtls_debug_file_name = NULL ;
2006-08-26 00:05:26 +00:00
# endif
2006-06-27 13:36:10 +00:00
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
static heur_dissector_list_t heur_subdissector_list ;
2007-11-05 23:05:20 +00:00
static const fragment_items dtls_frag_items = {
2009-10-16 21:17:57 +00:00
/* Fragment subtrees */
& ett_dtls_fragment ,
& ett_dtls_fragments ,
/* Fragment fields */
& hf_dtls_fragments ,
& hf_dtls_fragment ,
& hf_dtls_fragment_overlap ,
& hf_dtls_fragment_overlap_conflicts ,
& hf_dtls_fragment_multiple_tails ,
& hf_dtls_fragment_too_long_fragment ,
& hf_dtls_fragment_error ,
2011-01-30 21:01:07 +00:00
& hf_dtls_fragment_count ,
2009-10-16 21:17:57 +00:00
/* Reassembled in field */
& hf_dtls_reassembled_in ,
2010-02-02 16:01:52 +00:00
/* Reassembled length field */
& hf_dtls_reassembled_length ,
2012-09-07 02:09:59 +00:00
/* Reassembled data field */
NULL ,
2009-10-16 21:17:57 +00:00
/* Tag */
" Message fragments "
2007-11-05 23:05:20 +00:00
} ;
2013-12-23 20:42:43 +00:00
static SSL_COMMON_LIST_T ( dissect_dtls_hf ) ;
2006-08-02 08:15:51 +00:00
/* initialize/reset per capture state data (dtls sessions cache) */
2007-03-24 13:21:08 +00:00
static void
2006-08-02 08:15:51 +00:00
dtls_init ( void )
2006-06-27 13:36:10 +00:00
{
2011-04-26 21:59:11 +00:00
module_t * dtls_module = prefs_find_module ( " dtls " ) ;
2011-12-29 20:23:18 +00:00
pref_t * keys_list_pref ;
2011-04-26 21:59:11 +00:00
2015-06-28 14:31:18 +00:00
ssl_common_init ( & dtls_master_key_map ,
2014-07-25 11:19:14 +00:00
& dtls_decrypted_data , & dtls_compressed_data ) ;
2015-03-26 09:23:58 +00:00
reassembly_table_init ( & dtls_reassembly_table , & addresses_ports_reassembly_table_functions ) ;
2011-04-26 21:59:11 +00:00
/* We should have loaded "keys_list" by now. Mark it obsolete */
if ( dtls_module ) {
keys_list_pref = prefs_find_preference ( dtls_module , " keys_list " ) ;
if ( ! prefs_get_preference_obsolete ( keys_list_pref ) ) {
prefs_set_preference_obsolete ( keys_list_pref ) ;
}
}
2006-06-27 13:36:10 +00:00
}
2015-06-28 14:31:18 +00:00
static void
dtls_cleanup ( void )
{
2015-11-06 04:20:45 +00:00
if ( key_list_stack ! = NULL ) {
wmem_destroy_stack ( key_list_stack ) ;
key_list_stack = NULL ;
}
2015-06-28 14:31:18 +00:00
reassembly_table_destroy ( & dtls_reassembly_table ) ;
ssl_common_cleanup ( & dtls_master_key_map , & dtls_keylog_file ,
& dtls_decrypted_data , & dtls_compressed_data ) ;
}
2006-08-02 08:15:51 +00:00
/* parse dtls related preferences (private keys and ports association strings) */
2007-03-24 13:21:08 +00:00
static void
2012-02-10 23:08:46 +00:00
dtls_parse_uat ( void )
2006-06-27 13:36:10 +00:00
{
2015-11-06 04:20:45 +00:00
guint i , port ;
dissector_handle_t handle ;
2006-08-25 08:07:26 +00:00
2006-08-02 08:15:51 +00:00
if ( dtls_key_hash )
2012-02-10 23:08:46 +00:00
{
2006-08-02 08:15:51 +00:00
g_hash_table_destroy ( dtls_key_hash ) ;
2012-02-10 23:08:46 +00:00
}
2006-08-25 08:07:26 +00:00
/* remove only associations created from key list */
2015-11-06 04:20:45 +00:00
if ( key_list_stack ! = NULL ) {
while ( wmem_stack_count ( key_list_stack ) > 0 ) {
port = GPOINTER_TO_UINT ( wmem_stack_pop ( key_list_stack ) ) ;
handle = dissector_get_uint_handle ( dtls_associations , port ) ;
if ( handle ! = NULL )
ssl_association_remove ( " dtls.port " , dtls_handle , handle , port , FALSE ) ;
}
2006-08-25 08:07:26 +00:00
}
2006-06-27 13:36:10 +00:00
2012-02-10 23:08:46 +00:00
/* parse private keys string, load available keys and put them in key hash*/
2015-10-03 17:23:55 +00:00
dtls_key_hash = g_hash_table_new_full ( ssl_private_key_hash ,
ssl_private_key_equal , g_free , ssl_private_key_free ) ;
2012-02-10 23:08:46 +00:00
ssl_set_debug ( dtls_debug_file_name ) ;
if ( ndtlsdecrypt > 0 )
{
2015-11-06 04:20:45 +00:00
if ( key_list_stack = = NULL )
key_list_stack = wmem_stack_new ( NULL ) ;
2012-02-10 23:08:46 +00:00
for ( i = 0 ; i < ndtlsdecrypt ; i + + )
{
ssldecrypt_assoc_t * d = & ( dtlskeylist_uats [ i ] ) ;
2015-11-06 04:20:45 +00:00
ssl_parse_key_list ( d , dtls_key_hash , " dtls.port " , dtls_handle , FALSE ) ;
if ( key_list_stack )
wmem_stack_push ( key_list_stack , GUINT_TO_POINTER ( atoi ( d - > port ) ) ) ;
2012-02-10 23:08:46 +00:00
}
}
2014-06-20 16:43:28 +00:00
dissector_add_for_decode_as ( " sctp.port " , dtls_handle ) ;
dissector_add_for_decode_as ( " udp.port " , dtls_handle ) ;
2012-02-10 23:08:46 +00:00
}
static void
dtls_parse_old_keys ( void )
{
gchar * * old_keys , * * parts , * err ;
guint i ;
2012-08-15 13:56:59 +00:00
gchar * uat_entry ;
2012-02-10 23:08:46 +00:00
2011-04-26 21:59:11 +00:00
/* Import old-style keys */
if ( dtlsdecrypt_uat & & dtls_keys_list & & dtls_keys_list [ 0 ] ) {
2015-01-09 17:28:10 +00:00
old_keys = wmem_strsplit ( NULL , dtls_keys_list , " ; " , 0 ) ;
2011-04-26 21:59:11 +00:00
for ( i = 0 ; old_keys [ i ] ! = NULL ; i + + ) {
2015-01-09 17:28:10 +00:00
parts = wmem_strsplit ( NULL , old_keys [ i ] , " , " , 4 ) ;
2011-04-26 21:59:11 +00:00
if ( parts [ 0 ] & & parts [ 1 ] & & parts [ 2 ] & & parts [ 3 ] ) {
2015-07-20 17:02:08 +00:00
gchar * path = uat_esc ( parts [ 3 ] , ( guint ) strlen ( parts [ 3 ] ) ) ;
2015-01-09 17:28:10 +00:00
uat_entry = wmem_strdup_printf ( NULL , " \" %s \" , \" %s \" , \" %s \" , \" %s \" , \" \" " ,
2015-07-20 17:02:08 +00:00
parts [ 0 ] , parts [ 1 ] , parts [ 2 ] , path ) ;
g_free ( path ) ;
2012-08-15 13:56:59 +00:00
if ( ! uat_load_str ( dtlsdecrypt_uat , uat_entry , & err ) ) {
2011-12-29 20:23:18 +00:00
ssl_debug_printf ( " dtls_parse: Can't load UAT string %s: %s \n " ,
2012-08-15 13:56:59 +00:00
uat_entry , err ) ;
2015-01-10 00:50:09 +00:00
g_free ( err ) ;
2011-12-29 20:23:18 +00:00
}
2015-01-09 17:28:10 +00:00
wmem_free ( NULL , uat_entry ) ;
2011-04-26 21:59:11 +00:00
}
2015-01-09 17:28:10 +00:00
wmem_free ( NULL , parts ) ;
2011-04-26 21:59:11 +00:00
}
2015-01-09 17:28:10 +00:00
wmem_free ( NULL , old_keys ) ;
2011-04-26 21:59:11 +00:00
}
2006-06-27 13:36:10 +00:00
}
/*
2006-08-02 08:15:51 +00:00
* DTLS Dissection Routines
2006-06-27 13:36:10 +00:00
*
*/
2006-08-02 08:15:51 +00:00
2006-06-27 13:36:10 +00:00
/* record layer dissector */
2006-08-02 08:15:51 +00:00
static gint dissect_dtls_record ( tvbuff_t * tvb , packet_info * pinfo ,
2009-10-16 21:17:57 +00:00
proto_tree * tree , guint32 offset ,
2014-04-26 09:38:40 +00:00
SslSession * session , gint is_from_server ,
2009-10-16 21:17:57 +00:00
SslDecryptSession * conv_data ) ;
2006-06-27 13:36:10 +00:00
/* alert message dissector */
2006-08-02 08:15:51 +00:00
static void dissect_dtls_alert ( tvbuff_t * tvb , packet_info * pinfo ,
2006-06-27 13:36:10 +00:00
proto_tree * tree , guint32 offset ,
2014-05-24 14:51:10 +00:00
const SslSession * session ) ;
2006-06-27 13:36:10 +00:00
/* handshake protocol dissector */
2006-08-02 08:15:51 +00:00
static void dissect_dtls_handshake ( tvbuff_t * tvb , packet_info * pinfo ,
2006-06-27 13:36:10 +00:00
proto_tree * tree , guint32 offset ,
guint32 record_length ,
2014-04-26 09:38:40 +00:00
SslSession * session , gint is_from_server ,
2006-06-27 13:36:10 +00:00
SslDecryptSession * conv_data , guint8 content_type ) ;
2012-02-26 13:50:52 +00:00
/* heartbeat message dissector */
static void dissect_dtls_heartbeat ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * tree , guint32 offset ,
2014-05-24 14:51:10 +00:00
const SslSession * session , guint32 record_length ,
2014-04-11 11:13:42 +00:00
gboolean decrypted ) ;
2012-02-26 13:50:52 +00:00
2012-02-06 22:14:30 +00:00
static int dissect_dtls_hnd_hello_verify_request ( tvbuff_t * tvb ,
2009-10-16 21:17:57 +00:00
proto_tree * tree ,
guint32 offset ,
SslDecryptSession * ssl ) ;
2006-06-27 13:36:10 +00:00
/*
* Support Functions
*
*/
2006-08-02 08:15:51 +00:00
static gint looks_like_dtls ( tvbuff_t * tvb , guint32 offset ) ;
2006-06-27 13:36:10 +00:00
/*********************************************************************
*
* Main dissector
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Code to actually dissect the packets
*/
2015-11-23 03:59:08 +00:00
static int
dissect_dtls ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2006-06-27 13:36:10 +00:00
{
2011-12-29 20:23:18 +00:00
conversation_t * conversation ;
proto_item * ti ;
proto_tree * dtls_tree ;
guint32 offset ;
gboolean first_record_in_frame ;
SslDecryptSession * ssl_session ;
2014-05-24 14:51:10 +00:00
SslSession * session ;
2014-04-26 09:38:40 +00:00
gint is_from_server ;
2011-12-29 20:23:18 +00:00
ti = NULL ;
dtls_tree = NULL ;
offset = 0 ;
2006-08-02 08:15:51 +00:00
first_record_in_frame = TRUE ;
2011-12-29 20:23:18 +00:00
ssl_session = NULL ;
top_tree = tree ;
2006-08-02 08:15:51 +00:00
/* Track the version using conversations allows
* us to more frequently set the protocol column properly
* for continuation data frames .
*
* Also : We use the copy in conv_version as our cached copy ,
* so that we don ' t have to search the conversation
* table every time we want the version ; when setting
* the conv_version , must set the copy in the conversation
* in addition to conv_version
*/
2010-05-13 18:28:34 +00:00
conversation = find_or_create_conversation ( pinfo ) ;
2015-02-05 18:54:52 +00:00
ssl_session = ssl_get_session ( conversation , dtls_handle ) ;
2014-05-24 14:51:10 +00:00
session = & ssl_session - > session ;
2015-02-05 18:54:52 +00:00
is_from_server = ssl_packet_from_server ( session , dtls_associations , pinfo ) ;
if ( session - > last_nontls_frame ! = 0 & &
2016-01-24 03:40:51 +00:00
session - > last_nontls_frame > = pinfo - > num ) {
2015-02-05 18:54:52 +00:00
/* This conversation started at a different protocol and STARTTLS was
* used , but this packet comes too early . */
2015-11-23 03:59:08 +00:00
return 0 ;
2015-02-05 18:54:52 +00:00
}
2006-06-27 13:36:10 +00:00
2007-03-24 13:21:08 +00:00
/* try decryption only the first time we see this packet
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
* ( to keep cipher synchronized ) */
if ( pinfo - > fd - > flags . visited )
2007-03-24 13:21:08 +00:00
ssl_session = NULL ;
2006-08-02 08:15:51 +00:00
/* Initialize the protocol column; we'll set it later when we
2015-11-14 11:47:28 +00:00
* figure out what flavor of DTLS it is */
2009-08-09 07:59:51 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " DTLS " ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* clear the the info column */
2009-08-09 07:36:13 +00:00
col_clear ( pinfo - > cinfo , COL_INFO ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* Create display subtree for SSL as a whole */
2013-08-29 14:25:38 +00:00
ti = proto_tree_add_item ( tree , proto_dtls , tvb , 0 , - 1 , ENC_NA ) ;
dtls_tree = proto_item_add_subtree ( ti , ett_dtls ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* iterate through the records in this tvbuff */
while ( tvb_reported_length_remaining ( tvb , offset ) ! = 0 )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
/* on second and subsequent records per frame
* add a delimiter on info column
*/
2010-01-13 20:32:01 +00:00
if ( ! first_record_in_frame )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " , " ) ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
/* first try to dispatch off the cached version
* known to be associated with the conversation
*/
2014-05-24 14:51:10 +00:00
switch ( session - > version ) {
2015-11-14 12:33:02 +00:00
case DTLSV1DOT0_VERSION :
case DTLSV1DOT0_OPENSSL_VERSION :
case DTLSV1DOT2_VERSION :
2012-03-28 09:31:04 +00:00
offset = dissect_dtls_record ( tvb , pinfo , dtls_tree ,
2014-04-26 09:38:40 +00:00
offset , session , is_from_server ,
2012-03-28 09:31:04 +00:00
ssl_session ) ;
break ;
2009-10-16 21:17:57 +00:00
/* that failed, so apply some heuristics based
* on this individual packet
*/
2006-08-02 08:15:51 +00:00
default :
2009-10-16 21:17:57 +00:00
if ( looks_like_dtls ( tvb , offset ) )
{
/* looks like dtls */
offset = dissect_dtls_record ( tvb , pinfo , dtls_tree ,
2014-04-26 09:38:40 +00:00
offset , session , is_from_server ,
2009-10-16 21:17:57 +00:00
ssl_session ) ;
}
else
{
/* looks like something unknown, so lump into
* continuation data
*/
2014-07-08 16:34:04 +00:00
offset = tvb_reported_length ( tvb ) ;
2009-10-16 21:17:57 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO ,
" Continuation Data " ) ;
/* Set the protocol column */
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " DTLS " ) ;
}
break ;
2006-08-02 08:15:51 +00:00
}
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* set up for next record in frame, if any */
first_record_in_frame = FALSE ;
2006-06-27 13:36:10 +00:00
}
2007-04-18 04:13:50 +00:00
tap_queue_packet ( dtls_tap , pinfo , NULL ) ;
2015-11-23 03:59:08 +00:00
return tvb_captured_length ( tvb ) ;
2006-06-27 13:36:10 +00:00
}
2011-12-29 20:23:18 +00:00
static gboolean
2012-09-10 21:40:21 +00:00
dissect_dtls_heur ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2013-04-18 19:19:38 +00:00
2011-12-29 20:23:18 +00:00
{
/* Stronger confirmation of DTLS packet is provided by verifying the
2013-03-24 18:51:27 +00:00
* captured payload length against the remainder of the UDP packet size . */
2014-07-08 16:34:04 +00:00
guint length = tvb_captured_length ( tvb ) ;
2011-12-29 20:23:18 +00:00
guint offset = 0 ;
if ( tvb_reported_length ( tvb ) = = length ) {
2013-03-24 18:51:27 +00:00
/* The entire payload was captured. */
2011-12-29 20:23:18 +00:00
while ( offset + 13 < = length & & looks_like_dtls ( tvb , offset ) ) {
/* Advance offset to the end of the current DTLS record */
offset + = tvb_get_ntohs ( tvb , offset + 11 ) + 13 ;
if ( offset = = length ) {
2015-11-23 03:59:08 +00:00
dissect_dtls ( tvb , pinfo , tree , data ) ;
2011-12-29 20:23:18 +00:00
return TRUE ;
}
}
if ( pinfo - > fragmented & & offset > = 13 ) {
2015-11-23 03:59:08 +00:00
dissect_dtls ( tvb , pinfo , tree , data ) ;
2011-12-29 20:23:18 +00:00
return TRUE ;
}
return FALSE ;
}
2013-03-24 18:51:27 +00:00
/* This packet was truncated by the capture process due to a snapshot
* length - do our best with what we ' ve got . */
2014-07-08 16:34:04 +00:00
while ( tvb_captured_length_remaining ( tvb , offset ) > = 3 ) {
2011-12-29 20:23:18 +00:00
if ( ! looks_like_dtls ( tvb , offset ) )
return FALSE ;
offset + = 3 ;
2014-07-08 16:34:04 +00:00
if ( tvb_captured_length_remaining ( tvb , offset ) > = 10 ) {
2011-12-29 20:23:18 +00:00
offset + = tvb_get_ntohs ( tvb , offset + 8 ) + 10 ;
} else {
/* Dissect what we've got, which might be as little as 3 bytes. */
2015-11-23 03:59:08 +00:00
dissect_dtls ( tvb , pinfo , tree , data ) ;
2011-12-29 20:23:18 +00:00
return TRUE ;
}
if ( offset = = length ) {
/* Can this ever happen? Well, just in case ... */
2015-11-23 03:59:08 +00:00
dissect_dtls ( tvb , pinfo , tree , data ) ;
2011-12-29 20:23:18 +00:00
return TRUE ;
}
}
/* One last check to see if the current offset is at least less than the
* original number of bytes present before truncation or we ' re dealing with
* a packet fragment that ' s also been truncated . */
if ( ( length > = 3 ) & & ( offset < = tvb_reported_length ( tvb ) | | pinfo - > fragmented ) ) {
2015-11-23 03:59:08 +00:00
dissect_dtls ( tvb , pinfo , tree , data ) ;
2011-12-29 20:23:18 +00:00
return TRUE ;
}
return FALSE ;
}
2014-02-10 20:33:59 +00:00
static gboolean
dtls_is_null_cipher ( guint cipher )
{
switch ( cipher ) {
case 0x0000 :
case 0x0001 :
case 0x0002 :
case 0x002c :
case 0x002d :
case 0x002e :
case 0x003b :
case 0x00b0 :
case 0x00b1 :
case 0x00b4 :
case 0x00b5 :
case 0x00b8 :
case 0x00b9 :
case 0xc001 :
case 0xc006 :
case 0xc00b :
case 0xc010 :
case 0xc015 :
case 0xc039 :
case 0xc03a :
case 0xc03b :
return TRUE ;
default :
return FALSE ;
}
}
2006-08-02 08:15:51 +00:00
static gint
2007-03-24 13:21:08 +00:00
decrypt_dtls_record ( tvbuff_t * tvb , packet_info * pinfo , guint32 offset ,
2009-10-16 21:17:57 +00:00
guint32 record_length , guint8 content_type , SslDecryptSession * ssl ,
gboolean save_plaintext )
2006-06-27 13:36:10 +00:00
{
2011-12-29 20:23:18 +00:00
gint ret ;
SslDecoder * decoder ;
2007-03-24 13:21:08 +00:00
ret = 0 ;
2006-08-02 08:15:51 +00:00
/* if we can decrypt and decryption have success
* add decrypted data to this packet info */
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
if ( ! ssl | | ( ! save_plaintext & & ! ( ssl - > state & SSL_HAVE_SESSION_KEY ) ) ) {
2006-08-02 08:15:51 +00:00
ssl_debug_printf ( " decrypt_dtls_record: no session key \n " ) ;
return ret ;
}
2012-09-23 21:02:32 +00:00
ssl_debug_printf ( " decrypt_dtls_record: app_data len %d, ssl state %X \n " ,
record_length , ssl - > state ) ;
2007-03-24 13:21:08 +00:00
2012-05-05 17:35:35 +00:00
/* retrieve decoder for this packet direction */
2015-02-05 18:54:52 +00:00
if ( ssl_packet_from_server ( & ssl - > session , dtls_associations , pinfo ) ! = 0 ) {
2006-08-02 08:15:51 +00:00
ssl_debug_printf ( " decrypt_dtls_record: using server decoder \n " ) ;
2007-04-10 15:12:48 +00:00
decoder = ssl - > server ;
2006-08-02 08:15:51 +00:00
}
2007-03-24 13:21:08 +00:00
else {
2006-08-02 08:15:51 +00:00
ssl_debug_printf ( " decrypt_dtls_record: using client decoder \n " ) ;
2007-04-10 15:12:48 +00:00
decoder = ssl - > client ;
2006-08-02 08:15:51 +00:00
}
2007-03-24 13:21:08 +00:00
2014-05-22 08:45:40 +00:00
if ( ! decoder & & ! dtls_is_null_cipher ( ssl - > session . cipher ) ) {
2012-02-16 05:21:09 +00:00
ssl_debug_printf ( " decrypt_dtls_record: no decoder available \n " ) ;
return ret ;
}
2006-08-02 08:15:51 +00:00
/* ensure we have enough storage space for decrypted data */
if ( record_length > dtls_decrypted_data . data_len )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
ssl_debug_printf ( " decrypt_dtls_record: allocating %d bytes "
2009-10-16 21:17:57 +00:00
" for decrypt data (old len %d) \n " ,
record_length + 32 , dtls_decrypted_data . data_len ) ;
2013-03-16 16:25:41 +00:00
dtls_decrypted_data . data = ( guchar * ) g_realloc ( dtls_decrypted_data . data ,
2009-10-16 21:17:57 +00:00
record_length + 32 ) ;
2006-08-02 08:15:51 +00:00
dtls_decrypted_data . data_len = record_length + 32 ;
2006-06-27 13:36:10 +00:00
}
2007-03-24 13:21:08 +00:00
/* run decryption and add decrypted payload to protocol data, if decryption
2006-08-02 08:15:51 +00:00
* is successful */
2007-03-24 13:21:08 +00:00
dtls_decrypted_data_avail = dtls_decrypted_data . data_len ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
if ( ssl - > state & SSL_HAVE_SESSION_KEY ) {
2012-05-25 00:54:49 +00:00
if ( ! decoder ) {
ssl_debug_printf ( " decrypt_dtls_record: no decoder available \n " ) ;
return ret ;
}
2011-12-29 20:23:18 +00:00
if ( ssl_decrypt_record ( ssl , decoder , content_type , tvb_get_ptr ( tvb , offset , record_length ) , record_length ,
& dtls_compressed_data , & dtls_decrypted_data , & dtls_decrypted_data_avail ) = = 0 )
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
ret = 1 ;
}
2014-05-22 08:45:40 +00:00
else if ( dtls_is_null_cipher ( ssl - > session . cipher ) ) {
2014-02-10 20:33:59 +00:00
/* Non-encrypting cipher NULL-XXX */
2015-03-02 04:03:27 +00:00
tvb_memcpy ( tvb , dtls_decrypted_data . data , offset , record_length ) ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
dtls_decrypted_data_avail = dtls_decrypted_data . data_len = record_length ;
2006-08-02 08:15:51 +00:00
ret = 1 ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
}
2006-08-02 08:15:51 +00:00
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
if ( ret & & save_plaintext ) {
2011-12-29 20:23:18 +00:00
ssl_add_data_info ( proto_dtls , pinfo , dtls_decrypted_data . data , dtls_decrypted_data_avail ,
tvb_raw_offset ( tvb ) + offset , 0 ) ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
}
2007-01-12 10:25:03 +00:00
2006-08-02 08:15:51 +00:00
return ret ;
2006-06-27 13:36:10 +00:00
}
2015-06-24 19:21:42 +00:00
static void
export_pdu_packet ( tvbuff_t * tvb , packet_info * pinfo , guint tag , const gchar * name )
{
exp_pdu_data_t * exp_pdu_data ;
guint8 tags = EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT ;
2006-06-27 13:36:10 +00:00
2015-06-24 19:21:42 +00:00
exp_pdu_data = load_export_pdu_tags ( pinfo , tag , name , & tags , 1 ) ;
2006-06-27 13:36:10 +00:00
2015-06-24 19:21:42 +00:00
exp_pdu_data - > tvb_captured_length = tvb_captured_length ( tvb ) ;
exp_pdu_data - > tvb_reported_length = tvb_reported_length ( tvb ) ;
exp_pdu_data - > pdu_tvb = tvb ;
tap_queue_packet ( exported_pdu_tap , pinfo , exp_pdu_data ) ;
}
2006-06-27 13:36:10 +00:00
/*********************************************************************
*
2006-08-02 08:15:51 +00:00
* DTLS Dissection Routines
2006-06-27 13:36:10 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-08-02 08:15:51 +00:00
static gint
dissect_dtls_record ( tvbuff_t * tvb , packet_info * pinfo ,
2006-06-27 13:36:10 +00:00
proto_tree * tree , guint32 offset ,
2014-04-26 09:38:40 +00:00
SslSession * session , gint is_from_server ,
2006-06-27 13:36:10 +00:00
SslDecryptSession * ssl )
{
2006-08-02 08:15:51 +00:00
/*
* struct {
* uint8 major , minor ;
* } ProtocolVersion ;
*
*
* enum {
* change_cipher_spec ( 20 ) , alert ( 21 ) , handshake ( 22 ) ,
* application_data ( 23 ) , ( 255 )
* } ContentType ;
*
* struct {
* ContentType type ;
* ProtocolVersion version ;
2011-12-29 20:23:18 +00:00
* uint16 epoch ; // New field
* uint48 sequence_number ; // New field
2006-08-02 08:15:51 +00:00
* uint16 length ;
* opaque fragment [ TLSPlaintext . length ] ;
* } DTLSPlaintext ;
*/
2011-12-29 20:23:18 +00:00
guint32 record_length ;
guint16 version ;
guint16 epoch ;
2013-08-29 14:25:38 +00:00
guint64 sequence_number ;
2011-12-29 20:23:18 +00:00
guint8 content_type ;
guint8 next_byte ;
proto_tree * ti ;
proto_tree * dtls_record_tree ;
SslDataInfo * appl_data ;
2014-05-20 10:54:20 +00:00
heur_dtbl_entry_t * hdtbl_entry ;
2011-12-29 20:23:18 +00:00
2006-08-02 08:15:51 +00:00
/*
* Get the record layer fields of interest
*/
2011-12-29 20:23:18 +00:00
content_type = tvb_get_guint8 ( tvb , offset ) ;
version = tvb_get_ntohs ( tvb , offset + 1 ) ;
epoch = tvb_get_ntohs ( tvb , offset + 3 ) ;
2013-08-29 14:25:38 +00:00
sequence_number = tvb_get_ntoh48 ( tvb , offset + 5 ) ;
2011-12-29 20:23:18 +00:00
record_length = tvb_get_ntohs ( tvb , offset + 11 ) ;
2006-08-02 08:15:51 +00:00
2007-03-24 13:21:08 +00:00
if ( ssl ) {
2015-02-05 18:54:52 +00:00
if ( ssl_packet_from_server ( session , dtls_associations , pinfo ) ) {
2007-04-10 15:12:48 +00:00
if ( ssl - > server ) {
ssl - > server - > seq = ( guint32 ) sequence_number ;
ssl - > server - > epoch = epoch ;
}
2006-08-02 08:15:51 +00:00
}
else {
2007-04-10 15:12:48 +00:00
if ( ssl - > client ) {
ssl - > client - > seq = ( guint32 ) sequence_number ;
ssl - > client - > epoch = epoch ;
}
2006-08-02 08:15:51 +00:00
}
}
if ( ! ssl_is_valid_content_type ( content_type ) ) {
2007-03-24 13:21:08 +00:00
2006-06-27 13:36:10 +00:00
/* if we don't have a valid content_type, there's no sense
* continuing any further
*/
2009-09-24 20:21:23 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " Continuation Data " ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* Set the protocol column */
2009-08-09 07:59:51 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " DTLS " ) ;
2006-08-02 08:15:51 +00:00
return offset + 13 + record_length ;
2007-03-24 13:21:08 +00:00
}
2006-08-02 08:15:51 +00:00
/*
* If GUI , fill in record layer part of tree
*/
2013-08-29 14:25:38 +00:00
/* add the record layer subtree header */
ti = proto_tree_add_item ( tree , hf_dtls_record , tvb ,
2011-10-05 00:25:09 +00:00
offset , 13 + record_length , ENC_NA ) ;
2013-08-29 14:25:38 +00:00
dtls_record_tree = proto_item_add_subtree ( ti , ett_dtls_record ) ;
2006-06-27 13:36:10 +00:00
2013-08-29 14:25:38 +00:00
/* show the one-byte content type */
proto_tree_add_item ( dtls_record_tree , hf_dtls_record_content_type ,
tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + + ;
2006-06-27 13:36:10 +00:00
2013-08-29 14:25:38 +00:00
/* add the version */
proto_tree_add_item ( dtls_record_tree , hf_dtls_record_version , tvb ,
offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
2006-06-27 13:36:10 +00:00
2013-08-29 14:25:38 +00:00
/* show epoch */
proto_tree_add_uint ( dtls_record_tree , hf_dtls_record_epoch , tvb , offset , 2 , epoch ) ;
offset + = 2 ;
2006-06-27 13:36:10 +00:00
2013-08-29 14:25:38 +00:00
/* add sequence_number */
proto_tree_add_uint64 ( dtls_record_tree , hf_dtls_record_sequence_number , tvb , offset , 6 , sequence_number ) ;
offset + = 6 ;
2006-06-27 13:36:10 +00:00
2013-08-29 14:25:38 +00:00
/* add the length */
proto_tree_add_uint ( dtls_record_tree , hf_dtls_record_length , tvb ,
offset , 2 , record_length ) ;
offset + = 2 ; /* move past length field itself */
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/*
* if we don ' t already have a version set for this conversation ,
* but this message ' s version is authoritative ( i . e . , it ' s
* not client_hello , then save the version to to conversation
* structure and print the column version
*/
next_byte = tvb_get_guint8 ( tvb , offset ) ;
2015-11-14 11:47:28 +00:00
if ( session - > version = = SSL_VER_UNKNOWN )
ssl_try_set_version ( session , ssl , content_type , next_byte , TRUE , version ) ;
2015-11-14 12:33:02 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/*
* now dissect the next layer
*/
ssl_debug_printf ( " dissect_dtls_record: content_type %d \n " , content_type ) ;
2007-03-24 13:21:08 +00:00
/* PAOLO try to decrypt each record (we must keep ciphers "in sync")
2006-08-02 08:15:51 +00:00
* store plain text only for app data */
2014-07-10 09:50:23 +00:00
switch ( ( ContentType ) content_type ) {
2006-08-02 08:15:51 +00:00
case SSL_ID_CHG_CIPHER_SPEC :
2009-09-24 20:21:23 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " Change Cipher Spec " ) ;
2015-11-05 10:14:21 +00:00
ssl_dissect_change_cipher_spec ( & dissect_dtls_hf , tvb , pinfo ,
dtls_record_tree , offset , session ,
is_from_server , ssl ) ;
2014-07-11 22:30:12 +00:00
if ( ssl ) {
2014-07-25 11:19:14 +00:00
ssl_load_keyfile ( dtls_options . keylog_filename , & dtls_keylog_file ,
& dtls_master_key_map ) ;
2014-07-19 09:06:25 +00:00
ssl_finalize_decryption ( ssl , & dtls_master_key_map ) ;
2015-02-05 18:54:52 +00:00
ssl_change_cipher ( ssl , ssl_packet_from_server ( session , dtls_associations , pinfo ) ) ;
2014-07-11 22:30:12 +00:00
}
2006-08-02 08:15:51 +00:00
break ;
case SSL_ID_ALERT :
{
tvbuff_t * decrypted ;
decrypted = 0 ;
2007-03-24 13:21:08 +00:00
if ( ssl & & decrypt_dtls_record ( tvb , pinfo , offset ,
2009-10-16 21:17:57 +00:00
record_length , content_type , ssl , FALSE ) )
ssl_add_record_info ( proto_dtls , pinfo , dtls_decrypted_data . data ,
2015-09-14 08:28:30 +00:00
dtls_decrypted_data_avail , tvb_raw_offset ( tvb ) + offset ) ;
2006-08-02 08:15:51 +00:00
2013-02-23 01:57:15 +00:00
/* try to retrieve and use decrypted alert record, if any. */
2015-09-14 08:28:30 +00:00
decrypted = ssl_get_record_info ( tvb , proto_dtls , pinfo , tvb_raw_offset ( tvb ) + offset ) ;
2011-12-16 19:15:17 +00:00
if ( decrypted ) {
2009-10-16 21:17:57 +00:00
dissect_dtls_alert ( decrypted , pinfo , dtls_record_tree , 0 ,
2014-05-24 14:51:10 +00:00
session ) ;
2011-12-16 19:15:17 +00:00
add_new_data_source ( pinfo , decrypted , " Decrypted SSL record " ) ;
} else {
2009-10-16 21:17:57 +00:00
dissect_dtls_alert ( tvb , pinfo , dtls_record_tree , offset ,
2014-05-24 14:51:10 +00:00
session ) ;
2011-12-16 19:15:17 +00:00
}
2006-08-02 08:15:51 +00:00
break ;
}
case SSL_ID_HANDSHAKE :
{
tvbuff_t * decrypted ;
decrypted = 0 ;
2014-11-17 22:12:36 +00:00
ssl_calculate_handshake_hash ( ssl , tvb , offset , record_length ) ;
2007-03-24 13:21:08 +00:00
/* try to decrypt handshake record, if possible. Store decrypted
2013-02-23 01:57:15 +00:00
* record for later usage . The offset is used as ' key ' to identify
2006-08-02 08:15:51 +00:00
* this record into the packet ( we can have multiple handshake records
* in the same frame ) */
2007-03-24 13:21:08 +00:00
if ( ssl & & decrypt_dtls_record ( tvb , pinfo , offset ,
2009-10-16 21:17:57 +00:00
record_length , content_type , ssl , FALSE ) )
ssl_add_record_info ( proto_dtls , pinfo , dtls_decrypted_data . data ,
2015-09-14 08:28:30 +00:00
dtls_decrypted_data_avail , tvb_raw_offset ( tvb ) + offset ) ;
2007-03-24 13:21:08 +00:00
2013-02-23 01:57:15 +00:00
/* try to retrieve and use decrypted handshake record, if any. */
2015-09-14 08:28:30 +00:00
decrypted = ssl_get_record_info ( tvb , proto_dtls , pinfo , tvb_raw_offset ( tvb ) + offset ) ;
2011-12-16 19:15:17 +00:00
if ( decrypted ) {
2009-10-16 21:17:57 +00:00
dissect_dtls_handshake ( decrypted , pinfo , dtls_record_tree , 0 ,
2014-07-08 16:34:04 +00:00
tvb_reported_length ( decrypted ) , session , is_from_server ,
2014-04-26 09:38:40 +00:00
ssl , content_type ) ;
2011-12-16 19:15:17 +00:00
add_new_data_source ( pinfo , decrypted , " Decrypted SSL record " ) ;
} else {
2009-10-16 21:17:57 +00:00
dissect_dtls_handshake ( tvb , pinfo , dtls_record_tree , offset ,
2014-04-26 09:38:40 +00:00
record_length , session , is_from_server , ssl ,
content_type ) ;
2011-12-16 19:15:17 +00:00
}
2006-08-02 08:15:51 +00:00
break ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
case SSL_ID_APP_DATA :
if ( ssl )
2007-03-24 13:21:08 +00:00
decrypt_dtls_record ( tvb , pinfo , offset ,
2009-10-16 21:17:57 +00:00
record_length , content_type , ssl , TRUE ) ;
2007-03-24 13:21:08 +00:00
2013-02-23 01:57:15 +00:00
/* show on info column what we are decoding */
2009-09-24 20:21:23 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " Application Data " ) ;
2007-03-24 13:21:08 +00:00
2015-02-05 18:54:52 +00:00
/* app_handle discovery is done here instead of dissect_dtls_payload()
* because the protocol name needs to be displayed below . */
if ( ! session - > app_handle ) {
/* Unknown protocol handle, ssl_starttls_ack was not called before.
* Try to find an appropriate dissection handle and cache it . */
2015-11-06 04:20:45 +00:00
dissector_handle_t handle ;
handle = dissector_get_uint_handle ( dtls_associations , pinfo - > srcport ) ;
handle = handle ? handle : dissector_get_uint_handle ( dtls_associations , pinfo - > destport ) ;
if ( handle ) session - > app_handle = handle ;
2015-02-05 18:54:52 +00:00
}
2006-08-02 08:15:51 +00:00
proto_item_set_text ( dtls_record_tree ,
2009-10-16 21:17:57 +00:00
" %s Record Layer: %s Protocol: %s " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ,
2012-08-10 22:55:02 +00:00
val_to_str_const ( content_type , ssl_31_content_type , " unknown " ) ,
2015-02-05 18:54:52 +00:00
session - > app_handle
? dissector_handle_get_dissector_name ( session - > app_handle )
: " Application Data " ) ;
2007-03-24 13:21:08 +00:00
/* show decrypted data info, if available */
2011-05-27 03:06:50 +00:00
appl_data = ssl_get_data_info ( proto_dtls , pinfo , tvb_raw_offset ( tvb ) + offset ) ;
2007-01-12 10:25:03 +00:00
if ( appl_data & & ( appl_data - > plain_data . data_len > 0 ) )
2006-08-02 08:15:51 +00:00
{
2009-10-16 21:17:57 +00:00
tvbuff_t * next_tvb ;
2011-12-29 20:23:18 +00:00
gboolean dissected ;
2015-02-05 18:54:52 +00:00
guint16 saved_match_port ;
2009-10-16 21:17:57 +00:00
/* try to dissect decrypted data*/
ssl_debug_printf ( " dissect_dtls_record decrypted len %d \n " ,
appl_data - > plain_data . data_len ) ;
2007-03-24 13:21:08 +00:00
2009-10-16 21:17:57 +00:00
/* create a new TVB structure for desegmented data */
2011-12-29 20:23:18 +00:00
next_tvb = tvb_new_child_real_data ( tvb ,
appl_data - > plain_data . data ,
appl_data - > plain_data . data_len ,
appl_data - > plain_data . data_len ) ;
2007-01-12 10:25:03 +00:00
2009-10-16 21:17:57 +00:00
add_new_data_source ( pinfo , next_tvb , " Decrypted DTLS data " ) ;
2006-08-02 08:15:51 +00:00
2015-02-05 18:54:52 +00:00
saved_match_port = pinfo - > match_uint ;
if ( ssl_packet_from_server ( session , dtls_associations , pinfo ) ) {
pinfo - > match_uint = pinfo - > srcport ;
} else {
pinfo - > match_uint = pinfo - > destport ;
}
2009-10-16 21:17:57 +00:00
/* find out a dissector using server port*/
2015-02-05 18:54:52 +00:00
if ( session - > app_handle ) {
ssl_debug_printf ( " %s: found handle %p (%s) \n " , G_STRFUNC ,
( void * ) session - > app_handle ,
dissector_handle_get_dissector_name ( session - > app_handle ) ) ;
2012-11-16 11:35:01 +00:00
ssl_print_data ( " decrypted app data " , appl_data - > plain_data . data , appl_data - > plain_data . data_len ) ;
2007-03-24 13:21:08 +00:00
2013-06-18 01:13:07 +00:00
if ( have_tap_listener ( exported_pdu_tap ) ) {
2015-06-24 19:21:42 +00:00
export_pdu_packet ( next_tvb , pinfo , EXP_PDU_TAG_PROTO_NAME ,
dissector_handle_get_dissector_name ( session - > app_handle ) ) ;
2013-06-18 01:13:07 +00:00
}
2015-02-05 18:54:52 +00:00
dissected = call_dissector_only ( session - > app_handle , next_tvb , pinfo , top_tree , NULL ) ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
}
else {
/* try heuristic subdissectors */
2014-05-20 10:54:20 +00:00
dissected = dissector_try_heuristic ( heur_subdissector_list , next_tvb , pinfo , top_tree , & hdtbl_entry , NULL ) ;
2015-06-24 19:21:42 +00:00
if ( dissected & & have_tap_listener ( exported_pdu_tap ) ) {
2015-07-15 12:47:39 +00:00
export_pdu_packet ( next_tvb , pinfo , EXP_PDU_TAG_HEUR_PROTO_NAME , hdtbl_entry - > short_name ) ;
2015-06-24 19:21:42 +00:00
}
2009-10-16 21:17:57 +00:00
}
2015-02-05 18:54:52 +00:00
pinfo - > match_uint = saved_match_port ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
if ( dissected )
break ;
2007-03-24 13:21:08 +00:00
}
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
proto_tree_add_item ( dtls_record_tree , hf_dtls_record_appdata , tvb ,
2011-10-05 00:25:09 +00:00
offset , record_length , ENC_NA ) ;
2006-08-02 08:15:51 +00:00
break ;
2012-02-26 13:50:52 +00:00
case SSL_ID_HEARTBEAT :
2014-07-10 09:50:23 +00:00
{
2012-02-26 13:50:52 +00:00
tvbuff_t * decrypted ;
if ( ssl & & decrypt_dtls_record ( tvb , pinfo , offset ,
record_length , content_type , ssl , FALSE ) )
ssl_add_record_info ( proto_dtls , pinfo , dtls_decrypted_data . data ,
2015-09-14 08:28:30 +00:00
dtls_decrypted_data_avail , tvb_raw_offset ( tvb ) + offset ) ;
2012-02-26 13:50:52 +00:00
2013-02-23 01:57:15 +00:00
/* try to retrieve and use decrypted alert record, if any. */
2015-09-14 08:28:30 +00:00
decrypted = ssl_get_record_info ( tvb , proto_dtls , pinfo , tvb_raw_offset ( tvb ) + offset ) ;
2012-02-26 13:50:52 +00:00
if ( decrypted ) {
dissect_dtls_heartbeat ( decrypted , pinfo , dtls_record_tree , 0 ,
2014-07-08 16:34:04 +00:00
session , tvb_reported_length ( decrypted ) , TRUE ) ;
2012-02-26 13:50:52 +00:00
add_new_data_source ( pinfo , decrypted , " Decrypted SSL record " ) ;
} else {
dissect_dtls_heartbeat ( tvb , pinfo , dtls_record_tree , offset ,
2014-05-24 14:51:10 +00:00
session , record_length , FALSE ) ;
2012-02-26 13:50:52 +00:00
}
break ;
2014-07-10 09:50:23 +00:00
}
2006-08-02 08:15:51 +00:00
}
offset + = record_length ; /* skip to end of record */
return offset ;
2006-06-27 13:36:10 +00:00
}
/* dissects the alert message, filling in the tree */
static void
2006-08-02 08:15:51 +00:00
dissect_dtls_alert ( tvbuff_t * tvb , packet_info * pinfo ,
2006-06-27 13:36:10 +00:00
proto_tree * tree , guint32 offset ,
2014-05-24 14:51:10 +00:00
const SslSession * session )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
/* struct {
* AlertLevel level ;
* AlertDescription description ;
* } Alert ;
*/
2011-12-29 20:23:18 +00:00
proto_tree * ti ;
proto_tree * ssl_alert_tree ;
2006-08-02 08:15:51 +00:00
const gchar * level ;
const gchar * desc ;
2011-12-29 20:23:18 +00:00
guint8 byte ;
2013-08-29 14:25:38 +00:00
ti = proto_tree_add_item ( tree , hf_dtls_alert_message , tvb ,
2011-10-05 00:25:09 +00:00
offset , 2 , ENC_NA ) ;
2013-08-29 14:25:38 +00:00
ssl_alert_tree = proto_item_add_subtree ( ti , ett_dtls_alert ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/*
* set the record layer label
*/
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* first lookup the names for the alert level and description */
2011-12-29 20:23:18 +00:00
byte = tvb_get_guint8 ( tvb , offset ) ; /* grab the level byte */
2013-03-29 00:26:23 +00:00
level = try_val_to_str ( byte , ssl_31_alert_level ) ;
2006-06-27 13:36:10 +00:00
2011-12-29 20:23:18 +00:00
byte = tvb_get_guint8 ( tvb , offset + 1 ) ; /* grab the desc byte */
2013-03-29 00:26:23 +00:00
desc = try_val_to_str ( byte , ssl_31_alert_description ) ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* now set the text in the record layer line */
2014-09-30 23:12:26 +00:00
if ( level & & desc )
2006-06-27 13:36:10 +00:00
{
2013-06-12 15:15:26 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO ,
" Alert (Level: %s, Description: %s) " ,
level , desc ) ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
else
2006-06-27 13:36:10 +00:00
{
2009-09-24 20:21:23 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " Encrypted Alert " ) ;
2006-06-27 13:36:10 +00:00
}
2007-03-24 13:21:08 +00:00
2006-08-02 08:15:51 +00:00
if ( tree )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
if ( level & & desc )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
proto_item_set_text ( tree , " %s Record Layer: Alert "
" (Level: %s, Description: %s) " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ,
2009-10-16 21:17:57 +00:00
level , desc ) ;
proto_tree_add_item ( ssl_alert_tree , hf_dtls_alert_message_level ,
2011-10-06 03:35:44 +00:00
tvb , offset + + , 1 , ENC_BIG_ENDIAN ) ;
2009-10-16 21:17:57 +00:00
proto_tree_add_item ( ssl_alert_tree , hf_dtls_alert_message_description ,
2012-02-06 22:14:30 +00:00
tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
else
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
proto_item_set_text ( tree ,
" %s Record Layer: Encrypted Alert " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ) ;
2009-10-16 21:17:57 +00:00
proto_item_set_text ( ssl_alert_tree ,
" Alert Message: Encrypted Alert " ) ;
2006-06-27 13:36:10 +00:00
}
}
}
/* dissects the handshake protocol, filling the tree */
static void
2006-08-02 08:15:51 +00:00
dissect_dtls_handshake ( tvbuff_t * tvb , packet_info * pinfo ,
2006-06-27 13:36:10 +00:00
proto_tree * tree , guint32 offset ,
2014-04-26 08:45:41 +00:00
guint32 record_length , SslSession * session ,
2014-04-26 09:38:40 +00:00
gint is_from_server ,
2006-06-27 13:36:10 +00:00
SslDecryptSession * ssl , guint8 content_type )
{
2006-08-02 08:15:51 +00:00
/* struct {
* HandshakeType msg_type ;
* uint24 length ;
* uint16 message_seq ; //new field
2011-12-29 20:23:18 +00:00
* uint24 fragment_offset ; //new field
* uint24 fragment_length ; //new field
2006-08-02 08:15:51 +00:00
* select ( HandshakeType ) {
* case hello_request : HelloRequest ;
* case client_hello : ClientHello ;
* case server_hello : ServerHello ;
* case hello_verify_request : HelloVerifyRequest ; //new field
* case certificate : Certificate ;
* case server_key_exchange : ServerKeyExchange ;
* case certificate_request : CertificateRequest ;
* case server_hello_done : ServerHelloDone ;
* case certificate_verify : CertificateVerify ;
* case client_key_exchange : ClientKeyExchange ;
* case finished : Finished ;
* } body ;
* } Handshake ;
*/
2011-12-29 20:23:18 +00:00
2013-04-18 19:19:38 +00:00
proto_tree * ti , * length_item = NULL , * fragment_length_item = NULL ;
2011-12-29 20:23:18 +00:00
proto_tree * ssl_hand_tree ;
2006-08-02 08:15:51 +00:00
const gchar * msg_type_str ;
2011-12-29 20:23:18 +00:00
guint8 msg_type ;
guint32 length ;
guint16 message_seq ;
guint32 fragment_offset ;
guint32 fragment_length ;
gboolean first_iteration ;
2013-04-18 19:19:38 +00:00
guint32 reassembled_length ;
2015-10-20 16:41:46 +00:00
tvbuff_t * sub_tvb ;
2011-12-29 20:23:18 +00:00
msg_type_str = NULL ;
first_iteration = TRUE ;
2006-08-02 08:15:51 +00:00
/* just as there can be multiple records per packet, there
* can be multiple messages per record as long as they have
* the same content type
*
* we really only care about this for handshake messages
*/
2007-03-24 13:21:08 +00:00
2006-08-02 08:15:51 +00:00
/* set record_length to the max offset */
record_length + = offset ;
2007-11-05 23:05:20 +00:00
for ( ; offset < record_length ; offset + = fragment_length ,
2009-10-16 21:17:57 +00:00
first_iteration = FALSE ) /* set up for next pass, if any */
2006-08-02 08:15:51 +00:00
{
2013-07-17 21:12:24 +00:00
fragment_head * frag_msg = NULL ;
2011-12-29 20:23:18 +00:00
tvbuff_t * new_tvb = NULL ;
const gchar * frag_str = NULL ;
gboolean fragmented ;
2013-08-29 14:25:38 +00:00
/* add a subtree for the handshake protocol */
ti = proto_tree_add_item ( tree , hf_dtls_handshake_protocol , tvb , offset , - 1 , ENC_NA ) ;
ssl_hand_tree = proto_item_add_subtree ( ti , ett_dtls_handshake ) ;
2013-03-24 18:51:27 +00:00
msg_type = tvb_get_guint8 ( tvb , offset ) ;
2013-08-30 09:18:21 +00:00
fragment_length = tvb_get_ntoh24 ( tvb , offset + 9 ) ;
2013-08-29 20:23:43 +00:00
2013-08-30 09:18:21 +00:00
/* Check the fragment length in the handshake message. Assume it's an
2013-08-29 20:23:43 +00:00
* encrypted handshake message if the message would pass
* the record_length boundary . This is a workaround for the
* situation where the first octet of the encrypted handshake
* message is actually a known handshake message type .
*/
2013-08-30 09:18:21 +00:00
if ( offset + fragment_length < = record_length )
2013-08-29 20:23:43 +00:00
msg_type_str = try_val_to_str ( msg_type , ssl_31_handshake_type ) ;
else
msg_type_str = NULL ;
2007-03-24 13:21:08 +00:00
2006-08-02 08:15:51 +00:00
if ( ! msg_type_str & & ! first_iteration )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
/* only dissect / report messages if they're
* either the first message in this record
* or they ' re a valid message type
*/
return ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
/* on second and later iterations, add comma to info col */
if ( ! first_iteration )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " , " ) ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
/*
* Update our info string
*/
2013-06-12 15:15:26 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , ( msg_type_str ! = NULL )
? msg_type_str : " Encrypted Handshake Message " ) ;
2006-06-27 13:36:10 +00:00
2013-08-29 20:23:43 +00:00
/* if we don't have a valid handshake type, just quit dissecting */
if ( ! msg_type_str )
return ;
2013-08-29 14:25:38 +00:00
proto_tree_add_uint ( ssl_hand_tree , hf_dtls_handshake_type ,
2013-03-24 18:51:27 +00:00
tvb , offset , 1 , msg_type ) ;
offset + + ;
2013-08-30 09:18:21 +00:00
length = tvb_get_ntoh24 ( tvb , offset ) ;
2013-08-29 14:25:38 +00:00
length_item = proto_tree_add_uint ( ssl_hand_tree , hf_dtls_handshake_length ,
2013-04-18 19:19:38 +00:00
tvb , offset , 3 , length ) ;
2013-03-24 18:51:27 +00:00
offset + = 3 ;
message_seq = tvb_get_ntohs ( tvb , offset ) ;
2013-08-29 14:25:38 +00:00
proto_tree_add_uint ( ssl_hand_tree , hf_dtls_handshake_message_seq ,
2013-03-24 18:51:27 +00:00
tvb , offset , 2 , message_seq ) ;
offset + = 2 ;
fragment_offset = tvb_get_ntoh24 ( tvb , offset ) ;
2013-08-29 14:25:38 +00:00
proto_tree_add_uint ( ssl_hand_tree , hf_dtls_handshake_fragment_offset ,
2013-03-24 18:51:27 +00:00
tvb , offset , 3 , fragment_offset ) ;
offset + = 3 ;
2013-08-29 14:25:38 +00:00
fragment_length_item = proto_tree_add_uint ( ssl_hand_tree ,
2013-04-18 19:19:38 +00:00
hf_dtls_handshake_fragment_length ,
tvb , offset , 3 ,
fragment_length ) ;
2013-03-24 18:51:27 +00:00
offset + = 3 ;
proto_item_set_len ( ti , fragment_length + 12 ) ;
2013-04-18 19:19:38 +00:00
fragmented = FALSE ;
if ( fragment_length + fragment_offset > length )
{
if ( fragment_offset = = 0 )
{
2013-06-09 03:28:05 +00:00
expert_add_info ( pinfo , fragment_length_item , & ei_dtls_handshake_fragment_length_too_long ) ;
2013-04-18 19:19:38 +00:00
}
else
{
fragmented = TRUE ;
2013-06-09 03:28:05 +00:00
expert_add_info ( pinfo , fragment_length_item , & ei_dtls_handshake_fragment_past_end_msg ) ;
2013-04-18 19:19:38 +00:00
}
}
2015-07-17 14:31:32 +00:00
else if ( fragment_offset > 0 & & fragment_length = = 0 )
{
/* Fragmented message, but no actual fragment... Note that if a
* fragment was previously completed ( reassembled_length = = length ) ,
* it is already dissected . */
expert_add_info ( pinfo , fragment_length_item , & ei_dtls_handshake_fragment_length_zero ) ;
continue ;
}
2013-04-18 19:19:38 +00:00
else if ( fragment_length < length )
2009-10-16 21:17:57 +00:00
{
2013-04-18 19:19:38 +00:00
fragmented = TRUE ;
2009-10-16 21:17:57 +00:00
2014-07-10 09:50:23 +00:00
/* Handle fragments of known message type, ignore others */
if ( ssl_is_valid_handshake_type ( msg_type , TRUE ) )
2013-04-18 19:19:38 +00:00
{
/* Fragmented handshake message */
pinfo - > fragmented = TRUE ;
2009-10-16 21:17:57 +00:00
2013-04-18 19:19:38 +00:00
/* Don't pass the reassembly code data that doesn't exist */
tvb_ensure_bytes_exist ( tvb , offset , fragment_length ) ;
frag_msg = fragment_add ( & dtls_reassembly_table ,
tvb , offset , pinfo , message_seq , NULL ,
fragment_offset , fragment_length , TRUE ) ;
/*
* Do we already have a length for this reassembly ?
*/
reassembled_length = fragment_get_tot_len ( & dtls_reassembly_table ,
pinfo , message_seq , NULL ) ;
if ( reassembled_length = = 0 )
{
/* No - set it to the length specified by this packet. */
fragment_set_tot_len ( & dtls_reassembly_table ,
pinfo , message_seq , NULL , length ) ;
}
else
{
/* Yes - if this packet specifies a different length,
report an error . */
if ( reassembled_length ! = length )
{
2013-06-09 03:28:05 +00:00
expert_add_info ( pinfo , length_item , & ei_dtls_msg_len_diff_fragment ) ;
2014-09-30 23:12:26 +00:00
}
2013-04-18 19:19:38 +00:00
}
if ( frag_msg & & ( fragment_length + fragment_offset ) = = reassembled_length )
{
/* Reassembled */
new_tvb = process_reassembled_data ( tvb , offset , pinfo ,
" Reassembled DTLS " ,
frag_msg ,
& dtls_frag_items ,
NULL , tree ) ;
frag_str = " (Reassembled) " ;
}
else
{
frag_str = " (Fragment) " ;
}
2013-06-12 15:15:26 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , frag_str ) ;
2013-04-18 19:19:38 +00:00
}
2009-10-16 21:17:57 +00:00
}
2007-11-05 23:05:20 +00:00
2013-04-18 19:19:38 +00:00
if ( tree )
{
2009-10-16 21:17:57 +00:00
/* set the label text on the record layer expanding node */
if ( first_iteration )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
proto_item_set_text ( tree , " %s Record Layer: %s Protocol: %s%s " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ,
2012-08-10 22:55:02 +00:00
val_to_str_const ( content_type , ssl_31_content_type , " unknown " ) ,
2009-10-16 21:17:57 +00:00
( msg_type_str ! = NULL ) ? msg_type_str :
" Encrypted Handshake Message " ,
( frag_str ! = NULL ) ? frag_str : " " ) ;
2006-06-27 13:36:10 +00:00
}
2009-10-16 21:17:57 +00:00
else
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
proto_item_set_text ( tree , " %s Record Layer: %s Protocol: %s%s " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ,
2012-08-10 22:55:02 +00:00
val_to_str_const ( content_type , ssl_31_content_type , " unknown " ) ,
2009-10-16 21:17:57 +00:00
" Multiple Handshake Messages " ,
( frag_str ! = NULL ) ? frag_str : " " ) ;
2006-06-27 13:36:10 +00:00
}
2009-10-16 21:17:57 +00:00
if ( ssl_hand_tree )
2006-06-27 13:36:10 +00:00
{
2009-10-16 21:17:57 +00:00
/* set the text label on the subtree node */
proto_item_set_text ( ssl_hand_tree , " Handshake Protocol: %s%s " ,
( msg_type_str ! = NULL ) ? msg_type_str :
" Encrypted Handshake Message " ,
( frag_str ! = NULL ) ? frag_str : " " ) ;
2006-06-27 13:36:10 +00:00
}
}
2015-10-20 16:41:46 +00:00
if ( fragmented & & ! new_tvb )
2006-06-27 13:36:10 +00:00
{
2015-10-20 16:41:46 +00:00
/* Skip fragmented messages not reassembled yet */
continue ;
}
2009-10-16 21:17:57 +00:00
2015-10-20 16:41:46 +00:00
if ( new_tvb )
{
sub_tvb = new_tvb ;
}
else
{
sub_tvb = tvb_new_subset_length ( tvb , offset , fragment_length ) ;
}
2009-10-16 21:17:57 +00:00
2015-10-20 16:41:46 +00:00
/* now dissect the handshake message, if necessary */
switch ( ( HandshakeType ) msg_type ) {
2009-10-16 21:17:57 +00:00
case SSL_HND_HELLO_REQUEST :
/* hello_request has no fields, so nothing to do! */
break ;
case SSL_HND_CLIENT_HELLO :
2014-07-19 08:54:19 +00:00
if ( ssl ) {
2015-10-20 16:41:46 +00:00
/* ClientHello is first packet so set direction */
ssl_set_server ( session , & pinfo - > dst , pinfo - > ptype , pinfo - > destport ) ;
2014-07-19 08:54:19 +00:00
}
ssl_dissect_hnd_cli_hello ( & dissect_dtls_hf , sub_tvb , pinfo ,
ssl_hand_tree , 0 , length , session , ssl ,
& dtls_hfs ) ;
2009-10-16 21:17:57 +00:00
break ;
2012-06-17 11:30:25 +00:00
case SSL_HND_SERVER_HELLO :
2015-05-25 17:10:59 +00:00
ssl_dissect_hnd_srv_hello ( & dissect_dtls_hf , sub_tvb , pinfo , ssl_hand_tree ,
2015-11-14 11:47:28 +00:00
0 , length , session , ssl , TRUE ) ;
2012-06-17 11:30:25 +00:00
break ;
2009-10-16 21:17:57 +00:00
case SSL_HND_HELLO_VERIFY_REQUEST :
dissect_dtls_hnd_hello_verify_request ( sub_tvb , ssl_hand_tree , 0 , ssl ) ;
break ;
2012-03-08 09:25:13 +00:00
case SSL_HND_NEWSESSION_TICKET :
2014-07-25 11:19:14 +00:00
/* no need to load keylog file here as it only links a previous
* master key with this Session Ticket */
2014-07-13 09:37:08 +00:00
ssl_dissect_hnd_new_ses_ticket ( & dissect_dtls_hf , sub_tvb ,
ssl_hand_tree , 0 , ssl ,
2014-07-19 09:06:25 +00:00
dtls_master_key_map . session ) ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_CERTIFICATE :
2015-10-04 09:22:41 +00:00
ssl_dissect_hnd_cert ( & dissect_dtls_hf , sub_tvb , ssl_hand_tree , 0 ,
pinfo , session , ssl , dtls_key_hash , is_from_server ) ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_SERVER_KEY_EXCHG :
2014-07-11 08:40:47 +00:00
ssl_dissect_hnd_srv_keyex ( & dissect_dtls_hf , sub_tvb , ssl_hand_tree , 0 , length , session ) ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_CERT_REQUEST :
2014-07-10 22:58:35 +00:00
ssl_dissect_hnd_cert_req ( & dissect_dtls_hf , sub_tvb , ssl_hand_tree , 0 , pinfo , session ) ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_SVR_HELLO_DONE :
2015-11-05 10:14:21 +00:00
if ( ssl )
ssl - > state | = SSL_SERVER_HELLO_DONE ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_CERT_VERIFY :
2015-03-12 02:01:37 +00:00
ssl_dissect_hnd_cli_cert_verify ( & dissect_dtls_hf , tvb , ssl_hand_tree , offset , session ) ;
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_CLIENT_KEY_EXCHG :
2014-07-11 08:40:47 +00:00
ssl_dissect_hnd_cli_keyex ( & dissect_dtls_hf , sub_tvb , ssl_hand_tree , 0 , length , session ) ;
2013-12-08 00:58:06 +00:00
if ( ! ssl )
2009-10-16 21:17:57 +00:00
break ;
2014-07-25 11:19:14 +00:00
ssl_load_keyfile ( dtls_options . keylog_filename , & dtls_keylog_file ,
& dtls_master_key_map ) ;
2014-07-11 22:30:12 +00:00
/* try to find master key from pre-master key */
2014-07-19 09:06:25 +00:00
if ( ! ssl_generate_pre_master_secret ( ssl , length , sub_tvb , 0 ,
dtls_options . psk ,
& dtls_master_key_map ) ) {
2013-12-08 00:58:06 +00:00
ssl_debug_printf ( " dissect_dtls_handshake can't generate pre master secret \n " ) ;
}
2009-10-16 21:17:57 +00:00
break ;
case SSL_HND_FINISHED :
2014-07-13 22:04:18 +00:00
ssl_dissect_hnd_finished ( & dissect_dtls_hf , sub_tvb , ssl_hand_tree ,
0 , session , NULL ) ;
2009-10-16 21:17:57 +00:00
break ;
2014-07-10 09:50:23 +00:00
case SSL_HND_CERT_URL :
case SSL_HND_CERT_STATUS :
case SSL_HND_SUPPLEMENTAL_DATA :
case SSL_HND_ENCRYPTED_EXTS :
/* TODO: does this need further dissection? */
break ;
2006-06-27 13:36:10 +00:00
}
}
}
2012-02-26 13:50:52 +00:00
/* dissects the heartbeat message, filling in the tree */
static void
dissect_dtls_heartbeat ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * tree , guint32 offset ,
2014-05-24 14:51:10 +00:00
const SslSession * session , guint32 record_length ,
2014-04-11 11:13:42 +00:00
gboolean decrypted )
2012-02-26 13:50:52 +00:00
{
/* struct {
* HeartbeatMessageType type ;
* uint16 payload_length ;
* opaque payload ;
* opaque padding ;
* } HeartbeatMessage ;
*/
proto_tree * ti ;
proto_tree * dtls_heartbeat_tree ;
const gchar * type ;
guint8 byte ;
guint16 payload_length ;
guint16 padding_length ;
2013-08-29 14:25:38 +00:00
ti = proto_tree_add_item ( tree , hf_dtls_heartbeat_message , tvb ,
2012-02-26 13:50:52 +00:00
offset , record_length - 32 , ENC_NA ) ;
2013-08-29 14:25:38 +00:00
dtls_heartbeat_tree = proto_item_add_subtree ( ti , ett_dtls_heartbeat ) ;
2012-02-26 13:50:52 +00:00
/*
* set the record layer label
*/
/* first lookup the names for the message type and the payload length */
byte = tvb_get_guint8 ( tvb , offset ) ;
2013-03-29 00:26:23 +00:00
type = try_val_to_str ( byte , tls_heartbeat_type ) ;
2012-02-26 13:50:52 +00:00
payload_length = tvb_get_ntohs ( tvb , offset + 1 ) ;
padding_length = record_length - 3 - payload_length ;
/* now set the text in the record layer line */
if ( type & & ( payload_length < = record_length - 16 - 3 ) ) {
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Heartbeat %s " , type ) ;
} else {
col_append_str ( pinfo - > cinfo , COL_INFO , " Encrypted Heartbeat " ) ;
}
if ( tree ) {
2014-04-11 11:13:42 +00:00
if ( type & & ( ( payload_length < = record_length - 16 - 3 ) | | decrypted ) ) {
2012-02-26 13:50:52 +00:00
proto_item_set_text ( tree , " %s Record Layer: Heartbeat "
" %s " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ,
2012-02-26 13:50:52 +00:00
type ) ;
proto_tree_add_item ( dtls_heartbeat_tree , hf_dtls_heartbeat_message_type ,
tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
2014-04-11 11:13:42 +00:00
ti = proto_tree_add_uint ( dtls_heartbeat_tree , hf_dtls_heartbeat_message_payload_length ,
tvb , offset , 2 , payload_length ) ;
2012-02-26 13:50:52 +00:00
offset + = 2 ;
2014-04-11 11:13:42 +00:00
if ( payload_length > record_length - 16 - 3 ) {
expert_add_info_format ( pinfo , ti , & ei_dtls_heartbeat_payload_length ,
" Invalid heartbeat payload length (%d) " , payload_length ) ;
/* Invalid heartbeat payload length, adjust to try decoding */
payload_length = record_length - 16 - 3 ;
padding_length = 16 ;
proto_item_append_text ( ti , " (invalid, using %u to decode payload) " , payload_length ) ;
}
2012-02-26 13:50:52 +00:00
proto_tree_add_bytes_format ( dtls_heartbeat_tree , hf_dtls_heartbeat_message_payload ,
tvb , offset , payload_length ,
NULL , " Payload (%u byte%s) " ,
payload_length ,
plurality ( payload_length , " " , " s " ) ) ;
offset + = payload_length ;
proto_tree_add_bytes_format ( dtls_heartbeat_tree , hf_dtls_heartbeat_message_padding ,
tvb , offset , padding_length ,
NULL , " Padding and HMAC (%u byte%s) " ,
padding_length ,
plurality ( padding_length , " " , " s " ) ) ;
} else {
proto_item_set_text ( tree ,
" %s Record Layer: Encrypted Heartbeat " ,
2015-11-14 11:47:28 +00:00
val_to_str_const ( session - > version , ssl_version_short_names , " DTLS " ) ) ;
2012-02-26 13:50:52 +00:00
proto_item_set_text ( dtls_heartbeat_tree ,
" Encrypted Heartbeat Message " ) ;
}
}
}
2012-06-17 11:30:25 +00:00
static int
dissect_dtls_hnd_hello_verify_request ( tvbuff_t * tvb , proto_tree * tree ,
2013-08-29 14:25:38 +00:00
guint32 offset , SslDecryptSession * ssl _U_ )
2012-06-17 11:30:25 +00:00
{
/*
* struct {
* ProtocolVersion server_version ;
* opaque cookie < 0. .32 > ;
* } HelloVerifyRequest ;
*/
guint8 cookie_length ;
2013-08-29 14:25:38 +00:00
/* show the client version */
2014-07-19 09:12:49 +00:00
proto_tree_add_item ( tree , dissect_dtls_hf . hf . hs_server_version , tvb ,
2013-08-29 14:25:38 +00:00
offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
2012-06-17 11:30:25 +00:00
2013-08-29 14:25:38 +00:00
/* look for a cookie */
cookie_length = tvb_get_guint8 ( tvb , offset ) ;
2012-06-17 11:30:25 +00:00
2014-07-19 08:54:19 +00:00
proto_tree_add_uint ( tree , dtls_hfs . hf_dtls_handshake_cookie_len ,
2013-08-29 14:25:38 +00:00
tvb , offset , 1 , cookie_length ) ;
offset + + ; /* skip opaque length */
2012-06-17 11:30:25 +00:00
2013-08-29 14:25:38 +00:00
if ( cookie_length > 0 )
{
2014-07-19 08:54:19 +00:00
proto_tree_add_bytes_format ( tree , dtls_hfs . hf_dtls_handshake_cookie ,
2013-08-29 14:25:38 +00:00
tvb , offset , cookie_length ,
NULL , " Cookie (%u byte%s) " ,
cookie_length ,
plurality ( cookie_length , " " , " s " ) ) ;
offset + = cookie_length ;
}
2012-06-17 11:30:25 +00:00
2013-08-29 14:25:38 +00:00
return offset ;
2012-06-17 11:30:25 +00:00
}
2006-06-27 13:36:10 +00:00
/*********************************************************************
*
* Support Functions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* this applies a heuristic to determine whether
* or not the data beginning at offset looks like a
2006-08-02 08:15:51 +00:00
* valid dtls record .
2006-06-27 13:36:10 +00:00
*/
2006-08-02 08:15:51 +00:00
static gint
looks_like_dtls ( tvbuff_t * tvb , guint32 offset )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
/* have to have a valid content type followed by a valid
* protocol version
*/
2011-12-29 20:23:18 +00:00
guint8 byte ;
2006-08-02 08:15:51 +00:00
guint16 version ;
2006-06-27 13:36:10 +00:00
2006-08-02 08:15:51 +00:00
/* see if the first byte is a valid content type */
byte = tvb_get_guint8 ( tvb , offset ) ;
if ( ! ssl_is_valid_content_type ( byte ) )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
return 0 ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
/* now check to see if the version byte appears valid */
version = tvb_get_ntohs ( tvb , offset + 1 ) ;
2012-03-28 09:31:04 +00:00
if ( version ! = DTLSV1DOT0_VERSION & & version ! = DTLSV1DOT2_VERSION & &
2015-11-14 12:33:02 +00:00
version ! = DTLSV1DOT0_OPENSSL_VERSION )
2006-06-27 13:36:10 +00:00
{
2006-08-02 08:15:51 +00:00
return 0 ;
2006-06-27 13:36:10 +00:00
}
2006-08-02 08:15:51 +00:00
return 1 ;
2006-06-27 13:36:10 +00:00
}
2011-04-26 21:59:11 +00:00
/* UAT */
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# if defined(HAVE_LIBGNUTLS) && defined(HAVE_LIBGCRYPT)
2011-04-26 21:59:11 +00:00
static void
dtlsdecrypt_free_cb ( void * r )
{
2013-03-16 16:25:41 +00:00
ssldecrypt_assoc_t * h = ( ssldecrypt_assoc_t * ) r ;
2011-04-26 21:59:11 +00:00
2011-12-29 20:23:18 +00:00
g_free ( h - > ipaddr ) ;
g_free ( h - > port ) ;
g_free ( h - > protocol ) ;
g_free ( h - > keyfile ) ;
g_free ( h - > password ) ;
2011-04-26 21:59:11 +00:00
}
2011-04-26 22:56:22 +00:00
# endif
2011-04-26 21:59:11 +00:00
#if 0
static void
dtlsdecrypt_update_cb ( void * r _U_ , const char * * err _U_ )
{
2011-12-29 20:23:18 +00:00
return ;
2011-04-26 21:59:11 +00:00
}
# endif
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# if defined(HAVE_LIBGNUTLS) && defined(HAVE_LIBGCRYPT)
2011-04-26 21:59:11 +00:00
static void *
dtlsdecrypt_copy_cb ( void * dest , const void * orig , size_t len _U_ )
{
2013-03-16 16:25:41 +00:00
const ssldecrypt_assoc_t * o = ( const ssldecrypt_assoc_t * ) orig ;
ssldecrypt_assoc_t * d = ( ssldecrypt_assoc_t * ) dest ;
2011-04-26 21:59:11 +00:00
2011-12-29 20:23:18 +00:00
d - > ipaddr = g_strdup ( o - > ipaddr ) ;
d - > port = g_strdup ( o - > port ) ;
d - > protocol = g_strdup ( o - > protocol ) ;
d - > keyfile = g_strdup ( o - > keyfile ) ;
d - > password = g_strdup ( o - > password ) ;
2011-04-26 21:59:11 +00:00
2011-12-29 20:23:18 +00:00
return d ;
2011-04-26 21:59:11 +00:00
}
UAT_CSTRING_CB_DEF ( sslkeylist_uats , ipaddr , ssldecrypt_assoc_t )
UAT_CSTRING_CB_DEF ( sslkeylist_uats , port , ssldecrypt_assoc_t )
UAT_CSTRING_CB_DEF ( sslkeylist_uats , protocol , ssldecrypt_assoc_t )
2011-09-20 10:15:09 +00:00
UAT_FILENAME_CB_DEF ( sslkeylist_uats , keyfile , ssldecrypt_assoc_t )
2011-04-26 21:59:11 +00:00
UAT_CSTRING_CB_DEF ( sslkeylist_uats , password , ssldecrypt_assoc_t )
2015-11-06 04:20:45 +00:00
static gboolean
dtlsdecrypt_uat_fld_protocol_chk_cb ( void * r _U_ , const char * p , guint len _U_ , const void * u1 _U_ , const void * u2 _U_ , char * * err )
{
if ( ! p | | strlen ( p ) = = 0u ) {
* err = g_strdup_printf ( " No protocol given. " ) ;
return FALSE ;
}
if ( ! find_dissector ( p ) ) {
if ( proto_get_id_by_filter_name ( p ) ! = - 1 ) {
* err = g_strdup_printf ( " While '%s' is a valid dissector filter name, that dissector is not configured "
" to support DTLS decryption. \n \n "
" If you need to decrypt '%s' over DTLS, please contact the Wireshark development team. " , p , p ) ;
} else {
char * ssl_str = ssl_association_info ( " dtls.port " , " UDP " ) ;
* err = g_strdup_printf ( " Could not find dissector for: '%s' \n Commonly used DTLS dissectors include: \n %s " , p , ssl_str ) ;
g_free ( ssl_str ) ;
}
return FALSE ;
}
* err = NULL ;
return TRUE ;
}
2011-04-26 22:56:22 +00:00
# endif
2011-04-26 21:59:11 +00:00
2012-02-10 23:08:46 +00:00
void proto_reg_handoff_dtls ( void ) ;
2006-06-27 13:36:10 +00:00
/*********************************************************************
*
2007-01-02 14:11:35 +00:00
* Standard Wireshark Protocol Registration and housekeeping
2006-06-27 13:36:10 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
proto_register_dtls ( void )
{
2006-08-02 08:15:51 +00:00
/* Setup list of header fields See Section 1.6.1 for details*/
static hf_register_info hf [ ] = {
{ & hf_dtls_record ,
{ " Record Layer " , " dtls.record " ,
2009-10-16 21:17:57 +00:00
FT_NONE , BASE_NONE , NULL , 0x0 ,
2010-09-23 21:46:31 +00:00
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_content_type ,
{ " Content Type " , " dtls.record.content_type " ,
2009-10-16 21:17:57 +00:00
FT_UINT8 , BASE_DEC , VALS ( ssl_31_content_type ) , 0x0 ,
2010-09-23 21:46:31 +00:00
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_version ,
{ " Version " , " dtls.record.version " ,
2009-10-16 21:17:57 +00:00
FT_UINT16 , BASE_HEX , VALS ( ssl_versions ) , 0x0 ,
" Record layer version. " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_epoch ,
{ " Epoch " , " dtls.record.epoch " ,
2009-10-16 21:17:57 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_sequence_number ,
{ " Sequence Number " , " dtls.record.sequence_number " ,
2013-08-29 14:25:38 +00:00
FT_UINT64 , BASE_DEC , NULL , 0x0 ,
2009-10-16 21:17:57 +00:00
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_length ,
{ " Length " , " dtls.record.length " ,
2009-10-16 21:17:57 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Length of DTLS record data " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_record_appdata ,
{ " Encrypted Application Data " , " dtls.app_data " ,
2009-10-16 21:17:57 +00:00
FT_BYTES , BASE_NONE , NULL , 0x0 ,
" Payload is encrypted application data " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_alert_message ,
{ " Alert Message " , " dtls.alert_message " ,
2009-10-16 21:17:57 +00:00
FT_NONE , BASE_NONE , NULL , 0x0 ,
2010-09-24 02:51:40 +00:00
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_alert_message_level ,
{ " Level " , " dtls.alert_message.level " ,
2009-10-16 21:17:57 +00:00
FT_UINT8 , BASE_DEC , VALS ( ssl_31_alert_level ) , 0x0 ,
" Alert message level " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_alert_message_description ,
{ " Description " , " dtls.alert_message.desc " ,
2009-10-16 21:17:57 +00:00
FT_UINT8 , BASE_DEC , VALS ( ssl_31_alert_description ) , 0x0 ,
" Alert message description " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_protocol ,
{ " Handshake Protocol " , " dtls.handshake " ,
2009-10-16 21:17:57 +00:00
FT_NONE , BASE_NONE , NULL , 0x0 ,
" Handshake protocol message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_type ,
{ " Handshake Type " , " dtls.handshake.type " ,
2009-10-16 21:17:57 +00:00
FT_UINT8 , BASE_DEC , VALS ( ssl_31_handshake_type ) , 0x0 ,
" Type of handshake message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_length ,
{ " Length " , " dtls.handshake.length " ,
2009-10-16 21:17:57 +00:00
FT_UINT24 , BASE_DEC , NULL , 0x0 ,
" Length of handshake message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_message_seq ,
{ " Message Sequence " , " dtls.handshake.message_seq " ,
2009-10-16 21:17:57 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Message sequence of handshake message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_fragment_offset ,
{ " Fragment Offset " , " dtls.handshake.fragment_offset " ,
2009-10-16 21:17:57 +00:00
FT_UINT24 , BASE_DEC , NULL , 0x0 ,
" Fragment offset of handshake message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
{ & hf_dtls_handshake_fragment_length ,
{ " Fragment Length " , " dtls.handshake.fragment_length " ,
2009-10-16 21:17:57 +00:00
FT_UINT24 , BASE_DEC , NULL , 0x0 ,
" Fragment length of handshake message " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
2014-07-19 08:54:19 +00:00
{ & dtls_hfs . hf_dtls_handshake_cookie_len ,
2006-08-02 08:15:51 +00:00
{ " Cookie Length " , " dtls.handshake.cookie_length " ,
2009-10-16 21:17:57 +00:00
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Length of the cookie field " , HFILL }
2006-08-02 08:15:51 +00:00
} ,
2014-07-19 08:54:19 +00:00
{ & dtls_hfs . hf_dtls_handshake_cookie ,
2006-08-02 08:15:51 +00:00
{ " Cookie " , " dtls.handshake.cookie " ,
2009-10-16 21:17:57 +00:00
FT_BYTES , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
2006-08-02 08:15:51 +00:00
} ,
2012-02-26 13:50:52 +00:00
{ & hf_dtls_heartbeat_message ,
{ " Heartbeat Message " , " dtls.heartbeat_message " ,
FT_NONE , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_dtls_heartbeat_message_type ,
{ " Type " , " dtls.heartbeat_message.type " ,
FT_UINT8 , BASE_DEC , VALS ( tls_heartbeat_type ) , 0x0 ,
" Heartbeat message type " , HFILL }
} ,
{ & hf_dtls_heartbeat_message_payload_length ,
{ " Payload Length " , " dtls.heartbeat_message.payload_length " ,
FT_UINT16 , BASE_DEC , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_dtls_heartbeat_message_payload ,
{ " Payload Length " , " dtls.heartbeat_message.payload " ,
FT_BYTES , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_dtls_heartbeat_message_padding ,
{ " Payload Length " , " dtls.heartbeat_message.padding " ,
FT_BYTES , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
2007-11-05 23:05:20 +00:00
{ & hf_dtls_fragments ,
{ " Message fragments " , " dtls.fragments " ,
2009-10-16 21:17:57 +00:00
FT_NONE , BASE_NONE , NULL , 0x00 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment ,
{ " Message fragment " , " dtls.fragment " ,
2009-10-16 21:17:57 +00:00
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment_overlap ,
{ " Message fragment overlap " , " dtls.fragment.overlap " ,
2009-10-16 21:17:57 +00:00
FT_BOOLEAN , BASE_NONE , NULL , 0x0 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment_overlap_conflicts ,
{ " Message fragment overlapping with conflicting data " ,
2009-10-16 21:17:57 +00:00
" dtls.fragment.overlap.conflicts " ,
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
FT_BOOLEAN , BASE_NONE , NULL , 0x0 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment_multiple_tails ,
{ " Message has multiple tail fragments " ,
2009-10-16 21:17:57 +00:00
" dtls.fragment.multiple_tails " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment_too_long_fragment ,
{ " Message fragment too long " , " dtls.fragment.too_long_fragment " ,
2009-10-16 21:17:57 +00:00
FT_BOOLEAN , BASE_NONE , NULL , 0x0 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
{ & hf_dtls_fragment_error ,
{ " Message defragmentation error " , " dtls.fragment.error " ,
2009-10-16 21:17:57 +00:00
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
2011-01-30 21:01:07 +00:00
{ & hf_dtls_fragment_count ,
2012-01-19 20:19:28 +00:00
{ " Message fragment count " , " dtls.fragment.count " ,
2011-01-30 21:01:07 +00:00
FT_UINT32 , BASE_DEC , NULL , 0x00 , NULL , HFILL }
} ,
2007-11-05 23:05:20 +00:00
{ & hf_dtls_reassembled_in ,
{ " Reassembled in " , " dtls.reassembled.in " ,
2009-10-16 21:17:57 +00:00
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
2007-11-05 23:05:20 +00:00
} ,
2010-02-02 16:01:52 +00:00
{ & hf_dtls_reassembled_length ,
2010-02-06 18:20:21 +00:00
{ " Reassembled DTLS length " , " dtls.reassembled.length " ,
2010-02-02 16:01:52 +00:00
FT_UINT32 , BASE_DEC , NULL , 0x00 , NULL , HFILL }
} ,
2014-02-25 16:27:32 +00:00
SSL_COMMON_HF_LIST ( dissect_dtls_hf , " dtls " )
2006-08-02 08:15:51 +00:00
} ;
/* Setup protocol subtree array */
static gint * ett [ ] = {
& ett_dtls ,
& ett_dtls_record ,
& ett_dtls_alert ,
& ett_dtls_handshake ,
2012-02-26 13:50:52 +00:00
& ett_dtls_heartbeat ,
2006-08-02 08:15:51 +00:00
& ett_dtls_certs ,
2007-11-05 23:05:20 +00:00
& ett_dtls_fragment ,
& ett_dtls_fragments ,
2013-12-23 20:42:43 +00:00
SSL_COMMON_ETT_LIST ( dissect_dtls_hf )
2006-08-02 08:15:51 +00:00
} ;
2013-06-09 03:28:05 +00:00
static ei_register_info ei [ ] = {
2015-07-17 14:31:32 +00:00
{ & ei_dtls_handshake_fragment_length_zero , { " dtls.handshake.fragment_length.zero " , PI_PROTOCOL , PI_WARN , " Zero-length fragment length for fragmented message " , EXPFILL } } ,
2013-06-09 03:28:05 +00:00
{ & ei_dtls_handshake_fragment_length_too_long , { " dtls.handshake.fragment_length.too_long " , PI_PROTOCOL , PI_ERROR , " Fragment length is larger than message length " , EXPFILL } } ,
{ & ei_dtls_handshake_fragment_past_end_msg , { " dtls.handshake.fragment_past_end_msg " , PI_PROTOCOL , PI_ERROR , " Fragment runs past the end of the message " , EXPFILL } } ,
{ & ei_dtls_msg_len_diff_fragment , { " dtls.msg_len_diff_fragment " , PI_PROTOCOL , PI_ERROR , " Message length differs from value in earlier fragment " , EXPFILL } } ,
2014-04-11 11:13:42 +00:00
{ & ei_dtls_heartbeat_payload_length , { " dtls.heartbeat_message.payload_length.invalid " , PI_MALFORMED , PI_ERROR , " Invalid heartbeat payload length " , EXPFILL } } ,
2013-12-23 20:42:43 +00:00
SSL_COMMON_EI_LIST ( dissect_dtls_hf , " dtls " )
2013-06-09 03:28:05 +00:00
} ;
expert_module_t * expert_dtls ;
2006-08-02 08:15:51 +00:00
/* Register the protocol name and description */
proto_dtls = proto_register_protocol ( " Datagram Transport Layer Security " ,
2009-10-16 21:17:57 +00:00
" DTLS " , " dtls " ) ;
2006-08-02 08:15:51 +00:00
2016-03-13 11:51:45 +00:00
dtls_associations = register_dissector_table ( " dtls.port " , " DTLS UDP Dissector " , proto_dtls , FT_UINT16 , BASE_DEC , DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE ) ;
2015-11-06 04:20:45 +00:00
2006-08-02 08:15:51 +00:00
/* Required function calls to register the header fields and
* subtrees used */
proto_register_field_array ( proto_dtls , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2013-06-09 03:28:05 +00:00
expert_dtls = expert_register_protocol ( proto_dtls ) ;
expert_register_field_array ( expert_dtls , ei , array_length ( ei ) ) ;
2006-08-02 08:15:51 +00:00
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# ifdef HAVE_LIBGCRYPT
2006-08-02 08:15:51 +00:00
{
2012-02-10 23:08:46 +00:00
module_t * dtls_module = prefs_register_protocol ( proto_dtls , proto_reg_handoff_dtls ) ;
2011-04-26 21:59:11 +00:00
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# ifdef HAVE_LIBGNUTLS
2011-12-29 20:23:18 +00:00
static uat_field_t dtlskeylist_uats_flds [ ] = {
UAT_FLD_CSTRING_OTHER ( sslkeylist_uats , ipaddr , " IP address " , ssldecrypt_uat_fld_ip_chk_cb , " IPv4 or IPv6 address " ) ,
UAT_FLD_CSTRING_OTHER ( sslkeylist_uats , port , " Port " , ssldecrypt_uat_fld_port_chk_cb , " Port Number " ) ,
2015-11-06 04:20:45 +00:00
UAT_FLD_CSTRING_OTHER ( sslkeylist_uats , protocol , " Protocol " , dtlsdecrypt_uat_fld_protocol_chk_cb , " Protocol " ) ,
2011-12-29 20:23:18 +00:00
UAT_FLD_FILENAME_OTHER ( sslkeylist_uats , keyfile , " Key File " , ssldecrypt_uat_fld_fileopen_chk_cb , " Path to the keyfile. " ) ,
UAT_FLD_CSTRING_OTHER ( sslkeylist_uats , password , " Password (p12 file) " , ssldecrypt_uat_fld_password_chk_cb , " Password " ) ,
UAT_END_FIELDS
} ;
dtlsdecrypt_uat = uat_new ( " DTLS RSA Keylist " ,
sizeof ( ssldecrypt_assoc_t ) ,
" dtlsdecrypttablefile " , /* filename */
TRUE , /* from_profile */
2014-01-30 17:43:52 +00:00
& dtlskeylist_uats , /* data_ptr */
2011-12-29 20:23:18 +00:00
& ndtlsdecrypt , /* numitems_ptr */
UATs could be put into "categories". The categories were defined only
implicitly by the #define name and string they were defined to; not all
UATs neatly fit into any of the categories, so some of them were put
into categories that weren't obviously correct for them, and one - the
display filter macro UAT - wasn't put into any category at all (which
caused crashes when editing them, as the GUI code that handled UAT
changes from a dialog assumed the category field was non-null).
The category was, in practice, used only to decide, in the
aforementioned GUI code, whether the packet summary pane needed to be
updated or not. It also offered no option of "don't update the packet
summary pane *and* don't redissect anything", which is what would be
appropriate for the display filter macro UAT.
Replace the category with a set of fields indicating what the UAT
affects; we currently offer "dissection", which applies to most UATs
(any UAT in libwireshark presumably affects dissection at a minimum) and
"the set of named fields that exist". Changing any UAT that affects
dissection requires a redissection; changing any UAT that affects the
set of named fields that exist requires a redissection *and* rebuilding
the packet summary pane.
Perhaps we also need "filtering", so that if you change a display filter
macro, we re-filter, in case the display is currently filtered with a
display filter that uses a macro that changed.
svn path=/trunk/; revision=43603
2012-07-08 01:00:46 +00:00
UAT_AFFECTS_DISSECTION , /* affects dissection of packets, but not set of named fields */
2011-12-29 20:23:18 +00:00
" ChK12ProtocolsSection " , /* TODO, need revision - help */
dtlsdecrypt_copy_cb ,
NULL , /* dtlsdecrypt_update_cb? */
dtlsdecrypt_free_cb ,
2012-02-10 23:08:46 +00:00
dtls_parse_uat ,
2011-12-29 20:23:18 +00:00
dtlskeylist_uats_flds ) ;
prefs_register_uat_preference ( dtls_module , " cfg " ,
" RSA keys list " ,
" A table of RSA keys for DTLS decryption " ,
dtlsdecrypt_uat ) ;
ssl-utils: allow gcrypt without GnuTLS, improve structure
Fix distinction between HAVE_LIBGNUTLS and HAVE_LIBGCRYPT. If GnuTLS is
unavailable, then the only missing feature is decryption using an RSA
private key file. Regardless of GnuTLS, allow SSL decryption (e.g. using
a SSL key log file or a PSK configured via preferences).
This change has no functional effect when GnuTLS and gcrypt are both
available (or not). Additionally, decryption is possible if only
libgcrypt is available.
Further changes to make ssl-utils more maintainable and documented:
- Group related functions, add markers and documentation. The following
functions are moved (with no further modifications):
- ssl_data_realloc, ssl_data_copy: related to StringInfo.
- ssl_change_cipher, ssl_create_flow: related to the decryption of a
session.
- ssl_decompress_record: related to Record Decompression.
- ssl_lib_init: moved to an arbitrary place.
- ssl_set_server: moved closer to ssl_packet_from_server.
- ssl_is_valid_content_type, ssl_is_valid_handshake_type: move closer
to dissection code.
- ssl_dissect_hnd_hello_ext_status_request,
ssl_dissect_hnd_hello_ext_status_request_v2,
ssl_dissect_hnd_hello_ext_elliptic_curves,
ssl_dissect_hnd_hello_ext_ec_point_formats: move to TLS extensions.
- Remove unused forward declaration of _gcry_rsa_decrypt.
- ssl-packet-utils.h:
- Remove ssl_equal, ssl_hash. These are only used in
packet-ssl-utils.c.
- ssl_private_key_equal, ssl_private_key_hash,
ssl_common_register_options: inline when decryption is not
possible.
- Remove ws_symbol_export.h, enable SSL debug log when libgcrypt is
compiled in (instead of depending on GnuTLS).
- Move/merge stub code when GnuTLS or libgcrypt are not available:
- ssl_find_cipher: move.
- ssl_cipher_setiv: move.
- ssl_generate_pre_master_secret, ssl_generate_keyring_material: move.
Compile-tested all combinations:
- no GnuTLS, no libgcrypt: CentOS 6.
- no GnuTLS, has libgcrypt: CentOS 6. Passes all decryption tests
except for the ones that need a RSA private key file.
- has GnuTLS, no libgcrypt: Arch Linux.
- has GnuTLS, has libgcrypt: Arch Linux. The decryption tests pass.
(GnuTLS support is useless without gcrypt, but included for completeness.)
Change-Id: I727248937331f8788de8ed78248bb33296206096
Reviewed-on: https://code.wireshark.org/review/11052
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2015-10-15 00:00:47 +00:00
# endif /* HAVE_LIBGNUTLS */
2011-12-29 20:23:18 +00:00
2012-06-13 01:13:12 +00:00
prefs_register_filename_preference ( dtls_module , " debug_file " , " DTLS debug file " ,
" redirect dtls debug to file name; leave empty to disable debug, "
" use \" " SSL_DEBUG_USE_STDERR " \" to redirect output to stderr \n " ,
& dtls_debug_file_name ) ;
2011-04-26 21:59:11 +00:00
2011-12-29 20:23:18 +00:00
prefs_register_string_preference ( dtls_module , " keys_list " , " RSA keys list (deprecated) " ,
" Semicolon-separated list of private RSA keys used for DTLS decryption. "
" Used by versions of Wireshark prior to 1.6 " ,
2012-04-30 19:14:14 +00:00
& dtls_keys_list ) ;
2013-12-06 23:55:08 +00:00
ssl_common_register_options ( dtls_module , & dtls_options ) ;
2006-08-02 08:15:51 +00:00
}
2006-08-26 00:05:26 +00:00
# endif
2006-06-27 13:36:10 +00:00
2015-12-09 04:04:01 +00:00
register_dissector ( " dtls " , dissect_dtls , proto_dtls ) ;
2006-08-25 08:07:26 +00:00
dtls_handle = find_dissector ( " dtls " ) ;
2012-08-15 13:56:59 +00:00
2006-08-02 08:15:51 +00:00
register_init_routine ( dtls_init ) ;
2015-06-28 14:31:18 +00:00
register_cleanup_routine ( dtls_cleanup ) ;
2006-08-02 08:15:51 +00:00
dtls_tap = register_tap ( " dtls " ) ;
ssl_debug_printf ( " proto_register_dtls: registered tap %s:%d \n " ,
2009-10-16 21:17:57 +00:00
" dtls " , dtls_tap ) ;
From Michael Chen via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5863 :
1. Reload framing protocol no longer encapsulates the Reload message, instead
the latter is in its own tree following Reload framing, much like IP, UDP, etc.
2. Similarly, DTLS no longer encapsulates its data payload if the payload can
be dissected. The recognized payload is in its own tree following the DTLS,
much like IP, UDP, etc.
4. DTLS now has its own heuristic table for dissecting its payload, and
reload-framing is added to this DTLS heuristic table.
6. DTLS will try to dissect its payload if the agreed upon cipher is
RSA-NULL-MD5 (0x0001) or RSA-NULL-SHA (0x0002), even when DTLS is not
configured with the client/server private keys.
Still to do: make DTLS a heuristic dissector on top of UDP (item 3 in the bug).
svn path=/trunk/; revision=37110
2011-05-13 02:48:08 +00:00
2016-03-13 11:51:45 +00:00
heur_subdissector_list = register_heur_dissector_list ( " dtls " , proto_dtls ) ;
2006-06-27 13:36:10 +00:00
}
2011-06-01 18:34:41 +00:00
2006-06-27 13:36:10 +00:00
/* If this dissector uses sub-dissector registration add a registration
* routine . This format is required because a script is used to find
* these routines and create the code that calls these routines .
*/
void
proto_reg_handoff_dtls ( void )
{
2012-02-10 23:08:46 +00:00
static gboolean initialized = FALSE ;
2007-03-24 13:21:08 +00:00
2006-08-02 08:15:51 +00:00
/* add now dissector to default ports.*/
2012-02-10 23:08:46 +00:00
dtls_parse_uat ( ) ;
dtls_parse_old_keys ( ) ;
2013-06-18 01:13:07 +00:00
exported_pdu_tap = find_tap_id ( EXPORT_PDU_TAP_NAME_LAYER_7 ) ;
2012-02-10 23:08:46 +00:00
2012-08-15 16:02:01 +00:00
if ( initialized = = FALSE ) {
2015-07-13 00:40:31 +00:00
heur_dissector_add ( " udp " , dissect_dtls_heur , " DTLS over UDP " , " dtls_udp " , proto_dtls , HEURISTIC_ENABLE ) ;
2012-08-15 16:02:01 +00:00
dissector_add_uint ( " sctp.ppi " , DIAMETER_DTLS_PROTOCOL_ID , find_dissector ( " dtls " ) ) ;
}
2011-06-01 18:34:41 +00:00
2012-02-10 23:08:46 +00:00
initialized = TRUE ;
2006-06-27 13:36:10 +00:00
}
2014-09-30 23:12:26 +00:00
2015-11-06 19:55:19 +00:00
void
dtls_dissector_add ( guint port , dissector_handle_t handle )
{
ssl_association_add ( " dtls.port " , dtls_handle , handle , port , FALSE ) ;
}
void
dtls_dissector_delete ( guint port , dissector_handle_t handle )
{
ssl_association_remove ( " dtls.port " , dtls_handle , handle , port , FALSE ) ;
}
2014-09-30 23:12:26 +00:00
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local Variables :
* c - basic - offset : 2
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* ex : set shiftwidth = 2 tabstop = 8 expandtab :
* : indentSize = 2 : tabSize = 8 : noTabs = true :
*/