/* packet-wtls.c * * Routines to dissect WTLS component of WAP traffic. * * $Id: packet-wtls.c,v 1.24 2004/02/28 22:56:36 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * WAP dissector based on original work by Ben Fowler * Updated by Neil Hunter * WTLS support by Alexandre P. Ferreira (Splice IP) * * 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. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #ifdef NEED_SNPRINTF_H # include "snprintf.h" #endif #include #include #include #include "packet-wap.h" #include "packet-wtls.h" /* File scoped variables for the protocol and registered fields */ static int proto_wtls = HF_EMPTY; /* These fields used by fixed part of header */ static int hf_wtls_record = HF_EMPTY; static int hf_wtls_record_type = HF_EMPTY; static int hf_wtls_record_length = HF_EMPTY; static int hf_wtls_record_sequence = HF_EMPTY; static int hf_wtls_record_ciphered = HF_EMPTY; static int hf_wtls_hands = HF_EMPTY; static int hf_wtls_hands_type = HF_EMPTY; static int hf_wtls_hands_length = HF_EMPTY; static int hf_wtls_hands_cli_hello = HF_EMPTY; static int hf_wtls_hands_cli_hello_version = HF_EMPTY; static int hf_wtls_hands_cli_hello_gmt = HF_EMPTY; static int hf_wtls_hands_cli_hello_random = HF_EMPTY; static int hf_wtls_hands_cli_hello_session = HF_EMPTY; static int hf_wtls_hands_cli_hello_session_str = HF_EMPTY; static int hf_wtls_hands_cli_hello_cli_key_id = HF_EMPTY; static int hf_wtls_hands_cli_hello_cli_key_len = HF_EMPTY; static int hf_wtls_hands_cli_hello_trust_key_id = HF_EMPTY; static int hf_wtls_hands_cli_hello_key_exchange =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_exchange_suite =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_parameter_index =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_parameter_set =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_identifier_type =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_identifier_charset =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_identifier_size =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_identifier =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_identifier_str =HF_EMPTY; static int hf_wtls_hands_cli_hello_cipher_suite =HF_EMPTY; static int hf_wtls_hands_cli_hello_cipher_suite_item =HF_EMPTY; static int hf_wtls_hands_cli_hello_compression_methods =HF_EMPTY; static int hf_wtls_hands_cli_hello_compression =HF_EMPTY; static int hf_wtls_hands_cli_hello_sequence_mode =HF_EMPTY; static int hf_wtls_hands_cli_hello_key_refresh =HF_EMPTY; static int hf_wtls_hands_serv_hello = HF_EMPTY; static int hf_wtls_hands_serv_hello_version = HF_EMPTY; static int hf_wtls_hands_serv_hello_gmt = HF_EMPTY; static int hf_wtls_hands_serv_hello_random = HF_EMPTY; static int hf_wtls_hands_serv_hello_session = HF_EMPTY; static int hf_wtls_hands_serv_hello_session_str = HF_EMPTY; static int hf_wtls_hands_serv_hello_cli_key_id =HF_EMPTY; static int hf_wtls_hands_serv_hello_cipher_suite_item =HF_EMPTY; static int hf_wtls_hands_serv_hello_cipher_bulk =HF_EMPTY; static int hf_wtls_hands_serv_hello_cipher_mac =HF_EMPTY; static int hf_wtls_hands_serv_hello_compression =HF_EMPTY; static int hf_wtls_hands_serv_hello_sequence_mode =HF_EMPTY; static int hf_wtls_hands_serv_hello_key_refresh =HF_EMPTY; static int hf_wtls_hands_certificates =HF_EMPTY; static int hf_wtls_hands_certificate =HF_EMPTY; static int hf_wtls_hands_certificate_type =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_version =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_signature_type =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_issuer_type =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_issuer_charset =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_issuer_size =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_issuer_name =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_valid_not_before =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_valid_not_after =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_subject_type =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_subject_charset =HF_EMPTY; static int hf_wtls_hands_certificate_wtls_subject_size = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_subject_name = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_public_key_type = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_key_parameter_index = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_key_parameter_set = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_rsa_exponent = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_rsa_modules = HF_EMPTY; static int hf_wtls_hands_certificate_wtls_signature = HF_EMPTY; static int hf_wtls_alert = HF_EMPTY; static int hf_wtls_alert_level = HF_EMPTY; static int hf_wtls_alert_description = HF_EMPTY; /* Initialize the subtree pointers */ static gint ett_wtls = ETT_EMPTY; static gint ett_wtls_rec = ETT_EMPTY; static gint ett_wtls_msg_type = ETT_EMPTY; static gint ett_wtls_msg_type_item = ETT_EMPTY; static gint ett_wtls_msg_type_item_sub = ETT_EMPTY; static gint ett_wtls_msg_type_item_sub_sub = ETT_EMPTY; static const value_string wtls_vals_record_type[] = { { 1, "change_cipher_data" }, { 2, "alert" }, { 3, "handshake" }, { 4, "application_data" }, { 0, NULL } }; static const value_string wtls_vals_cipher_bulk[] = { { 0, "Null" }, { 1, "RC5 CBC 40" }, { 2, "RC5 CBC 56" }, { 3, "RC5 CBC" }, { 4, "DES CBC 40" }, { 5, "DES CBC" }, { 6, "3DES CBC cwEDE40" }, { 7, "IDEA CBC 40" }, { 8, "IDEA CBC 56" }, { 9, "IDEA CBC" }, { 0, NULL } }; static const value_string wtls_vals_cipher_mac[] = { { 0, "SHA 0" }, { 1, "SHA 40 " }, { 2, "SHA 80" }, { 3, "SHA" }, { 4, "SHA XOR 40" }, { 5, "MD5 40" }, { 6, "MD5 80" }, { 7, "MD5" }, { 0, NULL } }; static const value_string wtls_vals_handshake_type[] = { { 0, "Hello Request" }, { 1, "Client Hello" }, { 2, "Server Hello" }, { 11, "Certificate" }, { 12, "Server Key Exchange" }, { 13, "Certificate Request" }, { 14, "Server Hello Done" }, { 15, "Certificate Verify" }, { 16, "Client Key Exchange" }, { 20, "Finished" }, { 0x00, NULL } }; static const value_string wtls_vals_key_exchange_suite[] = { { 0, "NULL" }, { 1, "Shared Secret" }, { 2, "Diffie Hellman Anonymous" }, { 3, "Diffie Hellman Anonymous 512" }, { 4, "Diffie Hellman Anonymous 768" }, { 5, "RSA Anonymous" }, { 6, "RSA Anonymous 512" }, { 7, "RSA Anonymous 768" }, { 8, "RSA" }, { 9, "RSA 512" }, { 10, "RSA 768" }, { 11, "EC Diffie Hellman Anonymous" }, { 12, "EC Diffie Hellman Anonymous 113" }, { 13, "EC Diffie Hellman Anonymous 131" }, { 14, "EC Diffie Hellman ECDSA" }, { 15, "EC Diffie Hellman Anonymous Uncomp" }, { 16, "EC Diffie Hellman Anonymous Uncomp 113" }, { 17, "EC Diffie Hellman Anonymous Uncomp 131" }, { 18, "EC Diffie Hellman ECDSA Uncomp" }, { 0x00, NULL } }; static const value_string wtls_vals_identifier_type[] = { { 0, "No identifier" }, { 1, "Textual Name" }, { 2, "Binary Name" }, { 254, "SHA-1 Hash of Public Key" }, { 255, "x509 Distinguished Name" }, { 0x00, NULL } }; static const value_string wtls_vals_certificate_type[] = { { 1, "WTLS" }, { 2, "X.509" }, { 3, "X.968" }, { 4, "URL" }, { 0x00, NULL } }; static const value_string wtls_vals_compression[] = { { 0, "Null" }, { 0x00, NULL } }; static const value_string wtls_vals_sequence_mode[] = { { 0, "Off" }, { 1, "Implicit" }, { 2, "Explicit" }, { 0x00, NULL } }; static const value_string wtls_vals_certificate_signature[] = { { 0, "Anonymous" }, { 1, "ECDSA_SHA" }, { 2, "RSA_SHA" }, { 0x00, NULL } }; static const value_string wtls_vals_public_key_type[] = { { 2, "RSA" }, { 3, "ECDH" }, { 4, "ECSA" }, { 0x00, NULL } }; static const value_string wtls_vals_alert_level[] = { { 1, "Warning" }, { 2, "Critical" }, { 3, "Fatal" }, { 0x00, NULL } }; static const value_string wtls_vals_alert_description[] = { { 0,"connection_close_notify"}, { 1,"session_close_notify"}, { 5,"no_connection"}, { 10,"unexpected_message"}, { 11,"time_required"}, { 20,"bad_record_mac"}, { 21,"decryption_failed"}, { 22,"record_overflow"}, { 30,"decompression_failure"}, { 40,"handshake_failure"}, { 42,"bad_certificate"}, { 43,"unsupported_certificate"}, { 44,"certificate_revoked"}, { 45,"certificate_expired"}, { 46,"certificate_unknown"}, { 47,"illegal_parameter"}, { 48,"unknown_ca"}, { 49,"access_denied"}, { 50,"decode_error"}, { 51,"decrypt_error"}, { 52,"unknown_key_id"}, { 53,"disabled_key_id"}, { 54,"key_exchange_disabled"}, { 55,"session_not_ready"}, { 56,"unknown_parameter_index"}, { 57,"duplicate_finished_received"}, { 60,"export_restriction"}, { 70,"protocol_version"}, { 71,"insufficient_security"}, { 80,"internal_error"}, { 90,"user_canceled"}, { 100,"no_renegotiation"}, { 0x00, NULL } }; #define WTLS_RECORD_TYPE_LENGTH 0x80 #define WTLS_RECORD_TYPE_SEQUENCE 0x40 #define WTLS_RECORD_TYPE_CIPHER_CUR 0x20 #define WTLS_RECORD_CONTENT_TYPE 0x0f #define WTLS_ALERT 0x02 #define WTLS_PLAIN_HANDSHAKE 0x03 #define WTLS_HANDSHAKE_CLIENT_HELLO 1 #define WTLS_HANDSHAKE_SERVER_HELLO 2 #define WTLS_HANDSHAKE_CERTIFICATE 11 #define CERTIFICATE_WTLS 1 #define CERTIFICATE_X509 2 #define CERTIFICATE_X968 3 #define CERTIFICATE_URL 4 #define IDENTIFIER_NULL 0 #define IDENTIFIER_TEXT 1 #define IDENTIFIER_BIN 2 #define IDENTIFIER_SHA_1 254 #define IDENTIFIER_X509 255 #define PUBLIC_KEY_RSA 2 #define PUBLIC_KEY_ECDH 3 #define PUBLIC_KEY_ECDSA 4 static void dissect_wtls_handshake (proto_tree *, tvbuff_t *, guint, guint); /* Code to actually dissect the packets */ static void dissect_wtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; char pdut; char pdu_msg_type; guint count = 0; guint offset_wtls = 0; /* Set up structures we will need to add the protocol subtree and manage it */ proto_item *ti; proto_tree *wtls_tree; proto_tree *wtls_rec_tree; proto_tree *wtls_msg_type_tree; if (check_col(pinfo->cinfo, COL_PROTOCOL)) { switch ( pinfo->match_port ) { case UDP_PORT_WTLS_WSP: col_set_str(pinfo->cinfo, COL_PROTOCOL, "WTLS+WSP" ); break; case UDP_PORT_WTLS_WTP_WSP: col_set_str(pinfo->cinfo, COL_PROTOCOL, "WTLS+WTP+WSP" ); break; } } /* Develop the string to put in the Info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_set_str(pinfo->cinfo, COL_INFO, "WTLS" ); }; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { ti = proto_tree_add_item(tree, proto_wtls, tvb, offset_wtls, -1, bo_little_endian); wtls_tree = proto_item_add_subtree(ti, ett_wtls); for (offset_wtls=0; offset_wtls < (tvb_reported_length(tvb)-1);) { pdut = tvb_get_guint8 (tvb, offset_wtls); offset = offset_wtls+1; if (pdut & WTLS_RECORD_TYPE_SEQUENCE) { offset+=2; } if (pdut & WTLS_RECORD_TYPE_LENGTH) { count = tvb_get_ntohs(tvb, offset); offset+=2; count += offset-offset_wtls; } else { count = tvb_length_remaining (tvb, offset_wtls); } ti = proto_tree_add_uint(wtls_tree, hf_wtls_record, tvb, offset_wtls, count, pdut); wtls_rec_tree = proto_item_add_subtree(ti, ett_wtls_rec); offset = offset_wtls; ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_type, tvb,offset,1,bo_big_endian); offset++; offset_wtls += count; if (pdut & WTLS_RECORD_TYPE_SEQUENCE) { ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_sequence, tvb,offset,2,bo_big_endian); offset+=2; } if (pdut & WTLS_RECORD_TYPE_LENGTH) { count = tvb_get_ntohs(tvb, offset); ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_length, tvb,offset,2,bo_big_endian); offset+=2; } else { count = tvb_length_remaining (tvb, offset); } if (pdut & WTLS_RECORD_TYPE_CIPHER_CUR) { ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_ciphered, tvb,offset,count,bo_big_endian); continue; } switch (pdut & WTLS_RECORD_CONTENT_TYPE) { case WTLS_PLAIN_HANDSHAKE : dissect_wtls_handshake(wtls_rec_tree,tvb,offset,count); break; case WTLS_ALERT : ti = proto_tree_add_item(wtls_rec_tree, hf_wtls_alert, tvb, offset, count, bo_little_endian); wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); pdu_msg_type = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_level, tvb,offset,1,bo_big_endian); offset+=1; count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_description, tvb,offset,1,bo_big_endian); offset+=1; default: offset+=count; break; } } } } static int add_text_identifier(tvbuff_t *tvb, int offset, int hf_charset, int hf_size, int hf_str, proto_tree *tree) { guint8 size; int client_size = 0; proto_tree_add_item(tree, hf_charset, tvb, offset, 2, bo_big_endian); offset+=2; size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(tree, hf_size, tvb, offset, 1, bo_big_endian); offset++; proto_tree_add_item(tree, hf_str, tvb, offset, size, bo_big_endian); offset+=size; client_size+=size+3; #ifdef DEBUG fprintf(stderr, "text id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ return client_size; } static void dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count) { char pdu_msg_type; nstime_t timeValue; int client_size = 0; guint value = 0; int size = 0; guint public_key = 0; guint signature = 0; char valStr[1024]; char *valBulk = NULL; char *valMac = NULL; proto_item *ti; proto_item *cli_key_item; proto_tree *wtls_msg_type_tree; proto_tree *wtls_msg_type_item_tree; proto_tree *wtls_msg_type_item_sub_tree; proto_tree *wtls_msg_type_item_sub_sub_tree; pdu_msg_type = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_uint(tree, hf_wtls_hands, tvb, offset,count, pdu_msg_type); wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type, tvb,offset,1,bo_big_endian); offset+=1; count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length, tvb,offset,2,bo_big_endian); offset+=2; switch(pdu_msg_type) { case WTLS_HANDSHAKE_CLIENT_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset, count, bo_little_endian); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version, tvb,offset,1,bo_big_endian); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; ti = proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random, tvb,offset,12,bo_big_endian); offset+=12; count = tvb_get_guint8(tvb, offset); switch(count) { case 0: ti = proto_tree_add_string (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session_str, tvb,offset,count+1,"NULL"); break; case 1 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, tvb,offset,count+1,tvb_get_guint8(tvb,offset+1)); break; case 2 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, tvb,offset,count+1,tvb_get_ntohs(tvb,offset+1)); break; case 3 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, tvb,offset,count+1,tvb_get_ntoh24(tvb,offset+1)); break; case 4 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, tvb,offset,count+1,tvb_get_ntohl(tvb,offset+1)); break; default: ti = proto_tree_add_string (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session_str, tvb,offset,count+1,"Too big"); break; } offset+=1+count; /* process client_key_ids structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cli_key_id, tvb, offset, count+2, bo_little_endian); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of client_key_ids structure */ ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,bo_big_endian); offset+=2; /* cycle through client_key_ids entries */ for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); ti = proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,bo_big_endian); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,bo_big_endian); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,bo_big_endian); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch(value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,bo_big_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,bo_big_endian); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,bo_big_endian); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,bo_big_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,bo_big_endian); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process trusted_keys structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_trust_key_id, tvb, offset, count+2, bo_little_endian); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of trusted_keys structure */ ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,bo_big_endian); offset+=2; for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); ti = proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,bo_big_endian); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,bo_big_endian); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,bo_big_endian); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch (value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,bo_big_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,bo_big_endian); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,bo_big_endian); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); /* need to fetch identifier and display it */ ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,bo_big_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,bo_big_endian); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process cipher_suites structure */ count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cipher_suite, tvb, offset, count+1, bo_little_endian); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { value = tvb_get_guint8 (tvb, offset); valBulk = match_strval(value, wtls_vals_cipher_bulk); offset++; client_size=1; valMac = match_strval(tvb_get_guint8 (tvb, offset), wtls_vals_cipher_mac); if (valBulk != NULL) { if (valMac != NULL) { snprintf(valStr,1024,"%s, %s",valBulk,valMac); } else { snprintf(valStr,1024,"%s, Unknown MAC (0x%02x)",valBulk,tvb_get_guint8 (tvb, offset)); } } else { if (valMac != NULL) { snprintf(valStr,1024,"Unknown Bulk (0x%02x), %s",value,valMac); } else { snprintf(valStr,1024,"Unknown Bulk (0x%02x), Unknown MAC (0x%02x)",value, tvb_get_guint8 (tvb, offset)); } } offset++; client_size++; cli_key_item = proto_tree_add_string(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset-2,2, valStr); } count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_compression_methods, tvb, offset, count+1, bo_little_endian); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { client_size=0; ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_compression, tvb, offset,1, bo_little_endian); offset++; client_size++; } ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_sequence_mode, tvb, offset, 1, bo_little_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_key_refresh, tvb, offset, 1, bo_little_endian); break; case WTLS_HANDSHAKE_SERVER_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset, count, bo_little_endian); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version, tvb,offset,1,bo_big_endian); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; ti = proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random, tvb,offset,12,bo_big_endian); offset+=12; count = tvb_get_guint8(tvb, offset); switch(count) { case 0: ti = proto_tree_add_string (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session_str, tvb,offset,count+1,"NULL"); break; case 1 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, tvb,offset,count+1,tvb_get_guint8(tvb,offset+1)); break; case 2 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, tvb,offset,count+1,tvb_get_ntohs(tvb,offset+1)); break; case 3 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, tvb,offset,count+1,tvb_get_ntoh24(tvb,offset+1)); break; case 4 : ti = proto_tree_add_uint (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, tvb,offset,count+1,tvb_get_ntohl(tvb,offset+1)); break; default: ti = proto_tree_add_string (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session_str, tvb,offset,count+1,"Too big"); break; } offset+=1+count; ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cli_key_id, tvb,offset,1,bo_big_endian); offset++; cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2, bo_little_endian); wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_bulk, tvb,offset,1,bo_big_endian); offset++; value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_mac, tvb,offset,1,bo_big_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_compression, tvb, offset,1, bo_little_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_sequence_mode, tvb, offset, 1, bo_little_endian); offset++; ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_key_refresh, tvb, offset, 1, bo_little_endian); offset++; break; case WTLS_HANDSHAKE_CERTIFICATE : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates, tvb, offset,count, bo_little_endian); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); count = tvb_get_ntohs (tvb, offset); offset+=2; for (;count > 0;count-=client_size) { cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_certificate, tvb, offset,1, bo_little_endian); client_size=0; wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); proto_item_set_len(cli_key_item, client_size); value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_type, tvb, offset,1, bo_little_endian); offset++; client_size++; switch(value) { case CERTIFICATE_WTLS: ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_version, tvb, offset,1, bo_little_endian); offset++; client_size++; signature = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature_type, tvb, offset,1, bo_little_endian); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_issuer_type, tvb, offset,1, bo_little_endian); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_issuer_charset, hf_wtls_hands_certificate_wtls_issuer_size, hf_wtls_hands_certificate_wtls_issuer_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; ti = proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_before, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; ti = proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_after, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_subject_type, tvb, offset,1, bo_little_endian); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_subject_charset, hf_wtls_hands_certificate_wtls_subject_size, hf_wtls_hands_certificate_wtls_subject_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } public_key = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_public_key_type, tvb, offset,1, bo_little_endian); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_index, tvb,offset,1,bo_big_endian); offset++; client_size++; if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_set, tvb,offset,size+2,bo_big_endian); offset+=size+2; client_size+=size+2; } switch (public_key) { case PUBLIC_KEY_RSA : value = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_exponent, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; value = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_modules, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; break; case PUBLIC_KEY_ECDH : break; case PUBLIC_KEY_ECDSA : break; } value = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature, tvb,offset,2+value,value*8); offset+=2+value; client_size+=2+value; break; case CERTIFICATE_X509: case CERTIFICATE_X968: value = tvb_get_ntohs (tvb, offset); offset+=2; client_size+=2; client_size += value; offset += value; break; case CERTIFICATE_URL: value = tvb_get_guint8 (tvb, offset); offset++; client_size++; client_size += value; offset += value; break; } proto_item_set_len(cli_key_item, client_size); } break; default: offset+=count; break; } } /* Register the protocol with Ethereal */ void proto_register_wtls(void) { /* Setup list of header fields */ static hf_register_info hf[] = { { &hf_wtls_record, { "Record", "wtls.record", FT_UINT8, BASE_DEC, VALS ( wtls_vals_record_type ), 0x0f, "Record", HFILL } }, { &hf_wtls_record_type, { "Record Type", "wtls.rec_type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_record_type ), 0x0f, "Record Type", HFILL } }, { &hf_wtls_record_length, { "Record Length", "wtls.rec_length", FT_UINT16, BASE_DEC, NULL, 0x00, "Record Length", HFILL } }, { &hf_wtls_record_sequence, { "Record Sequence", "wtls.rec_seq", FT_UINT16, BASE_DEC, NULL, 0x00, "Record Sequence", HFILL } }, { &hf_wtls_record_ciphered, { "Record Ciphered", "wtls.rec_cipher", FT_NONE, BASE_NONE, NULL, 0x00, "Record Ciphered", HFILL } }, { &hf_wtls_hands, { "Handshake", "wtls.handshake", FT_UINT8, BASE_DEC, VALS ( wtls_vals_handshake_type ), 0x00, "Handshake", HFILL } }, { &hf_wtls_hands_type, { "Type", "wtls.handshake.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_handshake_type ), 0x00, "Type", HFILL } }, { &hf_wtls_hands_length, { "Length", "wtls.handshake.length", FT_UINT16, BASE_DEC, NULL, 0x00, "Length", HFILL } }, { &hf_wtls_hands_cli_hello, { "Client Hello", "wtls.handshake.client_hello", FT_NONE, BASE_NONE, NULL, 0x00, "Client Hello", HFILL } }, { &hf_wtls_hands_cli_hello_version, { "Version", "wtls.handshake.client_hello.version", FT_UINT8, BASE_DEC, NULL, 0x00, "Version", HFILL } }, { &hf_wtls_hands_cli_hello_gmt, { "Time GMT", "wtls.handshake.client_hello.gmt", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, "Time GMT", HFILL } }, { &hf_wtls_hands_cli_hello_random, { "Random", "wtls.handshake.client_hello.random", FT_NONE, BASE_NONE, NULL, 0x00, "Random", HFILL } }, { &hf_wtls_hands_cli_hello_session, { "Session ID", "wtls.handshake.client_hello.sessionid", FT_UINT32, BASE_DEC, NULL, 0x00, "Session ID", HFILL } }, { &hf_wtls_hands_cli_hello_session_str, { "Session ID", "wtls.handshake.client_hello.session.str", FT_STRING, BASE_NONE, NULL, 0x00, "Session ID", HFILL } }, { &hf_wtls_hands_cli_hello_cli_key_id, { "Client Keys", "wtls.handshake.client_hello.client_keys_id", FT_NONE, BASE_NONE, NULL, 0x00, "Client Keys" , HFILL } }, { &hf_wtls_hands_cli_hello_cli_key_len, { "Length", "wtls.handshake.client_hello.client_keys_len", FT_UINT16, BASE_DEC, NULL, 0x00, "Length" , HFILL } }, { &hf_wtls_hands_cli_hello_trust_key_id, { "Trusted Keys", "wtls.handshake.client_hello.trusted_keys_id", FT_NONE, BASE_NONE, NULL, 0x00, "Trusted Keys" , HFILL } }, { &hf_wtls_hands_cli_hello_key_exchange, { "Key Exchange", "wtls.handshake.client_hello.key.key_exchange", FT_UINT8, BASE_DEC, VALS ( wtls_vals_key_exchange_suite ), 0x00, "Key Exchange", HFILL } }, { &hf_wtls_hands_cli_hello_key_exchange_suite, { "Suite", "wtls.handshake.client_hello.key.key_exchange.suite", FT_UINT8, BASE_DEC, VALS ( wtls_vals_key_exchange_suite ), 0x00, "Suite", HFILL } }, { &hf_wtls_hands_cli_hello_key_parameter_index, { "Parameter Index", "wtls.handshake.client_hello.parameter_index", FT_UINT8, BASE_DEC, NULL, 0x00, "Parameter Index", HFILL } }, { &hf_wtls_hands_cli_hello_key_parameter_set, { "Parameter Set", "wtls.handshake.client_hello.parameter", FT_STRING, BASE_NONE, NULL, 0x00, "Parameter Set", HFILL } }, { &hf_wtls_hands_cli_hello_key_identifier_type, { "Identifier Type", "wtls.handshake.client_hello.ident_type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_identifier_type ), 0x00, "Identifier Type", HFILL } }, { &hf_wtls_hands_cli_hello_key_identifier_charset, { "Identifier CharSet", "wtls.handshake.client_hello.ident_charset", FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00, "Identifier CharSet", HFILL } }, { &hf_wtls_hands_cli_hello_key_identifier_size, { "Identifier Size", "wtls.handshake.client_hello.ident_size", FT_UINT8, BASE_DEC, NULL, 0x00, "Identifier Size", HFILL } }, { &hf_wtls_hands_cli_hello_key_identifier, { "Identifier", "wtls.handshake.client_hello.identifier", FT_NONE, BASE_NONE, NULL, 0x00, "Identifier", HFILL } }, { &hf_wtls_hands_cli_hello_key_identifier_str, { "Identifier Name", "wtls.handshake.client_hello.ident_name", FT_STRING, BASE_NONE, NULL, 0x00, "Identifier Name", HFILL } }, { &hf_wtls_hands_cli_hello_cipher_suite, { "Cipher Suites", "wtls.handshake.client_hello.ciphers", FT_NONE, BASE_NONE, NULL, 0x00, "Cipher Suite", HFILL } }, { &hf_wtls_hands_cli_hello_cipher_suite_item, { "Cipher", "wtls.handshake.client_hello.cipher", FT_STRING, BASE_NONE, NULL, 0x00, "Cipher", HFILL } }, { &hf_wtls_hands_cli_hello_compression_methods, { "Compression Methods", "wtls.handshake.client_hello.comp_methods", FT_NONE, BASE_NONE, NULL, 0x00, "Compression Methods", HFILL } }, { &hf_wtls_hands_cli_hello_compression, { "Compression", "wtls.handshake.client_hello.compression", FT_UINT8, BASE_HEX, VALS ( wtls_vals_compression ), 0x00, "Compression", HFILL } }, { &hf_wtls_hands_cli_hello_sequence_mode, { "Sequence Mode", "wtls.handshake.client_hello.sequence_mode", FT_UINT8, BASE_DEC, VALS ( wtls_vals_sequence_mode ), 0x00, "Sequence Mode", HFILL } }, { &hf_wtls_hands_cli_hello_key_refresh, { "Refresh", "wtls.handshake.client_hello.refresh", FT_UINT8, BASE_DEC, NULL, 0x00, "Refresh", HFILL } }, { &hf_wtls_hands_serv_hello, { "Server Hello", "wtls.handshake.server_hello", FT_NONE, BASE_NONE, NULL, 0x00, "Server Hello", HFILL } }, { &hf_wtls_hands_serv_hello_version, { "Version", "wtls.handshake.server_hello.version", FT_UINT8, BASE_DEC, NULL, 0x00, "Version", HFILL } }, { &hf_wtls_hands_serv_hello_gmt, { "Time GMT", "wtls.handshake.server_hello.gmt", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, "Time GMT", HFILL } }, { &hf_wtls_hands_serv_hello_random, { "Random", "wtls.handshake.server_hello.random", FT_NONE, BASE_NONE, NULL, 0x00, "Random", HFILL } }, { &hf_wtls_hands_serv_hello_session, { "Session ID", "wtls.handshake.server_hello.sessionid", FT_UINT32, BASE_DEC, NULL, 0x00, "Session ID", HFILL } }, { &hf_wtls_hands_serv_hello_session_str, { "Session ID", "wtls.handshake.server_hello.session.str", FT_STRING, BASE_NONE, NULL, 0x00, "Session ID", HFILL } }, { &hf_wtls_hands_serv_hello_cli_key_id, { "Client Key ID", "wtls.handshake.server_hello.key", FT_UINT8, BASE_HEX, NULL, 0x00, "Client Key ID", HFILL } }, { &hf_wtls_hands_serv_hello_cipher_suite_item, { "Cipher", "wtls.handshake.server_hello.cipher", FT_NONE, BASE_NONE, NULL, 0x00, "Cipher", HFILL } }, { &hf_wtls_hands_serv_hello_cipher_bulk, { "Cipher Bulk", "wtls.handshake.server_hello.cipher.bulk", FT_UINT8, BASE_DEC, VALS ( wtls_vals_cipher_bulk ), 0x00, "Cipher Bulk", HFILL } }, { &hf_wtls_hands_serv_hello_cipher_mac, { "Cipher MAC", "wtls.handshake.server_hello.cipher.mac", FT_UINT8, BASE_DEC, VALS ( wtls_vals_cipher_mac ), 0x00, "Cipher MAC", HFILL } }, { &hf_wtls_hands_serv_hello_compression, { "Compression", "wtls.handshake.server_hello.compression", FT_UINT8, BASE_HEX, VALS ( wtls_vals_compression ), 0x00, "Compression", HFILL } }, { &hf_wtls_hands_serv_hello_sequence_mode, { "Sequence Mode", "wtls.handshake.server_hello.sequence_mode", FT_UINT8, BASE_DEC, VALS ( wtls_vals_sequence_mode ), 0x00, "Sequence Mode", HFILL } }, { &hf_wtls_hands_serv_hello_key_refresh, { "Refresh", "wtls.handshake.server_hello.refresh", FT_UINT8, BASE_DEC, NULL, 0x00, "Refresh", HFILL } }, { &hf_wtls_hands_certificates, { "Certificates", "wtls.handshake.certificates", FT_NONE, BASE_NONE, NULL, 0x00, "Certificates", HFILL } }, { &hf_wtls_hands_certificate, { "Certificate", "wtls.handshake.certificate", FT_NONE, BASE_NONE, NULL, 0x00, "Certificate", HFILL } }, { &hf_wtls_hands_certificate_type, { "Type", "wtls.handshake.certificate.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_certificate_type ), 0x00, "Type", HFILL } }, { &hf_wtls_hands_certificate_wtls_version, { "Version", "wtls.handshake.certificate.version", FT_UINT8, BASE_HEX, NULL, 0x00, "Version", HFILL } }, { &hf_wtls_hands_certificate_wtls_signature_type, { "Signature Type", "wtls.handshake.certificate.signature.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_certificate_signature ), 0x00, "Signature Type", HFILL } }, { &hf_wtls_hands_certificate_wtls_signature, { "Signature Size", "wtls.handshake.certificate.signature.signature", FT_UINT32, BASE_DEC, NULL, 0x00, "Signature Size", HFILL } }, { &hf_wtls_hands_certificate_wtls_issuer_type, { "Issuer", "wtls.handshake.certificate.issuer.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_identifier_type ), 0x00, "Issuer", HFILL } }, { &hf_wtls_hands_certificate_wtls_issuer_charset, { "Charset", "wtls.handshake.certificate.issuer.charset", FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00, "Charset", HFILL } }, { &hf_wtls_hands_certificate_wtls_issuer_size, { "Size", "wtls.handshake.certificate.issuer.size", FT_UINT8, BASE_DEC, NULL, 0x00, "Size", HFILL } }, { &hf_wtls_hands_certificate_wtls_issuer_name, { "Name", "wtls.handshake.certificate.issuer.name", FT_STRING, BASE_NONE, NULL, 0x00, "Name", HFILL } }, { &hf_wtls_hands_certificate_wtls_valid_not_before, { "Valid not before", "wtls.handshake.certificate.before", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, "Valid not before", HFILL } }, { &hf_wtls_hands_certificate_wtls_valid_not_after, { "Valid not after", "wtls.handshake.certificate.after", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, "Valid not after", HFILL } }, { &hf_wtls_hands_certificate_wtls_subject_type, { "Subject", "wtls.handshake.certificate.subject.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_identifier_type ), 0x00, "Subject", HFILL } }, { &hf_wtls_hands_certificate_wtls_subject_charset, { "Charset", "wtls.handshake.certificate.subject.charset", FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00, "Charset", HFILL } }, { &hf_wtls_hands_certificate_wtls_subject_size, { "Size", "wtls.handshake.certificate.subject.size", FT_UINT8, BASE_DEC, NULL, 0x00, "Size", HFILL } }, { &hf_wtls_hands_certificate_wtls_subject_name, { "Name", "wtls.handshake.certificate.subject.name", FT_STRING, BASE_NONE, NULL, 0x00, "Name", HFILL } }, { &hf_wtls_hands_certificate_wtls_public_key_type, { "Public Key Type", "wtls.handshake.certificate.public.type", FT_UINT8, BASE_DEC, VALS ( wtls_vals_public_key_type ), 0x00, "Public Key Type", HFILL } }, { &hf_wtls_hands_certificate_wtls_key_parameter_index, { "Parameter Index", "wtls.handshake.certificate.parameter_index", FT_UINT8, BASE_DEC, NULL, 0x00, "Parameter Index", HFILL } }, { &hf_wtls_hands_certificate_wtls_key_parameter_set, { "Parameter Set", "wtls.handshake.certificate.parameter", FT_STRING, BASE_NONE, NULL, 0x00, "Parameter Set", HFILL } }, { &hf_wtls_hands_certificate_wtls_rsa_exponent, { "RSA Exponent Size", "wtls.handshake.certificate.rsa.exponent", FT_UINT32, BASE_DEC, NULL, 0x00, "RSA Exponent Size", HFILL } }, { &hf_wtls_hands_certificate_wtls_rsa_modules, { "RSA Modulus Size", "wtls.handshake.certificate.rsa.modules", FT_UINT32, BASE_DEC, NULL, 0x00, "RSA Modulus Size", HFILL } }, { &hf_wtls_alert, { "Alert", "wtls.alert", FT_NONE, BASE_NONE, NULL, 0x00, "Alert", HFILL } }, { &hf_wtls_alert_level, { "Level", "wtls.alert.level", FT_UINT8, BASE_DEC, VALS ( wtls_vals_alert_level ), 0x00, "Level", HFILL } }, { &hf_wtls_alert_description, { "Description", "wtls.alert.description", FT_UINT8, BASE_DEC, VALS ( wtls_vals_alert_description ), 0x00, "Description", HFILL } }, }; /* Setup protocol subtree array */ static gint *ett[] = { &ett_wtls, &ett_wtls_rec, &ett_wtls_msg_type, &ett_wtls_msg_type_item, &ett_wtls_msg_type_item_sub, &ett_wtls_msg_type_item_sub_sub, }; /* Register the protocol name and description */ proto_wtls = proto_register_protocol( "Wireless Transport Layer Security", /* protocol name for use by ethereal */ "WTLS", /* short version of name */ "wtls" /* Abbreviated protocol name, should Match IANA < URL:http://www.iana.org/assignments/port-numbers/ > */ ); /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_wtls, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_wtls(void) { dissector_handle_t wtls_handle; wtls_handle = create_dissector_handle(dissect_wtls, proto_wtls); dissector_add("udp.port", UDP_PORT_WTLS_WSP, wtls_handle); dissector_add("udp.port", UDP_PORT_WTLS_WTP_WSP, wtls_handle); dissector_add("udp.port", UDP_PORT_WTLS_WSP_PUSH,wtls_handle); }