diff options
-rw-r--r-- | epan/dissectors/packet-dtls.c | 53 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.c | 39 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.h | 3 |
3 files changed, 60 insertions, 35 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c index c357b222e2..60571623e8 100644 --- a/epan/dissectors/packet-dtls.c +++ b/epan/dissectors/packet-dtls.c @@ -169,6 +169,9 @@ static gint dtls_decrypted_data_avail = 0; static ssl_common_options_t dtls_options = { NULL, NULL}; static const gchar *dtls_debug_file_name = NULL; +static guint32 dtls_default_client_cid_length; +static guint32 dtls_default_server_cid_length; + static heur_dissector_list_t heur_subdissector_list; static const fragment_items dtls_frag_items = { @@ -493,6 +496,27 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ return tvb_captured_length(tvb); } +static guint8 dtls_cid_length(SslSession *session, gboolean is_from_server) +{ + guint8 cid_length; + + if (is_from_server) { + if (session && session->client_cid_len_present) { + cid_length = session->client_cid_len; + } else { + cid_length = (guint8)dtls_default_client_cid_length; + } + } else { + if (session && session->server_cid_len_present) { + cid_length = session->server_cid_len; + } else { + cid_length = (guint8)dtls_default_server_cid_length; + } + } + + return cid_length; +} + static gboolean dissect_dtls_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) @@ -511,17 +535,11 @@ dissect_dtls_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat if (record_type == SSL_ID_TLS12_CID) { /* CID length is not embedded in the packet */ SslDecryptSession *ssl_session = ssl_get_session_by_cid(tvb, offset + 11); - if (ssl_session) { - SslSession *session = &ssl_session->session; - gint is_from_server = ssl_packet_from_server(session, dtls_associations, pinfo); - guint8 cid_length = is_from_server ? session->client_cid_len : session->server_cid_len; - offset += tvb_get_ntohs(tvb, offset + cid_length + 11) + 13 + cid_length; - } else { - return FALSE; - } - } else { - offset += tvb_get_ntohs(tvb, offset + 11) + 13; + SslSession *session = ssl_session ? &ssl_session->session : NULL; + gint is_from_server = ssl_packet_from_server(session, dtls_associations, pinfo); + offset += dtls_cid_length(session, is_from_server); } + offset += tvb_get_ntohs(tvb, offset + 11) + 13; if (offset == length) { dissect_dtls(tvb, pinfo, tree, data); return TRUE; @@ -774,11 +792,11 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, tvbuff_t *decrypted; SslRecordInfo *record = NULL; heur_dtbl_entry_t *hdtbl_entry; - guint8 cid[DTLS_MAX_CID_LENGTH]; + guint8 *cid = NULL; guint8 cid_length; /* Connection ID length to use if any */ - cid_length = is_from_server ? session->client_cid_len : session->server_cid_len; + cid_length = dtls_cid_length(session, is_from_server); /* * Get the record layer fields of interest @@ -789,7 +807,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, sequence_number = tvb_get_ntoh48(tvb, offset + 5); if (content_type == SSL_ID_TLS12_CID && cid_length > 0) { - tvb_memcpy(tvb, cid, offset + 11, cid_length); + cid = tvb_memdup(wmem_packet_scope(), tvb, offset + 11, cid_length); record_length = tvb_get_ntohs(tvb, offset + cid_length + 11); dtls_record_length = 13 + cid_length + record_length; } else { @@ -2164,6 +2182,15 @@ proto_register_dtls(void) "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, TRUE); + + prefs_register_uint_preference(dtls_module, "client_cid_length", "Client Connection ID length", + "Default client Connection ID length used when the Client Handshake message is missing", + 10, &dtls_default_client_cid_length); + + prefs_register_uint_preference(dtls_module, "server_cid_length", "Server Connection ID length", + "Default server Connection ID length used when the Server Handshake message is missing", + 10, &dtls_default_server_cid_length); + ssl_common_register_options(dtls_module, &dtls_options, TRUE); } diff --git a/epan/dissectors/packet-tls-utils.c b/epan/dissectors/packet-tls-utils.c index 3cc3a65f1c..aaa5f4854f 100644 --- a/epan/dissectors/packet-tls-utils.c +++ b/epan/dissectors/packet-tls-utils.c @@ -4664,6 +4664,8 @@ tls_decrypt_aead_record(SslDecryptSession *ssl, SslDecoder *decoder, const guint8 draft_version = ssl->session.tls13_draft_version; const guchar *auth_tag_wire; guchar auth_tag_calc[16]; + guchar *aad = NULL; + guint aad_len = 0; #else guchar nonce_with_counter[16] = { 0 }; #endif @@ -4774,10 +4776,9 @@ tls_decrypt_aead_record(SslDecryptSession *ssl, SslDecoder *decoder, /* (D)TLS 1.2 needs specific AAD, TLS 1.3 (before -25) uses empty AAD. */ if (is_cid) { /* if connection ID */ - guchar aad[23+DTLS_MAX_CID_LENGTH]; - guint aad_len; if (ssl->session.deprecated_cid) { - aad_len = 13 + 1 + cidl; + aad_len = 14 + cidl; + aad = wmem_alloc(wmem_packet_scope(), aad_len); phton64(aad, decoder->seq); /* record sequence number */ phton16(aad, decoder->epoch); /* DTLS 1.2 includes epoch. */ aad[8] = ct; /* TLSCompressed.type */ @@ -4786,7 +4787,8 @@ tls_decrypt_aead_record(SslDecryptSession *ssl, SslDecoder *decoder, aad[11 + cidl] = cidl; /* cid_length */ phton16(aad + 12 + cidl, ciphertext_len); /* TLSCompressed.length */ } else { - aad_len = 13 + 8 + 1 + 1 + cidl; + aad_len = 23 + cidl; + aad = wmem_alloc(wmem_packet_scope(), aad_len); memset(aad, 0xFF, 8); /* seq_num_placeholder */ aad[8] = ct; /* TLSCompressed.type */ aad[9] = cidl; /* cid_length */ @@ -4797,14 +4799,9 @@ tls_decrypt_aead_record(SslDecryptSession *ssl, SslDecoder *decoder, memcpy(aad + 21, cid, cidl); /* cid */ phton16(aad + 21 + cidl, ciphertext_len); /* TLSCompressed.length */ } - ssl_print_data("AAD", aad, aad_len); - err = gcry_cipher_authenticate(decoder->evp, aad, aad_len); - if (err) { - ssl_debug_printf("%s failed to set AAD: %s\n", G_STRFUNC, gcry_strerror(err)); - return FALSE; - } } else if (is_v12) { - guchar aad[13]; + aad_len = 13; + aad = wmem_alloc(wmem_packet_scope(), aad_len); phton64(aad, decoder->seq); /* record sequence number */ if (version == DTLSV1DOT2_VERSION) { phton16(aad, decoder->epoch); /* DTLS 1.2 includes epoch. */ @@ -4812,19 +4809,17 @@ tls_decrypt_aead_record(SslDecryptSession *ssl, SslDecoder *decoder, aad[8] = ct; /* TLSCompressed.type */ phton16(aad + 9, record_version); /* TLSCompressed.version */ phton16(aad + 11, ciphertext_len); /* TLSCompressed.length */ - ssl_print_data("AAD", aad, sizeof(aad)); - err = gcry_cipher_authenticate(decoder->evp, aad, sizeof(aad)); - if (err) { - ssl_debug_printf("%s failed to set AAD: %s\n", G_STRFUNC, gcry_strerror(err)); - return FALSE; - } } else if (draft_version >= 25 || draft_version == 0) { - guchar aad[5]; + aad_len = 5; + aad = wmem_alloc(wmem_packet_scope(), aad_len); aad[0] = ct; /* TLSCiphertext.opaque_type (23) */ phton16(aad + 1, record_version); /* TLSCiphertext.legacy_record_version (0x0303) */ phton16(aad + 3, inl); /* TLSCiphertext.length */ - ssl_print_data("AAD", aad, sizeof(aad)); - err = gcry_cipher_authenticate(decoder->evp, aad, sizeof(aad)); + } + + if (aad && aad_len > 0) { + ssl_print_data("AAD", aad, aad_len); + err = gcry_cipher_authenticate(decoder->evp, aad, aad_len); if (err) { ssl_debug_printf("%s failed to set AAD: %s\n", G_STRFUNC, gcry_strerror(err)); return FALSE; @@ -5433,7 +5428,7 @@ int ssl_packet_from_server(SslSession *session, dissector_table_t table, packet_info *pinfo) { gint ret; - if (session->srv_addr.type != AT_NONE) { + if (session && session->srv_addr.type != AT_NONE) { ret = (session->srv_ptype == pinfo->ptype) && (session->srv_port == pinfo->srcport) && addresses_equal(&session->srv_addr, &pinfo->src); @@ -8498,9 +8493,11 @@ ssl_dissect_hnd_hello_ext_connection_id(ssl_common_dissect_t *hf, tvbuff_t *tvb, switch (hnd_type) { case SSL_HND_CLIENT_HELLO: + session->client_cid_len_present = TRUE; return ssl_dissect_ext_connection_id(hf, tvb, pinfo, tree, offset, ssl, cidl, &session->client_cid, &session->client_cid_len); case SSL_HND_SERVER_HELLO: + session->server_cid_len_present = TRUE; return ssl_dissect_ext_connection_id(hf, tvb, pinfo, tree, offset, ssl, cidl, &session->server_cid, &session->server_cid_len); default: diff --git a/epan/dissectors/packet-tls-utils.h b/epan/dissectors/packet-tls-utils.h index a0b3ab6a8b..f6b36acb16 100644 --- a/epan/dissectors/packet-tls-utils.h +++ b/epan/dissectors/packet-tls-utils.h @@ -474,12 +474,13 @@ typedef struct _SslSession { opaque cid<0..2^8-1>; } ConnectionId; */ -#define DTLS_MAX_CID_LENGTH 256 guint8 *client_cid; guint8 *server_cid; guint8 client_cid_len; + gboolean client_cid_len_present; guint8 server_cid_len; + gboolean server_cid_len_present; gboolean deprecated_cid; /* Set when handshake is using the deprecated CID extention type */ } SslSession; |