Wireshark-dev: Re: [Wireshark-dev] [DTLS patch]
From: "authesserre samuel" <sauthess@xxxxxxxxx>
Date: Thu, 6 Jul 2006 17:30:48 +0200
Hi, Sorry for this mistake (first empty mail) I have done the same corrections on DTLS dissector that you have done on SSL one.... I have done more (because the dissector wasn't finished at all ;) ) : - make code cleaner (removed SSL and pct code that was unuseful, add comments, indentation corrections....) - integration process details : make code cleaner : In my first patch I had just made adaptation without taking care about dead code so I have corrected this now I have added a description in the start of the plugin that explain (I wish ;) ) that plugin follow the only actual implementation of DTLS It is smaller and easier to understand... integration process : I have moved identical code in the two dissectors in a file named packet-ssl-dtls-common.h, I haven't touch packet-ssl or packet-ssl-utils before your agreement...(I think others things in packet-ssl could be moved but I make things in order....) Actually code is ready to integration and dtls dissector works with the code in packet-ssl-dtls-common.h. With your aggreement I will integrate this code in packet-ssl-utils and modify ssl dissector to use this functions (just code moving and functions names move, no algorithm modification to limit problems) I have for exemple unified parse of preference parameter (who is strictly the same) and others.... enclosed the only file that could be sent on this mailing list (< 40 ko) that allows you to understand what I am saying (about ssl interaction) Are you agree with this modifications? Can I start modifications on ssl one ? (I will not start if it isn't accepted ....) where can I send my patch without problem (it is bigger than 40 ko) ? thanks, regards, On 7/6/06, authesserre samuel <sauthess@xxxxxxxxx> wrote:
Hi, -- Authesserre Samuel 12 rue de la défense passive 14000 CAEN FRANCE 06-27-28-13-32 sauthess@xxxxxxxxx
-- Authesserre Samuel 12 rue de la défense passive 14000 CAEN FRANCE 06-27-28-13-32 sauthess@xxxxxxxxx
/* packet-ssl-dtls-common.c * Common part bitween SSL and DTLS dissectors * Copyright (c) 2006, Authesserre Samuel <sauthess@xxxxxxxxx> * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxxxxx> * 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 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * This fonction are prepared to integration in packet-ssl-utils file, * thay do the same job but allow use of them in TLS and DTLS dissections * */ #ifndef __SSL_DTLS_COMMON_H_ #define __SSL_DTLS_COMMON_H_ typedef struct { unsigned int ssl_port; dissector_handle_t handle; char* info; } SslAssociation; typedef struct _SslService { address addr; guint port; } SslService; /* Hash Functions for TLS/DTLS sessions table and private keys table*/ static gint ssl_equal (gconstpointer v, gconstpointer v2) { const StringInfo *val1 = (const StringInfo *)v; const StringInfo *val2 = (const StringInfo *)v2; if (val1->data_len == val2->data_len && !memcmp(val1->data, val2->data, val2->data_len)) { return 1; } return 0; } static guint ssl_hash (gconstpointer v) { guint l,hash = 0; StringInfo* id = (StringInfo*) v; guint* cur = (guint*) id->data; for (l=4; (l<id->data_len); l+=4, cur++) hash = hash ^ (*cur); return hash; } static gint ssl_private_key_equal (gconstpointer v, gconstpointer v2) { const SslService *val1 = (const SslService *)v; const SslService *val2 = (const SslService *)v2; if ((val1->port == val2->port) && ! CMP_ADDRESS(&val1->addr, &val2->addr)) { return 1; } return 0; } static guint ssl_private_key_hash (gconstpointer v) { const SslService *key = (const SslService *)v; guint l,hash = key->port, len = key->addr.len; guint* cur = (guint*) key->addr.data; for (l=4; (l<len); l+=4, cur++) hash = hash ^ (*cur); return hash; } /* private key table entries have a scope 'larger' then packet capture, * so we can't relay on se_alloc** function */ static void ssl_private_key_free(gpointer id, gpointer key, gpointer dummy _U_) { g_free(id); ssl_free_key((SSL_PRIVATE_KEY*) key); } /* handling of association between tls/dtls ports and clear text protocol */ static void ssl_association_add(GTree* associations, dissector_handle_t handle, unsigned int port, char *protocol, gboolean tcp) { SslAssociation* assoc = g_malloc(sizeof(SslAssociation)); assoc->info=g_malloc(strlen(protocol)+1); strcpy(assoc->info, protocol); assoc->ssl_port = port; assoc->handle = find_dissector(protocol); ssl_debug_printf("association_add port %d protocol %s handle %p\n", port, protocol, assoc->handle); if(!assoc->handle){ fprintf(stderr, "association_add() could not find handle for protocol:%s\n",protocol); } else { if(tcp) dissector_add("tcp.port", port, handle); else dissector_add("udp.port", port, handle); g_tree_insert(associations, (gpointer)port, assoc); } } static gint ssl_association_cmp(gconstpointer a, gconstpointer b) { return (gint)a-(gint)b; } static inline SslAssociation* ssl_association_find(GTree * associations, unsigned int port) { register SslAssociation* ret = g_tree_lookup(associations, (gpointer)port); ssl_debug_printf("association_find: port %d found %p\n", port, ret); return ret; } static gint ssl_association_remove_handle_tcp (gpointer key _U_, gpointer data, gpointer user_data _U_) { SslAssociation* assoc = (SslAssociation*) data; ssl_debug_printf("association_remove_handle removing ptr %p handle %p\n", data, assoc->handle); if (assoc->handle) dissector_delete("tcp.port", assoc->ssl_port, assoc->handle); g_free(data); return 0; } static gint ssl_association_remove_handle_udp (gpointer key _U_, gpointer data, gpointer user_data _U_) { SslAssociation* assoc = (SslAssociation*) data; ssl_debug_printf("association_remove_handle removing ptr %p handle %p\n", data, assoc->handle); if (assoc->handle) dissector_delete("tcp.port", assoc->ssl_port, assoc->handle); g_free(data); return 0; } static inline int ssl_packet_from_server(GTree* associations, unsigned int port) { register int ret = ssl_association_find(associations, port) != 0; ssl_debug_printf("packet_from_server: is from server %d\n", ret); return ret; } /* add to packet data a newly allocated tvb with the specified real data*/ static void ssl_add_record_info(int proto, packet_info *pinfo, unsigned char* data, int data_len, int record_id) { unsigned char* real_data = se_alloc(data_len); SslRecordInfo* rec = se_alloc(sizeof(SslRecordInfo)); SslPacketInfo* pi = p_get_proto_data(pinfo->fd, proto); if (!pi) { pi = se_alloc0(sizeof(SslPacketInfo)); p_add_proto_data(pinfo->fd, proto,pi); } rec->id = record_id; rec->tvb = tvb_new_real_data(real_data, data_len, data_len); memcpy(real_data, data, data_len); /* head insertion */ rec->next= pi->handshake_data; pi->handshake_data = rec; } /* search in packet data the tvbuff associated to the specified id */ static tvbuff_t* ssl_get_record_info(int proto, packet_info *pinfo, int record_id) { SslRecordInfo* rec; SslPacketInfo* pi = p_get_proto_data(pinfo->fd, proto); if (!pi) return NULL; for (rec = pi->handshake_data; rec; rec = rec->next) if (rec->id == record_id) return rec->tvb; return NULL; } /* initialize/reset per capture state data (ssl sessions cache) */ static void ssl_common_init(GHashTable *session_hash , StringInfo * decrypted_data) { if (session_hash) g_hash_table_destroy(session_hash); session_hash = g_hash_table_new(ssl_hash, ssl_equal); if (decrypted_data->data) g_free(decrypted_data->data); decrypted_data->data = g_malloc0(32); decrypted_data->data_len = 32; } /* parse ssl related preferences (private keys and ports association strings) */ static void ssl_parse_key_list(const char * keys_list, GHashTable *key_hash, GTree* associations, dissector_handle_t handle, gboolean tcp) { char* end; char* start = strdup(keys_list); char* tmp = start; ssl_debug_printf("ssl_init keys string %s\n", start); do { char* addr, *port, *protocol, *filename; addr = start; /* split ip/file couple with ';' separator*/ end = strchr(start, ';'); if (end) { *end = 0; start = end+1; } unsigned char* ip; SslService* service; SSL_PRIVATE_KEY * private_key; FILE* fp; /* for each entry split ip, port, protocol, filename with ',' separator */ ssl_debug_printf("ssl_init found host entry %s\n", addr); port = strchr(addr, ','); if (!port) { ssl_debug_printf("ssl_init entry malformed can't find port in %s\n", addr); break; } *port = 0; port++; protocol = strchr(port,','); if (!protocol) { ssl_debug_printf("ssl_init entry malformed can't find protocol in %s\n", port); break; } *protocol=0; protocol++; filename = strchr(protocol,','); if (!filename) { ssl_debug_printf("ssl_init entry malformed can't find filename in %s\n", port); break; } *filename=0; filename++; /* convert ip and port string to network rappresentation*/ service = g_malloc(sizeof(SslService) + 4); service->addr.type = AT_IPv4; service->addr.len = 4; service->addr.data = ip = ((unsigned char*)service) + sizeof(SslService); sscanf(addr, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]); service->port = atoi(port); ssl_debug_printf("ssl_init addr %hhu.%hhu.%hhu.%hhu port %d filename %s\n", ip[0], ip[1], ip[2], ip[3], service->port, filename); /* try to load pen file*/ fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "can't open file %s \n",filename); break; } private_key = ssl_load_key(fp); if (!private_key) { fprintf(stderr,"can't load private key from %s\n", filename); break; } fclose(fp); ssl_debug_printf("ssl_init private key file %s successfully loaded\n", filename); g_hash_table_insert(key_hash, service, private_key); ssl_association_add(associations, handle, atoi(port), protocol, tcp); } while (end != NULL); free(tmp); } /* store master secret into session data cache */ static void ssl_save_session(SslDecryptSession* ssl, GHashTable *session_hash) { /* allocate stringinfo chunks for session id and master secret data*/ StringInfo* session_id = se_alloc0(sizeof(StringInfo) + ssl->session_id.data_len); StringInfo* master_secret = se_alloc0(48 + sizeof(StringInfo)); master_secret->data = ((unsigned char*)master_secret+sizeof(StringInfo)); session_id->data = ((unsigned char*)session_id+sizeof(StringInfo)); ssl_data_set(session_id, ssl->session_id.data, ssl->session_id.data_len); ssl_data_set(master_secret, ssl->master_secret.data, ssl->master_secret.data_len); g_hash_table_insert(session_hash, session_id, master_secret); ssl_print_string("ssl_save_session stored session id", session_id); ssl_print_string("ssl_save_session stored master secret", master_secret); } static void ssl_restore_session(SslDecryptSession* ssl, GHashTable *session_hash) { StringInfo* ms = g_hash_table_lookup(session_hash, &ssl->session_id); if (!ms) { ssl_debug_printf("ssl_restore_session can't find stored session\n"); return; } ssl_data_set(&ssl->master_secret, ms->data, ms->data_len); ssl->state |= SSL_MASTER_SECRET; ssl_debug_printf("ssl_restore_session master key retrived\n"); } static int ssl_is_valid_content_type(guint8 type) { if (type >= 0x14 && type <= 0x17) { return 1; } return 0; } #endif
- Follow-Ups:
- Re: [Wireshark-dev] [DTLS patch]
- From: authesserre samuel
- Re: [Wireshark-dev] [DTLS patch]
- References:
- [Wireshark-dev] [DTLS patch]
- From: authesserre samuel
- [Wireshark-dev] [DTLS patch]
- Prev by Date: Re: [Wireshark-dev] Preliminary Interest Gauging: Usability Reviewof Wireshark
- Next by Date: [Wireshark-dev] [PATCH] Lua plugin build fixes
- Previous by thread: [Wireshark-dev] [DTLS patch]
- Next by thread: Re: [Wireshark-dev] [DTLS patch]
- Index(es):