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):