MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-zrtp.c
blobe9a8a0a8db19e86d368c735e0b879a931bf4637a
1 /* packet-zrtp.c
2 * Routines for zrtp packet dissection
3 * IETF draft draft-zimmermann-avt-zrtp-22
4 * Copyright 2007, Sagar Pai <sagar@gmail.com>
6 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-pop.c
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "config.h"
31 #include <string.h>
32 #include <glib.h>
33 #include <epan/packet.h>
34 #include <epan/strutil.h>
35 #include <epan/wmem/wmem.h>
36 #include <wsutil/crc32.h>
37 #include "packet-rtp.h"
38 #include "packet-rtcp.h"
41 RTP header
43 static int proto_zrtp = -1;
44 static int hf_zrtp_rtpversion = -1;
45 static int hf_zrtp_rtppadding = -1;
46 static int hf_zrtp_rtpextension = -1;
47 /* static int hf_zrtp_id = -1; */
48 static int hf_zrtp_sequence = -1;
49 static int hf_zrtp_cookie = -1;
50 static int hf_zrtp_source_id = -1;
53 ZRTP header
55 static int hf_zrtp_signature = -1;
56 static int hf_zrtp_msg_length = -1;
57 static int hf_zrtp_msg_type = -1;
58 static int hf_zrtp_msg_version = -1;
61 Hello Data
63 static int hf_zrtp_msg_client_id = -1;
64 static int hf_zrtp_msg_zid = -1;
65 static int hf_zrtp_msg_sigcap = -1;
66 static int hf_zrtp_msg_mitm = -1;
67 static int hf_zrtp_msg_passive = -1;
68 static int hf_zrtp_msg_hash_count = -1;
69 static int hf_zrtp_msg_cipher_count = -1;
70 static int hf_zrtp_msg_authtag_count = -1;
71 static int hf_zrtp_msg_key_count = -1;
72 static int hf_zrtp_msg_sas_count = -1;
73 static int hf_zrtp_msg_hash = -1;
74 static int hf_zrtp_msg_cipher = -1;
75 static int hf_zrtp_msg_at = -1;
76 static int hf_zrtp_msg_keya = -1;
77 static int hf_zrtp_msg_sas = -1;
78 static int hf_zrtp_msg_hash_image = -1;
81 Commit Data
83 static int hf_zrtp_msg_hvi = -1;
84 static int hf_zrtp_msg_nonce = -1;
85 static int hf_zrtp_msg_key_id = -1;
88 DHParts Data
90 static int hf_zrtp_msg_rs1ID = -1;
91 static int hf_zrtp_msg_rs2ID = -1;
92 static int hf_zrtp_msg_auxs = -1;
93 static int hf_zrtp_msg_pbxs = -1;
96 Confirm Data
98 static int hf_zrtp_msg_hmac = -1;
99 static int hf_zrtp_msg_cfb = -1;
102 Error Data
104 static int hf_zrtp_msg_error = -1;
107 Ping Data
109 static int hf_zrtp_msg_ping_version = -1;
110 static int hf_zrtp_msg_ping_endpointhash = -1;
111 static int hf_zrtp_msg_pingack_endpointhash = -1;
112 static int hf_zrtp_msg_ping_ssrc = -1;
115 Checksum Data
117 static int hf_zrtp_checksum = -1;
118 static int hf_zrtp_checksum_good = -1;
119 static int hf_zrtp_checksum_bad = -1;
122 Sub-Tree
124 static gint ett_zrtp = -1;
125 static gint ett_zrtp_msg = -1;
126 static gint ett_zrtp_msg_data = -1;
128 static gint ett_zrtp_msg_hc = -1;
129 static gint ett_zrtp_msg_kc = -1;
130 static gint ett_zrtp_msg_ac = -1;
131 static gint ett_zrtp_msg_cc = -1;
132 static gint ett_zrtp_msg_sc = -1;
134 static gint ett_zrtp_checksum = -1;
137 Definitions
139 #define ZRTP_ERR_10 0x10
140 #define ZRTP_ERR_20 0x20
141 #define ZRTP_ERR_30 0x30
142 #define ZRTP_ERR_40 0x40
143 #define ZRTP_ERR_51 0x51
144 #define ZRTP_ERR_52 0x52
145 #define ZRTP_ERR_53 0x53
146 #define ZRTP_ERR_54 0x54
147 #define ZRTP_ERR_55 0x55
148 #define ZRTP_ERR_56 0x56
149 #define ZRTP_ERR_61 0x61
150 #define ZRTP_ERR_62 0x62
151 #define ZRTP_ERR_63 0x63
152 #define ZRTP_ERR_70 0x70
153 #define ZRTP_ERR_80 0x80
154 #define ZRTP_ERR_90 0x90
155 #define ZRTP_ERR_91 0x91
156 #define ZRTP_ERR_A0 0xA0
157 #define ZRTP_ERR_B0 0xB0
158 #define ZRTP_ERR_100 0x100
161 Text for Display
163 typedef struct _value_zrtp_versions {
164 const gchar *version;
165 } value_zrtp_versions;
168 typedef struct _value_string_keyval {
169 const gchar *key;
170 const gchar *val;
171 } value_string_keyval;
174 const value_zrtp_versions valid_zrtp_versions[] =
176 {"1.1x"},
177 {"1.0x"},
178 {"0.95"},
179 {"0.90"},
180 {"0.85"},
181 {NULL}
184 const value_string_keyval zrtp_hash_type_vals[] =
186 { "S256", "SHA-256 Hash"},
187 { "S384", "SHA-384 Hash"},
188 { "N256", "SHA-3 256-bit hash"},
189 { "N384", "SHA-3 384 bit hash"},
190 { NULL, NULL }
193 const value_string_keyval zrtp_cipher_type_vals[] =
195 { "AES1", "AES-CM with 128 bit keys"},
196 { "AES2", "AES-CM with 192 bit keys"},
197 { "AES3", "AES-CM with 256 bit keys"},
198 { "2FS1", "TwoFish with 128 bit keys"},
199 { "2FS2", "TwoFish with 192 bit keys"},
200 { "2FS3", "TwoFish with 256 bit keys"},
201 { "CAM1", "Camellia with 128 bit keys"},
202 { "CAM2", "Camellia with 192 bit keys"},
203 { "CAM3", "Camellia with 256 bit keys"},
204 { NULL, NULL }
207 const value_string_keyval zrtp_auth_tag_vals[] =
209 { "HS32", "HMAC-SHA1 32 bit authentication tag"},
210 { "HS80", "HMAC-SHA1 80 bit authentication tag"},
211 { "SK32", "Skein-512-MAC 32 bit authentication tag"},
212 { "SK64", "Skein-512-MAC 64 bit authentication tag"},
213 { NULL, NULL }
216 const value_string_keyval zrtp_sas_type_vals[] =
218 { "B32 ", "Short authentication string using base 32"},
219 { "B256", "Short authentication string using base 256"},
220 { NULL, NULL }
223 const value_string_keyval zrtp_key_agreement_vals[] =
225 { "DH2k", "DH mode with p=2048 bit prime"},
226 { "DH3k", "DH mode with p=3072 bit prime"},
227 { "DH4k", "DH mode with p=4096 bit prime"},
228 { "Prsh", "Preshared non-DH mode using shared secret"},
229 { "EC25", "Elliptic Curve DH-256"},
230 { "EC38", "Elliptic Curve DH-384"},
231 { "EC52", "Elliptic Curve DH-521"},
232 { "Mult", "Multistream mode"},
233 { NULL, NULL }
236 const value_string zrtp_error_vals[] =
238 { ZRTP_ERR_10, "Malformed Packet (CRC OK but wrong structure)"},
239 { ZRTP_ERR_20, "Critical Software Error"},
240 { ZRTP_ERR_30, "Unsupported ZRTP version"},
241 { ZRTP_ERR_40, "Hello Components mismatch"},
242 { ZRTP_ERR_51, "Hash type unsupported"},
243 { ZRTP_ERR_52, "Cipher type not supported"},
244 { ZRTP_ERR_53, "Public key exchange not supported"},
245 { ZRTP_ERR_54, "SRTP auth. tag not supported"},
246 { ZRTP_ERR_55, "SAS scheme not supported"},
247 { ZRTP_ERR_56, "No shared secret available, DH mode required"},
248 { ZRTP_ERR_61, "DH Error: bad pv for initiator/responder value is (1,0,p-1)"},
249 { ZRTP_ERR_62, "DH Error: bad hash commitment (hvi != hashed data)"},
250 { ZRTP_ERR_63, "Received relayed SAS from untrusted MiTM"},
251 { ZRTP_ERR_70, "Auth. Error Bad Confirm Packet HMAC"},
252 { ZRTP_ERR_80, "Nonce is reused"},
253 { ZRTP_ERR_90, "Equal ZID's in Hello"},
254 { ZRTP_ERR_91, "SSRC collision"},
255 { ZRTP_ERR_A0, "Service unavailable"},
256 { ZRTP_ERR_B0, "Protocol timeout error"},
257 { ZRTP_ERR_100, "GoClear packet received, but not allowed"},
258 { 0, NULL}
261 static void
262 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
263 static void
264 dissect_ErrorACK(packet_info *pinfo);
265 static void
266 dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
267 static void
268 dissect_ClearACK( packet_info *pinfo);
269 static void
270 dissect_Conf2ACK(packet_info *pinfo);
271 static void
272 dissect_HelloACK( packet_info *pinfo);
273 static void
274 dissect_GoClear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
275 static void
276 dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
277 static void
278 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part);
279 static void
280 dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part);
281 static void
282 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
283 static void
284 dissect_RelayACK(packet_info *pinfo);
285 static void
286 dissect_Ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
287 static void
288 dissect_PingACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree);
291 static const gchar *
292 key_to_val(const gchar *key, int keylen, const value_string_keyval *kv, const gchar *fmt) {
293 int i = 0;
294 while (kv[i].key) {
295 if (!strncmp(kv[i].key, key, keylen)) {
296 return(kv[i].val);
298 i++;
300 return wmem_strdup_printf(wmem_packet_scope(), fmt, key);
303 static const gchar *
304 check_valid_version(const gchar *version) {
305 int i = 0;
306 int match_size = (version[0] == '0') ? 4 : 3;
307 while (valid_zrtp_versions[i].version) {
308 if (!strncmp(valid_zrtp_versions[i].version, version, match_size)) {
309 return(valid_zrtp_versions[i].version);
311 i++;
313 return NULL;
317 static void
318 dissect_zrtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
320 proto_tree *zrtp_tree;
321 proto_tree *zrtp_msg_tree;
322 proto_tree *zrtp_msg_data_tree;
323 proto_tree *checksum_tree;
324 proto_item *ti;
325 int linelen;
326 int checksum_offset;
327 unsigned char message_type[9];
328 unsigned int prime_offset = 0;
329 unsigned int msg_offset = 12;
330 guint32 sent_crc, calc_crc;
332 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZRTP");
334 col_set_str(pinfo->cinfo, COL_INFO, "Unknown ZRTP Packet");
336 ti = proto_tree_add_protocol_format(tree, proto_zrtp, tvb, 0, -1, "ZRTP protocol");
337 zrtp_tree = proto_item_add_subtree(ti, ett_zrtp);
339 proto_tree_add_item(zrtp_tree, hf_zrtp_rtpversion, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);
340 proto_tree_add_item(zrtp_tree, hf_zrtp_rtppadding, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);
341 proto_tree_add_item(zrtp_tree, hf_zrtp_rtpextension, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);
343 proto_tree_add_item(zrtp_tree, hf_zrtp_sequence, tvb, prime_offset+2, 2, ENC_BIG_ENDIAN);
345 proto_tree_add_item(zrtp_tree, hf_zrtp_cookie, tvb, prime_offset+4, 4, ENC_ASCII|ENC_NA);
347 proto_tree_add_item(zrtp_tree, hf_zrtp_source_id, tvb, prime_offset+8, 4, ENC_BIG_ENDIAN);
349 linelen = tvb_reported_length_remaining(tvb, msg_offset);
350 checksum_offset = linelen-4;
352 ti = proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, msg_offset, linelen-4, "Message");
353 zrtp_msg_tree = proto_item_add_subtree(ti, ett_zrtp_msg);
355 proto_tree_add_item(zrtp_msg_tree, hf_zrtp_signature, tvb, msg_offset+0, 2, ENC_BIG_ENDIAN);
357 proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_length, tvb, msg_offset+2, 2, ENC_BIG_ENDIAN);
359 tvb_memcpy(tvb, (void *)message_type, msg_offset+4, 8);
360 message_type[8] = '\0';
361 proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_type, tvb, msg_offset+4, 8, ENC_ASCII|ENC_NA);
363 linelen = tvb_reported_length_remaining(tvb, msg_offset+12);
365 if (!strncmp(message_type, "Hello ", 8)) {
366 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
367 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
368 dissect_Hello(tvb, pinfo, zrtp_msg_data_tree);
369 } else if (!strncmp(message_type, "HelloACK", 8)) {
370 dissect_HelloACK(pinfo);
371 } else if (!strncmp(message_type, "Commit ", 8)) {
372 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
373 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
374 dissect_Commit(tvb, pinfo, zrtp_msg_data_tree);
375 } else if (!strncmp(message_type, "DHPart1 ", 8)) {
376 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
377 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
378 dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 1);
379 } else if (!strncmp(message_type, "DHPart2 ", 8)) {
380 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
381 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
382 dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 2);
383 } else if (!strncmp(message_type, "Confirm1", 8)) {
384 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
385 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
386 dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 1);
387 } else if (!strncmp(message_type, "Confirm2", 8)) {
388 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
389 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
390 dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 2);
391 } else if (!strncmp(message_type, "Conf2ACK", 8)) {
392 dissect_Conf2ACK(pinfo);
393 } else if (!strncmp(message_type, "Error ", 8)) {
394 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
395 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
396 dissect_Error(tvb, pinfo, zrtp_msg_data_tree);
397 } else if (!strncmp(message_type, "ErrorACK", 8)) {
398 dissect_ErrorACK(pinfo);
399 } else if (!strncmp(message_type, "GoClear ", 8)) {
400 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
401 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
402 dissect_GoClear(tvb, pinfo, zrtp_msg_data_tree);
403 } else if (!strncmp(message_type, "ClearACK", 8)) {
404 dissect_ClearACK(pinfo);
405 } else if (!strncmp(message_type, "SASrelay", 8)) {
406 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
407 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
408 dissect_SASrelay(tvb, pinfo, zrtp_msg_data_tree);
409 } else if (!strncmp(message_type, "RelayACK", 8)) {
410 dissect_RelayACK(pinfo);
411 } else if (!strncmp(message_type, "Ping ", 8)) {
412 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
413 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
414 dissect_Ping(tvb, pinfo, zrtp_msg_data_tree);
415 } else if (!strncmp(message_type, "PingACK ", 8)) {
416 ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
417 zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
418 dissect_PingACK(tvb, pinfo, zrtp_msg_data_tree);
421 sent_crc = tvb_get_ntohl(tvb, msg_offset+checksum_offset);
422 calc_crc = ~crc32c_calculate(tvb_get_ptr(tvb, 0, msg_offset+checksum_offset), msg_offset+checksum_offset, CRC32C_PRELOAD);
424 if (sent_crc == calc_crc) {
425 ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
426 "0x%04x [correct]", sent_crc);
427 checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
428 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, TRUE);
429 PROTO_ITEM_SET_GENERATED(ti);
430 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, FALSE);
431 PROTO_ITEM_SET_GENERATED(ti);
432 } else {
433 ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
434 "0x%04x [incorrect, should be 0x%04x]", sent_crc, calc_crc);
435 checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
436 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, FALSE);
437 PROTO_ITEM_SET_GENERATED(ti);
438 ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, TRUE);
439 PROTO_ITEM_SET_GENERATED(ti);
444 static void
445 dissect_ErrorACK(packet_info *pinfo) {
446 col_set_str(pinfo->cinfo, COL_INFO, "ErrorACK Packet");
449 static void
450 dissect_ClearACK(packet_info *pinfo) {
451 col_set_str(pinfo->cinfo, COL_INFO, "ClearACK Packet");
454 static void
455 dissect_RelayACK(packet_info *pinfo) {
456 col_set_str(pinfo->cinfo, COL_INFO, "RelayACK Packet");
459 static void
460 dissect_Conf2ACK(packet_info *pinfo) {
462 /* Signals start of SRT(C)P streams */
463 struct srtp_info *dummy_srtp_info = wmem_new0(wmem_file_scope(), struct srtp_info);
465 dummy_srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
466 dummy_srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
467 dummy_srtp_info->mki_len = 0;
468 dummy_srtp_info->auth_tag_len = 4;
470 srtp_add_address(pinfo, &pinfo->net_src, pinfo->srcport, pinfo->destport,
471 "ZRTP", PINFO_FD_NUM(pinfo), FALSE, NULL, dummy_srtp_info);
473 srtp_add_address(pinfo, &pinfo->net_dst, pinfo->destport, pinfo->srcport,
474 "ZRTP", PINFO_FD_NUM(pinfo), FALSE, NULL, dummy_srtp_info);
476 srtcp_add_address(pinfo, &pinfo->net_src, pinfo->srcport+1, pinfo->destport+1,
477 "ZRTP", PINFO_FD_NUM(pinfo), dummy_srtp_info);
479 srtcp_add_address(pinfo, &pinfo->net_dst, pinfo->destport+1, pinfo->srcport+1,
480 "ZRTP", PINFO_FD_NUM(pinfo), dummy_srtp_info);
482 col_set_str(pinfo->cinfo, COL_INFO, "Conf2ACK Packet");
485 static void
486 dissect_HelloACK(packet_info *pinfo) {
487 col_set_str(pinfo->cinfo, COL_INFO, "HelloACK Packet");
490 static void
491 dissect_Ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
492 unsigned int data_offset = 24;
494 col_set_str(pinfo->cinfo, COL_INFO, "Ping Packet");
496 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_ping_version, tvb, data_offset, 4, ENC_ASCII|ENC_NA);
497 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_ping_endpointhash, tvb, data_offset+4, 8, ENC_BIG_ENDIAN);
500 static void
501 dissect_PingACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
502 unsigned int data_offset = 24;
504 col_set_str(pinfo->cinfo, COL_INFO, "PingACK Packet");
506 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_ping_version, tvb, data_offset, 4, ENC_ASCII|ENC_NA);
507 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_pingack_endpointhash, tvb, data_offset+4, 8, ENC_BIG_ENDIAN);
508 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_ping_endpointhash, tvb, data_offset+12, 8, ENC_BIG_ENDIAN);
509 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_ping_ssrc, tvb, data_offset+20, 4, ENC_BIG_ENDIAN);
512 static void
513 dissect_GoClear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
514 unsigned int data_offset = 24;
516 col_set_str(pinfo->cinfo, COL_INFO, "GoClear Packet");
518 /* Now we should clear the SRT(C)P session... */
520 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+0, 8, ENC_NA);
523 static void
524 dissect_Error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
525 unsigned int data_offset = 24;
527 col_set_str(pinfo->cinfo, COL_INFO, "Error Packet");
529 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_error, tvb, data_offset, 4, ENC_BIG_ENDIAN);
532 static void
533 dissect_Confirm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part) {
534 unsigned int data_offset = 24;
535 int linelen;
537 col_add_fstr(pinfo->cinfo, COL_INFO, (part == 1) ? "Confirm1 Packet" : "Confirm2 Packet");
539 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+0, 8, ENC_NA);
540 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_cfb, tvb, data_offset+8, 16, ENC_NA);
541 linelen = tvb_reported_length_remaining(tvb, data_offset+24);
542 proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, data_offset+24, linelen-4, "Encrypted Data");
545 static void
546 dissect_SASrelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
547 unsigned int data_offset = 24;
548 int linelen;
550 col_set_str(pinfo->cinfo, COL_INFO, "SASrelay Packet");
552 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+0, 8, ENC_NA);
553 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_cfb, tvb, data_offset+8, 16, ENC_NA);
554 linelen = tvb_reported_length_remaining(tvb, data_offset+24);
555 proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, data_offset+24, linelen-4, "Encrypted Data");
558 static void
559 dissect_DHPart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree, int part) {
560 unsigned int msg_offset = 12;
561 unsigned int data_offset = 56;
562 int linelen, pvr_len;
564 col_add_fstr(pinfo->cinfo, COL_INFO, (part == 1) ? "DHPart1 Packet" : "DHPart2 Packet");
566 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hash_image, tvb, msg_offset+12, 32, ENC_NA);
567 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_rs1ID, tvb, data_offset+0, 8, ENC_NA);
568 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_rs2ID, tvb, data_offset+8, 8, ENC_NA);
569 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_auxs, tvb, data_offset+16, 8, ENC_NA);
570 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_pbxs, tvb, data_offset+24, 8, ENC_NA);
571 linelen = tvb_reported_length_remaining(tvb, data_offset+32);
572 pvr_len = linelen-8-4;
573 proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, data_offset+32, pvr_len, (part==1) ? "pvr Data" : "pvi Data");
574 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+32+pvr_len, 8, ENC_NA);
577 static void
578 dissect_Commit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
579 unsigned int msg_offset = 12;
580 unsigned int data_offset = 56;
581 unsigned char value[5];
582 int key_type = 0;
584 0 - other type
585 1 - "Mult"
586 2 - "Prsh"
588 unsigned int offset;
590 col_set_str(pinfo->cinfo, COL_INFO, "Commit Packet");
592 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hash_image, tvb, msg_offset+12, 32, ENC_NA);
593 /* ZID */
594 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_zid, tvb, data_offset+0, 12, ENC_NA);
595 tvb_memcpy(tvb, (void *)value, data_offset+12, 4);
596 value[4] = '\0';
597 proto_tree_add_string_format_value(zrtp_tree, hf_zrtp_msg_hash, tvb, data_offset+12, 4, value,
598 "%s", key_to_val(value, 4, zrtp_hash_type_vals, "Unknown hash type %s"));
599 tvb_memcpy(tvb, (void *)value, data_offset+16, 4);
600 value[4] = '\0';
601 proto_tree_add_string_format_value(zrtp_tree, hf_zrtp_msg_cipher, tvb, data_offset+16, 4, value, "%s",
602 key_to_val(value, 4, zrtp_cipher_type_vals, "Unknown cipher type %s"));
603 tvb_memcpy(tvb, (void *)value, data_offset+20, 4);
604 value[4] = '\0';
605 proto_tree_add_string_format(zrtp_tree, hf_zrtp_msg_at, tvb, data_offset+20, 4, value,
606 "Auth tag: %s", key_to_val(value, 4, zrtp_auth_tag_vals, "Unknown auth tag %s"));
607 tvb_memcpy(tvb, (void *)value, data_offset+24, 4);
608 value[4] = '\0';
609 proto_tree_add_string_format_value(zrtp_tree, hf_zrtp_msg_keya, tvb, data_offset+24, 4, value,
610 "%s", key_to_val(value, 4, zrtp_key_agreement_vals, "Unknown key agreement %s"));
612 if(!strncmp(value, "Mult", 4)) {
613 key_type = 1;
614 } else if (!strncmp(value, "Prsh", 4)) {
615 key_type = 2;
617 tvb_memcpy(tvb, (void *)value, data_offset+28, 4);
618 value[4] = '\0';
619 proto_tree_add_string_format(zrtp_tree, hf_zrtp_msg_sas, tvb, data_offset+28, 4, value,
620 "SAS type: %s", key_to_val(value, 4, zrtp_sas_type_vals, "Unknown SAS type %s"));
622 switch (key_type) {
623 case 1: /*
624 Mult
626 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_nonce, tvb, data_offset+32, 16, ENC_NA);
627 offset = 48;
628 break;
629 case 2: /*
630 Prsh
632 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_nonce, tvb, data_offset+32, 16, ENC_NA);
633 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_key_id, tvb, data_offset+48, 8, ENC_NA);
634 offset = 56;
635 break;
636 default: /*
637 other
639 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hvi, tvb, data_offset+32, 32, ENC_NA);
640 offset = 64;
641 break;
644 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, data_offset+offset, 8, ENC_NA);
647 static void
648 dissect_Hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *zrtp_tree) {
649 proto_item *ti;
650 unsigned int msg_offset = 12;
651 unsigned int data_offset = 88;
652 guint8 val_b;
653 unsigned int i;
654 unsigned int run_offset;
655 unsigned int hc, cc, ac, kc, sc;
656 unsigned int vhc, vcc, vac, vkc, vsc;
657 unsigned char value[5];
658 unsigned char version_str[5];
659 proto_tree *tmp_tree;
661 col_set_str(pinfo->cinfo, COL_INFO, "Hello Packet");
663 tvb_memcpy(tvb, version_str, msg_offset+12, 4);
664 version_str[4] = '\0';
665 if (check_valid_version(version_str) == NULL) {
666 col_set_str(pinfo->cinfo, COL_INFO, "Unsupported version of ZRTP protocol");
668 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_version, tvb, msg_offset+12, 4, ENC_ASCII|ENC_NA);
669 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_client_id, tvb, msg_offset+16, 16, ENC_ASCII|ENC_NA);
670 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hash_image, tvb, msg_offset+32, 32, ENC_NA);
671 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_zid, tvb, msg_offset+64, 12, ENC_NA);
672 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_sigcap, tvb, data_offset+0, 1, ENC_BIG_ENDIAN);
673 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_mitm, tvb, data_offset+0, 1, ENC_BIG_ENDIAN);
674 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_passive, tvb, data_offset+0, 1, ENC_BIG_ENDIAN);
676 val_b = tvb_get_guint8(tvb, data_offset+1);
677 hc = val_b & 0x0F;
678 vhc = hc;
680 val_b = tvb_get_guint8(tvb, data_offset+2);
681 cc = val_b & 0xF0;
682 ac = val_b & 0x0F;
683 vcc = cc >> 4;
684 vac = ac;
686 val_b = tvb_get_guint8(tvb, data_offset+3);
687 kc = val_b & 0xF0;
688 sc = val_b & 0x0F;
689 vkc = kc >> 4;
690 vsc = sc;
692 ti = proto_tree_add_uint_format(zrtp_tree, hf_zrtp_msg_hash_count, tvb, data_offset+1, 1, hc, "Hash type count = %d", vhc);
693 tmp_tree = proto_item_add_subtree(ti, ett_zrtp_msg_hc);
694 run_offset = data_offset+4;
695 for (i=0; i<vhc; i++) {
696 tvb_memcpy(tvb, (void *)value, run_offset, 4);
697 value[4] = '\0';
698 proto_tree_add_string_format(tmp_tree, hf_zrtp_msg_hash, tvb, run_offset, 4, value,
699 "Hash[%d]: %s", i, key_to_val(value, 4, zrtp_hash_type_vals, "Unknown hash type %s"));
700 run_offset += 4;
702 ti = proto_tree_add_uint_format(zrtp_tree, hf_zrtp_msg_cipher_count, tvb, data_offset+2, 1, cc, "Cipher type count = %d", vcc);
703 tmp_tree = proto_item_add_subtree(ti, ett_zrtp_msg_cc);
704 for (i=0; i<vcc; i++) {
705 tvb_memcpy(tvb, (void *)value, run_offset, 4);
706 value[4] = '\0';
707 proto_tree_add_string_format(tmp_tree, hf_zrtp_msg_cipher, tvb, run_offset, 4, value, "Cipher[%d]: %s", i,
708 key_to_val(value, 4, zrtp_cipher_type_vals, "Unknown cipher type %s"));
709 run_offset += 4;
711 ti = proto_tree_add_uint_format(zrtp_tree, hf_zrtp_msg_authtag_count, tvb, data_offset+2, 1, ac, "Auth tag count = %d", vac);
712 tmp_tree = proto_item_add_subtree(ti, ett_zrtp_msg_ac);
713 for (i=0; i<vac; i++) {
714 tvb_memcpy(tvb, (void *)value, run_offset, 4);
715 value[4] = '\0';
716 proto_tree_add_string_format(tmp_tree, hf_zrtp_msg_at, tvb, run_offset, 4, value,
717 "Auth tag[%d]: %s", i, key_to_val(value, 4, zrtp_auth_tag_vals, "Unknown auth tag %s"));
718 run_offset += 4;
720 ti = proto_tree_add_uint_format(zrtp_tree, hf_zrtp_msg_key_count, tvb, data_offset+3, 1, kc, "Key agreement type count = %d", vkc);
721 tmp_tree = proto_item_add_subtree(ti, ett_zrtp_msg_kc);
722 for (i=0; i<vkc; i++) {
723 tvb_memcpy(tvb, (void *)value, run_offset, 4);
724 value[4] = '\0';
725 proto_tree_add_string_format(tmp_tree, hf_zrtp_msg_keya, tvb, run_offset, 4, value,
726 "Key agreement[%d]: %s", i, key_to_val(value, 4, zrtp_key_agreement_vals, "Unknown key agreement %s"));
727 run_offset += 4;
729 ti = proto_tree_add_uint_format(zrtp_tree, hf_zrtp_msg_sas_count, tvb, data_offset+3, 1, sc, "SAS type count = %d", vsc);
730 tmp_tree = proto_item_add_subtree(ti, ett_zrtp_msg_sc);
731 for (i=0; i<vsc; i++) {
732 tvb_memcpy(tvb, (void *)value, run_offset, 4);
733 value[4] = '\0';
734 proto_tree_add_string_format(tmp_tree, hf_zrtp_msg_sas, tvb, run_offset, 4, value,
735 "SAS type[%d]: %s", i, key_to_val(value, 4, zrtp_sas_type_vals, "Unknown SAS type %s"));
736 run_offset += 4;
739 proto_tree_add_item(zrtp_tree, hf_zrtp_msg_hmac, tvb, run_offset, 8, ENC_NA);
742 void
743 proto_register_zrtp(void)
745 static hf_register_info hf[] = {
746 {&hf_zrtp_rtpversion,
748 "RTP Version", "zrtp.rtpversion",
749 FT_UINT8, BASE_DEC,
750 NULL, 0xC0,
751 NULL, HFILL
755 {&hf_zrtp_rtppadding,
757 "RTP padding", "zrtp.rtppadding",
758 FT_BOOLEAN, 8,
759 NULL, 0x20,
760 NULL, HFILL
764 {&hf_zrtp_rtpextension,
766 "RTP Extension", "zrtp.rtpextension",
767 FT_BOOLEAN, 8,
768 NULL, 0x10,
769 NULL, HFILL
773 #if 0
774 {&hf_zrtp_id,
776 "ID", "zrtp.id",
777 FT_UINT8, BASE_HEX,
778 NULL, 0x0,
779 NULL, HFILL
782 #endif
784 {&hf_zrtp_sequence,
786 "Sequence", "zrtp.sequence",
787 FT_UINT16, BASE_DEC,
788 NULL, 0x0,
789 NULL, HFILL
793 {&hf_zrtp_cookie,
795 "Magic Cookie", "zrtp.cookie",
796 FT_STRING, BASE_NONE,
797 NULL, 0x0,
798 NULL, HFILL
802 {&hf_zrtp_source_id,
804 "Source Identifier", "zrtp.source_id",
805 FT_UINT32, BASE_HEX,
806 NULL, 0x0,
807 NULL, HFILL
812 Message Types
814 {&hf_zrtp_signature,
816 "Signature", "zrtp.signature",
817 FT_UINT16, BASE_HEX,
818 NULL, 0x0,
819 NULL, HFILL
823 {&hf_zrtp_msg_length,
825 "Length", "zrtp.length",
826 FT_UINT16, BASE_DEC,
827 NULL, 0x0,
828 NULL, HFILL
832 {&hf_zrtp_msg_type,
834 "Type", "zrtp.type",
835 FT_STRING, BASE_NONE,
836 NULL, 0x0,
837 NULL, HFILL
841 {&hf_zrtp_msg_version,
843 "ZRTP protocol version", "zrtp.version",
844 FT_STRING, BASE_NONE,
845 NULL, 0x0,
846 NULL, HFILL
850 {&hf_zrtp_msg_client_id,
852 "Client Identifier", "zrtp.client_source_id",
853 FT_STRING, BASE_NONE,
854 NULL, 0x0,
855 NULL, HFILL
859 {&hf_zrtp_msg_hash_image,
861 "Hash Image", "zrtp.hash_image",
862 FT_BYTES, BASE_NONE,
863 NULL, 0x0,
864 NULL, HFILL
868 {&hf_zrtp_msg_zid,
870 "ZID", "zrtp.zid",
871 FT_BYTES, BASE_NONE,
872 NULL, 0x0,
873 NULL, HFILL
877 {&hf_zrtp_msg_sigcap,
879 "Sig.capable", "zrtp.sigcap",
880 FT_BOOLEAN, 8,
881 NULL, 0x40,
882 NULL, HFILL
886 {&hf_zrtp_msg_mitm,
888 "MiTM", "zrtp.mitm",
889 FT_BOOLEAN, 8,
890 NULL, 0x20,
891 NULL, HFILL
895 {&hf_zrtp_msg_passive,
897 "Passive", "zrtp.passive",
898 FT_BOOLEAN, 8,
899 NULL, 0x10,
900 NULL, HFILL
904 {&hf_zrtp_msg_hash_count,
906 "Hash Count", "zrtp.hc",
907 FT_UINT8, BASE_DEC,
908 NULL, 0x0F,
909 NULL, HFILL
913 {&hf_zrtp_msg_cipher_count,
915 "Cipher Count", "zrtp.cc",
916 FT_UINT8, BASE_DEC,
917 NULL, 0xF0,
918 NULL, HFILL
922 {&hf_zrtp_msg_authtag_count,
924 "Auth tag Count", "zrtp.ac",
925 FT_UINT8, BASE_DEC,
926 NULL, 0x0F,
927 NULL, HFILL
931 {&hf_zrtp_msg_key_count,
933 "Key Agreement Count", "zrtp.kc",
934 FT_UINT8, BASE_DEC,
935 NULL, 0xF0,
936 NULL, HFILL
940 {&hf_zrtp_msg_sas_count,
942 "SAS Count", "zrtp.sc",
943 FT_UINT8, BASE_DEC,
944 NULL, 0x0F,
945 NULL, HFILL
949 {&hf_zrtp_msg_hash,
951 "Hash", "zrtp.hash",
952 FT_STRING, BASE_NONE,
953 NULL, 0x0,
954 NULL, HFILL
958 {&hf_zrtp_msg_cipher,
960 "Cipher", "zrtp.cipher",
961 FT_STRING, BASE_NONE,
962 NULL, 0x0,
963 NULL, HFILL
967 {&hf_zrtp_msg_at,
969 "AT", "zrtp.at",
970 FT_STRING, BASE_NONE,
971 NULL, 0x0,
972 NULL, HFILL
976 {&hf_zrtp_msg_keya,
978 "Key Agreement", "zrtp.keya",
979 FT_STRING, BASE_NONE,
980 NULL, 0x0,
981 NULL, HFILL
985 {&hf_zrtp_msg_sas,
987 "SAS", "zrtp.sas",
988 FT_STRING, BASE_NONE,
989 NULL, 0x0,
990 NULL, HFILL
994 {&hf_zrtp_msg_rs1ID,
996 "rs1ID", "zrtp.rs1id",
997 FT_BYTES, BASE_NONE,
998 NULL, 0x0,
999 NULL, HFILL
1003 {&hf_zrtp_msg_rs2ID,
1005 "rs2ID", "zrtp.rs2id",
1006 FT_BYTES, BASE_NONE,
1007 NULL, 0x0,
1008 NULL, HFILL
1012 {&hf_zrtp_msg_auxs,
1014 "auxs", "zrtp.auxs",
1015 FT_BYTES, BASE_NONE,
1016 NULL, 0x0,
1017 NULL, HFILL
1021 {&hf_zrtp_msg_pbxs,
1023 "pbxs", "zrtp.pbxs",
1024 FT_BYTES, BASE_NONE,
1025 NULL, 0x0,
1026 NULL, HFILL
1030 {&hf_zrtp_msg_hmac,
1032 "HMAC", "zrtp.hmac",
1033 FT_BYTES, BASE_NONE,
1034 NULL, 0x0,
1035 NULL, HFILL
1039 {&hf_zrtp_msg_cfb,
1041 "CFB", "zrtp.cfb",
1042 FT_BYTES, BASE_NONE,
1043 NULL, 0x0,
1044 NULL, HFILL
1048 {&hf_zrtp_msg_error,
1050 "Error", "zrtp.error",
1051 FT_UINT32, BASE_DEC,
1052 VALS(zrtp_error_vals), 0x0,
1053 NULL, HFILL
1057 {&hf_zrtp_msg_ping_version,
1059 "Ping Version", "zrtp.ping_version",
1060 FT_STRING, BASE_NONE,
1061 NULL, 0x0,
1062 NULL, HFILL
1066 {&hf_zrtp_msg_ping_endpointhash,
1068 "Ping Endpoint Hash", "zrtp.ping_endpointhash",
1069 FT_UINT64, BASE_HEX,
1070 NULL, 0x0,
1071 NULL, HFILL
1075 {&hf_zrtp_msg_pingack_endpointhash,
1077 "PingAck Endpoint Hash", "zrtp.pingack_endpointhash",
1078 FT_UINT64, BASE_HEX,
1079 NULL, 0x0,
1080 NULL, HFILL
1084 {&hf_zrtp_msg_ping_ssrc,
1086 "Ping SSRC", "zrtp.ping_ssrc",
1087 FT_UINT32, BASE_HEX,
1088 NULL, 0x0,
1089 NULL, HFILL
1093 {&hf_zrtp_checksum,
1095 "Checksum", "zrtp.checksum",
1096 FT_UINT32, BASE_HEX,
1097 NULL, 0x0,
1098 NULL, HFILL
1102 {&hf_zrtp_checksum_good,
1104 "Good", "zrtp.checksum_good",
1105 FT_BOOLEAN, BASE_NONE,
1106 NULL, 0x0,
1107 "True: checksum matches packet content; False: doesn't match content", HFILL
1111 {&hf_zrtp_checksum_bad,
1113 "Bad", "zrtp.checksum_bad",
1114 FT_BOOLEAN, BASE_NONE,
1115 NULL, 0x0,
1116 "True: checksum doesn't match packet content; False: matches content", HFILL
1120 {&hf_zrtp_msg_hvi,
1122 "hvi", "zrtp.hvi",
1123 FT_BYTES, BASE_NONE,
1124 NULL, 0x0,
1125 NULL, HFILL
1129 {&hf_zrtp_msg_nonce,
1131 "nonce", "zrtp.nonce",
1132 FT_BYTES, BASE_NONE,
1133 NULL, 0x0,
1134 NULL, HFILL
1138 {&hf_zrtp_msg_key_id,
1140 "key ID", "zrtp.key_id",
1141 FT_BYTES, BASE_NONE,
1142 NULL, 0x0,
1143 NULL, HFILL
1148 static gint *ett[] = {
1149 &ett_zrtp,
1150 &ett_zrtp_msg,
1151 &ett_zrtp_msg_data,
1152 &ett_zrtp_msg_hc,
1153 &ett_zrtp_msg_kc,
1154 &ett_zrtp_msg_ac,
1155 &ett_zrtp_msg_cc,
1156 &ett_zrtp_msg_sc,
1157 &ett_zrtp_checksum
1160 proto_zrtp = proto_register_protocol("ZRTP", "ZRTP", "zrtp");
1161 proto_register_field_array(proto_zrtp, hf, array_length(hf));
1162 proto_register_subtree_array(ett, array_length(ett));
1163 register_dissector("zrtp", dissect_zrtp, proto_zrtp);
1166 void
1167 proto_reg_handoff_zrtp(void)
1169 dissector_handle_t zrtp_handle;
1171 zrtp_handle = find_dissector("zrtp");
1172 dissector_add_handle("udp.port", zrtp_handle);