Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-fc00.c
blob4484000163b90c0368b472412e56725e645b0357
1 /* packet-fc00.c
2 * Routines for fc00/cjdns dissection
3 * Copyright 2015, Emery Hemingway <emery@v36.spacet>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * https://github.com/hyperboria/cjdns
16 #include <config.h>
18 #include <epan/expert.h>
19 #include <epan/packet.h>
20 #include <wsutil/base32.h>
22 /* Prototypes */
23 /* (Required to prevent [-Wmissing-prototypes] warnings */
24 void proto_reg_handoff_fc00(void);
25 void proto_register_fc00(void);
27 static dissector_handle_t fc00_handle;
29 /* Initialize the protocol and registered fields */
30 static int proto_fc00;
31 static int hf_fc00_session_state;
32 static int hf_fc00_session_nonce;
33 static int hf_fc00_auth_challenge;
34 static int hf_fc00_auth_type;
35 static int hf_fc00_auth_hash_code;
36 static int hf_fc00_auth_poly;
37 static int hf_fc00_auth_derivations;
38 static int hf_fc00_auth_additional;
39 static int hf_fc00_random_nonce;
40 static int hf_fc00_public_key;
41 static int hf_fc00_ip_address;
42 static int hf_fc00_authenticator;
43 static int hf_fc00_temp_publicy_key;
44 static int hf_fc00_payload;
46 /* Cjdns constants */
47 #define SESSION_STATE_OFF 0
48 #define SESSION_STATE_LEN 4
49 #define CHALLENGE_OFF 4
50 #define CHALLENGE_LEN 12
51 #define NONCE_OFF 16
52 #define NONCE_LEN 24
53 #define PUBLIC_KEY_OFF 40
54 #define PUBLIC_KEY_LEN 32
55 #define POLY_AUTH_OFF 72
56 #define POLY_AUTH_LEN 16
57 #define TEMP_KEY_OFF 88
58 #define TEMP_KEY_LEN 32
59 #define CRYPTO_HEADER_LEN 120
61 /* Initialize the subtree pointers */
62 static int ett_fc00;
63 static int ett_fc00_auth;
64 static int ett_fc00_key;
66 static const value_string session_states[] = {
67 { UINT32_MAX, "Connect To Me" },
68 { 0, "Hello" },
69 { 1, "Hello" },
70 { 2, "repeated Hello" },
71 { 3, "Key" },
72 { 4, "repeated Key" },
73 { 0, NULL }
76 /* Code to actually dissect the packets */
77 static int
78 dissect_cryptoauth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
80 uint32_t session_state;
81 proto_item *ti = NULL;
82 proto_tree *fc00_tree = NULL;
83 unsigned payload_len = 0;
85 col_set_str(pinfo->cinfo, COL_PROTOCOL, "fc00");
86 col_clear(pinfo->cinfo, COL_INFO);
88 session_state = tvb_get_ntohl(tvb, SESSION_STATE_OFF);
90 if ((session_state > 3) && (session_state < UINT32_MAX)) {
91 ti = proto_tree_add_item(tree, proto_fc00, tvb, 0, SESSION_STATE_LEN, ENC_NA);
92 fc00_tree = proto_item_add_subtree(ti, ett_fc00);
93 proto_tree_add_item(fc00_tree, hf_fc00_session_nonce, tvb,
94 SESSION_STATE_OFF, SESSION_STATE_LEN, ENC_BIG_ENDIAN);
96 payload_len = tvb_reported_length(tvb)-SESSION_STATE_LEN;
98 proto_tree_add_item(fc00_tree, hf_fc00_payload, tvb,
99 SESSION_STATE_LEN, payload_len, ENC_NA);
101 return SESSION_STATE_LEN;
104 ti = proto_tree_add_item(tree, proto_fc00, tvb, 0, 120, ENC_NA);
105 fc00_tree = proto_item_add_subtree(ti, ett_fc00);
107 proto_tree_add_item(fc00_tree, hf_fc00_session_state, tvb,
108 SESSION_STATE_OFF, SESSION_STATE_LEN, ENC_NA);
110 ti = proto_tree_add_item(fc00_tree, hf_fc00_auth_challenge, tvb,
111 CHALLENGE_OFF, CHALLENGE_LEN, ENC_NA);
113 proto_tree *auth_tree = proto_item_add_subtree(ti, ett_fc00_auth);
114 proto_tree_add_item(auth_tree, hf_fc00_auth_type, tvb, CHALLENGE_OFF, 1, ENC_NA);
115 proto_tree_add_item(auth_tree, hf_fc00_auth_hash_code, tvb, CHALLENGE_OFF+1, 7, ENC_NA);
116 proto_tree_add_item(auth_tree, hf_fc00_auth_poly, tvb, CHALLENGE_OFF+8, 1, ENC_NA);
117 proto_tree_add_item(auth_tree, hf_fc00_auth_derivations, tvb, CHALLENGE_OFF+8, 2, ENC_NA);
118 proto_tree_add_item(auth_tree, hf_fc00_auth_additional, tvb, CHALLENGE_OFF+10, 2, ENC_NA);
121 proto_tree_add_item(fc00_tree, hf_fc00_random_nonce, tvb,
122 NONCE_OFF, NONCE_LEN, ENC_NA);
124 if (fc00_tree)
126 GChecksum *hash = g_checksum_new(G_CHECKSUM_SHA512);
127 size_t digest_len = g_checksum_type_get_length(G_CHECKSUM_SHA512);
128 proto_tree *key_tree;
130 uint8_t *raw_key = (uint8_t*)wmem_alloc(pinfo->pool, PUBLIC_KEY_LEN);
131 char *encoded_key = (char*)wmem_alloc(pinfo->pool, 53);
132 uint8_t *ip_buf = (uint8_t*)wmem_alloc(pinfo->pool, digest_len);
134 tvb_memcpy(tvb, raw_key, PUBLIC_KEY_OFF, PUBLIC_KEY_LEN);
136 ws_base32_decode((uint8_t*)encoded_key, 53, raw_key, PUBLIC_KEY_LEN);
138 g_checksum_update(hash, (unsigned char*)raw_key, PUBLIC_KEY_LEN);
139 g_checksum_get_digest(hash, ip_buf, &digest_len);
140 g_checksum_free(hash);
142 hash = g_checksum_new(G_CHECKSUM_SHA512);
143 g_checksum_update(hash, (unsigned char*)ip_buf, digest_len);
144 g_checksum_get_digest(hash, ip_buf, &digest_len);
145 g_checksum_free(hash);
147 ti = proto_tree_add_none_format(fc00_tree, hf_fc00_public_key, tvb, PUBLIC_KEY_OFF, PUBLIC_KEY_LEN, "Public Key: %s.k", encoded_key);
149 key_tree = proto_item_add_subtree(ti, ett_fc00_key);
151 proto_tree_add_ipv6(key_tree, hf_fc00_ip_address, tvb, PUBLIC_KEY_OFF, PUBLIC_KEY_LEN, (ws_in6_addr*)ip_buf);
154 proto_tree_add_item(fc00_tree, hf_fc00_authenticator, tvb,
155 POLY_AUTH_OFF, POLY_AUTH_LEN, ENC_NA);
157 proto_tree_add_item(fc00_tree, hf_fc00_temp_publicy_key, tvb,
158 TEMP_KEY_OFF, TEMP_KEY_LEN, ENC_NA);
160 payload_len = tvb_reported_length(tvb)-(TEMP_KEY_OFF+TEMP_KEY_LEN);
162 proto_tree_add_item(fc00_tree, hf_fc00_payload, tvb,
163 CRYPTO_HEADER_LEN, payload_len, ENC_NA);
165 return tvb_captured_length(tvb);
168 /* Register the protocol with Wireshark.
170 void
171 proto_register_fc00(void)
173 static hf_register_info hf[] = {
174 { &hf_fc00_session_state,
175 { "Session State", "fc00.session_state",
176 FT_UINT32, BASE_DEC, VALS(session_states), 0x0,
177 NULL, HFILL }
180 { &hf_fc00_session_nonce,
181 { "Session Nonce", "fc00.session_nonce",
182 FT_UINT32, BASE_DEC, NULL, 0x0,
183 NULL, HFILL }
186 { &hf_fc00_auth_challenge,
187 { "Auth Challenge", "fc00.auth_challenge",
188 FT_BYTES, BASE_NONE, NULL, 0x0,
189 NULL, HFILL }
192 { &hf_fc00_auth_type,
193 { "Auth Type", "fc00.auth_challenge.type",
194 FT_UINT8, BASE_DEC, NULL, 0x0,
195 NULL, HFILL }
198 { &hf_fc00_auth_hash_code,
199 { "Auth Hash Code", "fc00.auth_challenge.hash_code",
200 FT_BYTES, BASE_NONE, NULL, 0x0,
201 NULL, HFILL }
204 { &hf_fc00_auth_poly,
205 { "Poly1305 Authentication", "fc00.auth_challenge.poly1305",
206 FT_UINT8, BASE_DEC, NULL, 0x80,
207 NULL, HFILL }
210 { &hf_fc00_auth_derivations,
211 { "Auth Derivations", "fc00.auth_challenge.derivations",
212 FT_UINT16, BASE_DEC, NULL, 0x7F,
213 NULL, HFILL }
216 { &hf_fc00_auth_additional,
217 { "Auth Additional", "fc00.auth_challenge.additional",
218 FT_UINT16, BASE_HEX, NULL, 0x0,
219 NULL, HFILL }
222 { &hf_fc00_random_nonce,
223 { "Random Nonce", "fc00.random_nonce",
224 FT_BYTES, BASE_NONE, NULL, 0x0,
225 NULL, HFILL }
228 { &hf_fc00_public_key,
229 { "Permanent Public Key", "fc00.public_key",
230 FT_NONE, BASE_NONE, NULL, 0x0,
231 "Base32 encoded public key", HFILL }
234 { &hf_fc00_ip_address,
235 { "IPv6 Address", "fc00.ip",
236 FT_IPv6, BASE_NONE, NULL, 0x0,
237 "Double SHA256 hash of public key", HFILL }
240 { &hf_fc00_authenticator,
241 { "Poly1305 Authenticator", "fc00.authenticator",
242 FT_BYTES, BASE_NONE, NULL, 0x0,
243 NULL, HFILL }
246 { &hf_fc00_temp_publicy_key,
247 { "Encrypted/Authenticated Temporary Public Key",
248 "fc00.temp_key",
249 FT_BYTES, BASE_NONE, NULL, 0x0,
250 NULL, HFILL }
253 { &hf_fc00_payload,
254 { "Encrypted Payload", "fc00.payload",
255 FT_BYTES, BASE_NONE, NULL, 0x0,
256 NULL, HFILL }
260 static int *ett[] = {
261 &ett_fc00,
262 &ett_fc00_auth,
263 &ett_fc00_key
266 proto_fc00 = proto_register_protocol("Fc00 CryptoAuth", "Fc00", "fc00");
268 proto_register_field_array(proto_fc00, hf, array_length(hf));
269 proto_register_subtree_array(ett, array_length(ett));
271 fc00_handle = register_dissector("fc00", dissect_cryptoauth, proto_fc00);
274 void
275 proto_reg_handoff_fc00(void)
277 dissector_add_for_decode_as_with_preference("udp.port", fc00_handle);
281 * Editor modelines - https://www.wireshark.org/tools/modelines.html
283 * Local variables:
284 * c-basic-offset: 4
285 * tab-width: 8
286 * indent-tabs-mode: nil
287 * End:
289 * vi: set shiftwidth=4 tabstop=8 expandtab:
290 * :indentSize=4:tabSize=8:noTabs=true: