Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / plugins / epan / opcua / opcua.c
blob5872a207bcc392ecf58df36f03e55e525f9612ce
1 /******************************************************************************
2 ** Copyright (C) 2006-2007 ascolab GmbH. All Rights Reserved.
3 ** Web: http://www.ascolab.com
4 **
5 ** SPDX-License-Identifier: GPL-2.0-or-later
6 **
7 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
8 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
9 **
10 ** Project: OpcUa Wireshark Plugin
12 ** Description: OpcUa Protocol Decoder.
14 ** Author: Gerhard Gappmeier <gerhard.gappmeier@ascolab.com>
15 ******************************************************************************/
17 #include <epan/dissectors/packet-tcp.h>
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
20 #include <epan/range.h>
21 #include <epan/reassemble.h>
22 #include <epan/secrets.h>
23 #include <epan/tvbuff.h>
24 #include <gcrypt.h>
25 #include <wiretap/secrets-types.h>
26 #include <wsutil/file_util.h>
28 #include "config.h"
29 #include "opcua_application_layer.h"
30 #include "opcua_complextypeparser.h"
31 #include "opcua_enumparser.h"
32 #include "opcua_hfindeces.h"
33 #include "opcua_keyset.h"
34 #include "opcua_security_layer.h"
35 #include "opcua_serviceparser.h"
36 #include "opcua_serviceids.h"
37 #include "opcua_simpletypes.h"
38 #include "opcua_transport_layer.h"
40 void proto_register_opcua(void);
42 extern const value_string g_requesttypes[];
43 extern const int g_NumServices;
44 static const char *g_opcua_debug_file_name;
45 int g_opcua_default_sig_len;
47 /* forward reference */
48 void proto_reg_handoff_opcua(void);
49 /* declare parse function pointer */
50 typedef int (*FctParse)(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int *pOffset, struct ua_metadata *data);
52 int proto_opcua;
53 static dissector_handle_t opcua_handle;
54 static module_t *opcua_module;
56 /* #define OPCUA_DEBUG */
57 #ifdef OPCUA_DEBUG
58 # define debugprintf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__);
59 #else
60 # define debugprintf(fmt, ...)
61 #endif
63 /** Official IANA registered port for OPC UA Binary Protocol. */
64 #define OPCUA_DEFAULT_PORT 4840
65 /* default port range for preferences */
66 #define OPCUA_PORT_RANGE "4840"
67 /** header length that is needed to compute the pdu length.
68 * @see get_opcua_message_len
70 #define FRAME_HEADER_LEN 8
71 /* AES block size: for both AES128 and AES256 the block size is 128 bits */
72 #define AES_BLOCK_SIZE 16
74 /** subtree types used in opcua_transport_layer.c */
75 int ett_opcua_extensionobject;
76 int ett_opcua_nodeid;
78 /** subtree types used locally */
79 static int ett_opcua_transport;
80 static int ett_opcua_fragment;
81 static int ett_opcua_fragments;
83 static int hf_opcua_fragments;
84 static int hf_opcua_fragment;
85 static int hf_opcua_fragment_overlap;
86 static int hf_opcua_fragment_overlap_conflicts;
87 static int hf_opcua_fragment_multiple_tails;
88 static int hf_opcua_fragment_too_long_fragment;
89 static int hf_opcua_fragment_error;
90 static int hf_opcua_fragment_count;
91 static int hf_opcua_reassembled_in;
92 static int hf_opcua_reassembled_length;
94 static const fragment_items opcua_frag_items = {
95 /* Fragment subtrees */
96 &ett_opcua_fragment,
97 &ett_opcua_fragments,
98 /* Fragment fields */
99 &hf_opcua_fragments,
100 &hf_opcua_fragment,
101 &hf_opcua_fragment_overlap,
102 &hf_opcua_fragment_overlap_conflicts,
103 &hf_opcua_fragment_multiple_tails,
104 &hf_opcua_fragment_too_long_fragment,
105 &hf_opcua_fragment_error,
106 &hf_opcua_fragment_count,
107 /* Reassembled in field */
108 &hf_opcua_reassembled_in,
109 /* Reassembled length field */
110 &hf_opcua_reassembled_length,
111 /* Reassembled data field */
112 NULL,
113 /* Tag */
114 "Message fragments"
117 static reassembly_table opcua_reassembly_table;
119 /** OpcUa Transport Message Types */
120 enum MessageType
122 MSG_HELLO = 0,
123 MSG_ACKNOWLEDGE,
124 MSG_ERROR,
125 MSG_REVERSEHELLO,
126 MSG_MESSAGE,
127 MSG_OPENSECURECHANNEL,
128 MSG_CLOSESECURECHANNEL,
129 MSG_INVALID
132 /** OpcUa Transport Message Type Names */
133 static const char* g_szMessageTypes[] =
135 "Hello message",
136 "Acknowledge message",
137 "Error message",
138 "Reverse Hello message",
139 "UA Secure Conversation Message",
140 "OpenSecureChannel message",
141 "CloseSecureChannel message",
142 "Invalid message"
145 static const enum_val_t opcua_sig_len_enum[] = {
146 { "None", "Unsigned", 0 },
147 { "20", "20 Bytes", 20 },
148 { "32", "32 Bytes", 32 },
149 { NULL, NULL, 0 }
152 #ifdef _MSC_VER
153 static char *ua_strtok_r(char *str, const char *delim, char **saveptr)
155 /* use MSVC specific strtok_s */
156 return strtok_s(str, delim, saveptr);
158 #else
159 static char *ua_strtok_r(char *str, const char *delim, char **saveptr)
161 /* use POSIX strtok_r */
162 return strtok_r(str, delim, saveptr);
164 #endif
166 /** returns the length of an OpcUa message.
167 * This function reads the length information from
168 * the transport header.
170 static unsigned get_opcua_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
171 int offset, void *data _U_)
173 int32_t plen;
175 /* the message length starts at offset 4 */
176 plen = tvb_get_letohl(tvb, offset + 4);
178 return plen;
181 /* Helper function to convert hex string to binary data */
182 unsigned hex_to_bin(const char *hex_string, unsigned char *binary_data, unsigned int binary_size)
184 unsigned length = (unsigned)strlen(hex_string);
185 unsigned i;
187 for (i = 0; i < length / 2 && i < binary_size; ++i) {
188 sscanf(hex_string + 2 * i, "%2hhx", &binary_data[i]);
191 return i;
194 /** Parsing context */
195 struct opcua_keylog_parser_ctx {
196 struct ua_keyset *keyset; /**< current keyset */
197 uint64_t last_id; /**< the id of the previous line, this is also the id of the keyset */
201 * Common function for parsing key log line used by opcua_keylog_process_lines and opcua_load_keylog_file.
203 * @param ctx Parsing context.
204 * @param line Current line to parse.
206 static void opcua_keylog_process_line(struct opcua_keylog_parser_ctx *ctx, const char *line)
208 struct ua_keyset *keyset;
209 char key[33]; /* 32 chars + null terminator */
210 char value[65]; /* 64 hex chars + null terminator */
211 const char *parts[4]; /* for string split */
212 unsigned int num_parts;
213 char *tmp, *saveptr;
214 uint32_t token_id = 0;
215 uint32_t channel_id = 0;
216 uint64_t id = 0;
217 int n;
219 /* parse key/value pair */
220 n = sscanf(line, "%32[^:]: %64s\n", key, value);
221 if (n != 2) return;
223 debugprintf("%s = %s\n", key, value);
225 /* split key into parts */
226 num_parts = 0;
227 tmp = ua_strtok_r(key, "_", &saveptr);
228 while (tmp && num_parts < 4) {
229 parts[num_parts++] = tmp;
230 tmp = ua_strtok_r(NULL, "_", &saveptr);
232 if (num_parts != 4) return; /* skip invalid enty */
233 channel_id = (uint32_t)strtoul(parts[2], NULL, 10);
234 token_id = (uint32_t)strtoul(parts[3], NULL, 10);
236 debugprintf("channel_id = %u\n", channel_id);
237 debugprintf("token_id = %u\n", token_id);
239 /* create unique keyset id */
240 id = ua_keyset_id(channel_id, token_id);
242 if (ctx->keyset == NULL || id != ctx->last_id) {
243 debugprintf("Adding new keyset for id %lu...\n", id);
244 /* create new keyset for new id */
245 ctx->keyset = ua_keysets_add();
246 ctx->last_id = id;
248 keyset = ctx->keyset;
249 if (keyset) {
250 keyset->id = id;
251 /* store key material */
252 if (strcmp(parts[0], "client") == 0) {
253 if (strcmp(parts[1], "iv") == 0) {
254 hex_to_bin(value, keyset->client_iv, sizeof(keyset->client_iv));
255 } else if (strcmp(parts[1], "key") == 0) {
256 keyset->client_key_len = (unsigned int)hex_to_bin(value, keyset->client_key, sizeof(keyset->client_key));
257 } else if (strcmp(parts[1], "siglen") == 0) {
258 keyset->client_sig_len = (unsigned int)strtoul(value, NULL, 10);
260 } else if (strcmp(parts[0], "server") == 0) {
261 if (strcmp(parts[1], "iv") == 0) {
262 hex_to_bin(value, keyset->server_iv, sizeof(keyset->server_iv));
263 } else if (strcmp(parts[1], "key") == 0) {
264 keyset->server_key_len = (unsigned int)hex_to_bin(value, keyset->server_key, sizeof(keyset->server_key));
265 } else if (strcmp(parts[1], "siglen") == 0) {
266 keyset->server_sig_len = (unsigned int)strtoul(value, NULL, 10);
273 * Parses key log data from PCAP file.
274 * This function splits the data by \n and calls opcua_keylog_process_line.
276 static void opcua_keylog_process_lines(char *data)
278 struct opcua_keylog_parser_ctx ctx = { NULL, 0 };
279 char *saveptr;
280 const char *line = ua_strtok_r(data, "\n", &saveptr);
282 while (line) {
283 opcua_keylog_process_line(&ctx, line);
284 line = ua_strtok_r(NULL, "\n", &saveptr);
287 /* sort data by id to make lookup working */
288 ua_keysets_sort();
292 * Loads the configured OPCUA Keylog file.
294 static void opcua_load_keylog_file(const char *filename)
296 struct opcua_keylog_parser_ctx ctx = { NULL, 0 };
297 char line[256];
299 debugprintf("Loading key file '%s'...\n", filename);
300 FILE *f = ws_fopen(filename, "r");
301 if (f == NULL) {
302 debugprintf("error: '%s' not found\n", filename);
303 return;
306 /* parse file contents */
307 while (fgets(line, sizeof(line), f)) {
308 opcua_keylog_process_line(&ctx, line);
310 fclose(f);
312 /* sort data by id to make lookup working */
313 ua_keysets_sort();
317 * Checks the padding of a symetric signed message.
318 * A message always contains a padding_len byte, which tells us the length of
319 * the padding. All following padding bytes contain the same value. This makes it
320 * possible the padding from the end of the message.
321 * Example Paddings:
322 * - 00
323 * - 01 01
324 * - 02 02 02
325 * @param padding Pointer to last padding byte.
326 * @return padding length on success, -1 if the paddding is invalid.
328 static int verify_padding(const uint8_t *padding)
330 uint8_t pad_len;
331 uint8_t i;
333 pad_len = *padding;
335 for (i = 0; i < pad_len; ++i) {
336 if (padding[-pad_len + i] != pad_len) return -1;
339 return pad_len;
342 * Gets security footer info.
344 * @param channel_id SecureChannelId for keyset lookup.
345 * @param token_id TokenId for keyset lookup.
346 * @param sig_len Returns the length of the signature.
347 * @param from_server True of the message is sent from the server, false when sent from the client.
349 * @return Returns 0 on success, -1 if parsing failed.
351 static int opcua_get_footer_info(uint32_t channel_id, uint32_t token_id, uint8_t *sig_len, bool from_server)
353 struct ua_keyset *keyset;
354 uint64_t id;
356 id = ua_keyset_id(channel_id, token_id);
358 /* try to get correct signature length from key log file */
359 keyset = ua_keysets_lookup(id);
360 if (keyset) {
361 /* The Client keys are used to secure Messages sent by the Client. The Server keys are used to
362 * secure Messages sent by the Server.
364 if (from_server) {
365 *sig_len = keyset->server_sig_len;
366 } else {
367 *sig_len = keyset->client_sig_len;
371 debugprintf("no keyset found for channel_id=%u and token_id=%u\n", channel_id, token_id);
372 /* we use sig_len set from OpenSecurehChannel Policy in this case.
373 * this requires to have the OPN in the capture file, otherwise we are out of luck.
376 return 0;
380 * This function to perform AES decryption on service data in-place.
381 * Add also determines the payload length by removing the padding and signature.
383 * @param channel_id SecureChannelId for keyset lookup.
384 * @param token_id TokenId for keyset lookup.
385 * @param cipher The cipher text.
386 * @param cipher_len The cipher test length in bytes.
387 * @param plaintext The plaintext to return.
388 * @param plaintext_len The plaintext in bytes, should be the same as cipher_len.
389 * @param padding_len Returns the length of the padding.
390 * @param sig_len Returns the length of the signature.
391 * @param from_server True of the message is sent from the server, false when sent from the client.
393 * @return Returns 0 on success, -1 if decryption failed.
395 static int decrypt_opcua(
396 uint32_t channel_id, uint32_t token_id,
397 const uint8_t *cipher, unsigned cipher_len,
398 uint8_t *plaintext, unsigned plaintext_len,
399 uint8_t *padding_len, uint8_t *sig_len, bool from_server)
401 struct ua_keyset *keyset;
402 uint64_t id;
403 unsigned int keylen, ivlen;
404 unsigned char *keydata, *ivdata;
405 int cipher_mode;
406 gcry_error_t res;
407 int ret = 0;
409 id = ua_keyset_id(channel_id, token_id);
411 keyset = ua_keysets_lookup(id);
412 if (keyset == NULL) {
413 debugprintf("no keyset found for channel_id=%u and token_id=%u\n", channel_id, token_id);
414 /* col_append_fstr(pinfo->cinfo, COL_INFO, " (encrypted)"); */
415 return -1;
417 debugprintf("found keyset for channel_id=%u and token_id=%u\n", channel_id, token_id);
419 /* The Client keys are used to secure Messages sent by the Client. The Server keys are used to
420 * secure Messages sent by the Server.
422 if (from_server) {
423 ivlen = sizeof(keyset->server_iv);
424 ivdata = keyset->server_iv;
425 keylen = keyset->server_key_len;
426 keydata = keyset->server_key;
427 *sig_len = keyset->server_sig_len;
428 } else {
429 ivlen = sizeof(keyset->client_iv);
430 ivdata = keyset->client_iv;
431 keylen = keyset->client_key_len;
432 keydata = keyset->client_key;
433 *sig_len = keyset->client_sig_len;
435 /* derive AES mode from key length */
436 switch (keylen) {
437 case 16:
438 debugprintf("using AES-128-CBC\n");
439 cipher_mode = GCRY_CIPHER_AES128;
440 break;
441 case 32:
442 debugprintf("using AES-256-CBC\n");
443 cipher_mode = GCRY_CIPHER_AES256;
444 break;
445 default:
446 debugprintf("invalid AES key length: %u bytes\n", keylen);
447 /* col_append_fstr(pinfo->cinfo, COL_INFO, " (encrypted)"); */
448 return -1;
451 debugprintf("cipher_len=%u\n", cipher_len);
452 if (cipher_len % 16 != 0) {
453 debugprintf("warning: cipher_len not a multiple of 16.\n");
456 gcry_cipher_hd_t handle;
457 gcry_cipher_open(&handle, cipher_mode, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
458 gcry_cipher_setkey(handle, keydata, keylen);
459 gcry_cipher_setiv(handle, ivdata, ivlen);
461 /* Decrypt the data in-place */
462 res = gcry_cipher_decrypt(handle, plaintext, plaintext_len, cipher, cipher_len);
463 if (res == 0) {
464 /* col_append_fstr(pinfo->cinfo, COL_INFO, " (decrypted)"); */
465 debugprintf("decryption succeeded.\n");
466 } else {
467 /* col_append_fstr(pinfo->cinfo, COL_INFO, " (encrypted)"); */
468 debugprintf("decryption failed.\n");
469 ret = -1;
471 gcry_cipher_close(handle);
472 /* it makes no sense to continue and verify the padding if decryption failed */
473 if (ret != 0) {
474 return ret;
477 ret = verify_padding(&plaintext[plaintext_len - *sig_len - 1]);
478 if (ret < 0) {
479 debugprintf("padding is invalid.\n");
482 /* return padding length */
483 *padding_len = plaintext[plaintext_len - *sig_len - 1];
484 debugprintf("sig_len=%u\n", *sig_len);
485 debugprintf("pad_len=%u\n", *padding_len);
487 return 0;
490 /** The OpcUa message dissector.
491 * This method dissects full OpcUa messages.
492 * It gets only called with reassembled data
493 * from tcp_dissect_pdus.
495 static int dissect_opcua_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
497 FctParse pfctParse = NULL;
498 enum MessageType msgtype = MSG_INVALID;
499 uint16_t src_port = pinfo->srcport;
500 range_t *port_range;
501 bool from_server = false;
502 bool decrypted = false; /* successfully decrypted secure message */
503 enum ua_message_mode mode = UA_MessageMode_None;
504 uint8_t sig_len = 0;
505 struct ua_metadata metadata;
506 tvbuff_t *decrypted_tvb = NULL;
507 int ret;
509 /* determine if telegram is from server or from client by checking the port number */
510 if (src_port == OPCUA_DEFAULT_PORT) {
511 from_server = true;
512 } else {
513 port_range = prefs_get_range_value("opcua", "tcp.port");
514 if (port_range && value_is_in_range(port_range, src_port)) {
515 from_server = true;
519 metadata.encrypted = false;
520 get_encryption_info(pinfo, &mode, &sig_len);
522 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OpcUa");
525 /* parse message type */
526 if (tvb_memeql(tvb, 0, (const uint8_t * )"HEL", 3) == 0)
528 msgtype = MSG_HELLO;
529 pfctParse = parseHello;
531 else if (tvb_memeql(tvb, 0, (const uint8_t*)"ACK", 3) == 0)
533 msgtype = MSG_ACKNOWLEDGE;
534 pfctParse = parseAcknowledge;
536 else if (tvb_memeql(tvb, 0, (const uint8_t*)"ERR", 3) == 0)
538 msgtype = MSG_ERROR;
539 pfctParse = parseError;
541 else if (tvb_memeql(tvb, 0, (const uint8_t*)"RHE", 3) == 0)
543 msgtype = MSG_REVERSEHELLO;
544 pfctParse = parseReverseHello;
546 else if (tvb_memeql(tvb, 0, (const uint8_t*)"MSG", 3) == 0)
548 msgtype = MSG_MESSAGE;
549 pfctParse = parseMessage;
551 else if (tvb_memeql(tvb, 0, (const uint8_t*)"OPN", 3) == 0)
553 msgtype = MSG_OPENSECURECHANNEL;
554 pfctParse = parseOpenSecureChannel;
556 else if (tvb_memeql(tvb, 0, (const uint8_t*)"CLO", 3) == 0)
558 msgtype = MSG_CLOSESECURECHANNEL;
559 pfctParse = parseCloseSecureChannel;
561 else
563 msgtype = MSG_INVALID;
565 /* Clear out stuff in the info column */
566 col_set_str(pinfo->cinfo, COL_INFO, g_szMessageTypes[msgtype]);
568 /* add empty item to make filtering by 'opcua' work */
569 proto_tree_add_item(tree, proto_opcua, tvb, 0, -1, ENC_NA);
571 return tvb_reported_length(tvb);
574 /* Clear out stuff in the info column */
575 col_set_str(pinfo->cinfo, COL_INFO, g_szMessageTypes[msgtype]);
577 if (pfctParse)
579 int offset = 0;
580 int iServiceId = -1;
581 bool bParseService = false; /* Only MSG, OPN and CLO have a service payload */
582 bool bIsFinalChunk = false;
583 unsigned payload_len = 0;
584 uint8_t pad_len = 0;
586 /* we are being asked for details */
587 proto_item *ti = NULL;
588 proto_tree *transport_tree = NULL;
590 ti = proto_tree_add_item(tree, proto_opcua, tvb, 0, -1, ENC_NA);
591 transport_tree = proto_item_add_subtree(ti, ett_opcua_transport);
593 /* call the transport message dissector */
594 (*pfctParse)(transport_tree, tvb, pinfo, &offset, &metadata);
596 /* MSG_MESSAGE and MSG_CLOSESECURECHANNEL can be decrypted.
597 * Also handle chunked message reassembly for MSG_MESSAGE.
599 if (msgtype == MSG_MESSAGE || msgtype == MSG_CLOSESECURECHANNEL)
601 uint8_t chunkType = 0;
602 uint32_t opcua_seqno = 0; /* OPCUA sequence number */
603 uint32_t opcua_reqid = 0; /* OPCUA request id */
604 fragment_head *frag_msg = NULL;
606 bParseService = true;
607 offset = 3;
608 chunkType = tvb_get_uint8(tvb, offset); offset += 1;
609 offset += 4; /* message size */
610 offset += 4; /* skip secure channel_id */
611 parseSecurityHeader(transport_tree, tvb, &offset, &metadata); /* only token_id (4 byte) */
613 if (mode == UA_MessageMode_MaybeEncrypted) {
614 /* try to parse ServiceId */
615 iServiceId = getServiceNodeId(tvb, offset + 8); /* skip 4 byte SeqNo and 4 byte RequestId */
616 const char *szServiceName = val_to_str((uint32_t)iServiceId, g_requesttypes, "not found");
617 if (strcmp(szServiceName, "not found") == 0) {
618 mode = UA_MessageMode_SignAndEncrypt;
619 } else {
620 mode = UA_MessageMode_Sign;
622 store_encryption_info(pinfo, mode, sig_len);
625 /* Message Structure:
626 * +-----------------+
627 * / | Message Header | MSGF, MessageSize
628 * | +-----------------+
629 * | | Security Header | SecureChannelId, TokenId
630 * | +-----------------+
631 * Signed < | Sequence Header | \ SequenceNumber, RequestId
632 * | +-----------------+ |
633 * | | Body | |
634 * | +-----------------+ > Encrypted
635 * \ | Padding | |
636 * +-----------------+ |
637 * | Signature | /
638 * +-----------------+
640 if (mode == UA_MessageMode_SignAndEncrypt) {
641 uint32_t channel_id = tvb_get_letohl(tvb, 8);
642 uint32_t token_id = tvb_get_letohl(tvb, 12);
643 unsigned cipher_len = tvb_ensure_captured_length_remaining(tvb, 16);
644 unsigned plaintext_len = cipher_len;
645 const uint8_t *cipher = tvb_get_ptr(tvb, 16, (int)cipher_len);
646 unsigned char *plaintext = (unsigned char*)wmem_alloc(pinfo->pool, plaintext_len);
648 ret = decrypt_opcua(channel_id, token_id, cipher, cipher_len, plaintext, plaintext_len, &pad_len, &sig_len, from_server);
649 if (ret == 0) {
650 /* decrypted */
651 /* to get the payload length we need to subtract the sequence header (8) byte,
652 * the padding (paddin_len+1), and the signature from the plaintext */
653 payload_len = plaintext_len - pad_len - sig_len - 9; /* pad_len 2 = 02 02 02 */
654 /* Now re-setup the tvb buffer to have the new data */
655 decrypted_tvb = tvb_new_child_real_data(tvb, plaintext, (unsigned)plaintext_len, (int)plaintext_len);
656 add_new_data_source(pinfo, decrypted_tvb, "Decrypted Data");
657 /* process decrypted_tvb from here */
658 tvb = decrypted_tvb;
659 offset = 0;
660 decrypted = true;
661 } else {
662 /* decryption failed */
663 metadata.encrypted = true;
665 } else if (mode == UA_MessageMode_Sign) {
666 uint32_t channel_id = tvb_get_letohl(tvb, 8);
667 uint32_t token_id = tvb_get_letohl(tvb, 12);
668 payload_len = tvb_ensure_captured_length_remaining(tvb, 24); /* subtract header */
670 ret = opcua_get_footer_info(channel_id, token_id, &sig_len, from_server);
671 if (ret != 0) {
672 debugprintf("Processing security footer of signed message failed.\n");
673 } else {
674 /* signed only messages have no padding, so the payload is the message size
675 * without 24 byte header and without signature */
676 payload_len -= sig_len;
678 /* store the current tvb as decrypted tvb, because we need this to parse the signature
679 * at the end, and tvb gets replaces with the reassembled UA message if the message was chunked.
681 decrypted_tvb = tvb;
682 } else {
683 /* no padding, no signature, just payload */
684 payload_len = tvb_ensure_captured_length_remaining(tvb, 24); /* subtract header */
685 pad_len= 0;
686 sig_len = 0;
689 opcua_seqno = tvb_get_letohl(tvb, offset); /* Sequence.Sequence Number */
690 opcua_reqid = tvb_get_letohl(tvb, offset + 4); /* Sequence.RequestId */
691 parseSequenceHeader(transport_tree, tvb, &offset, &metadata);
693 if (chunkType == 'A')
695 /* cancel chunk reassembly */
696 fragment_delete(&opcua_reassembly_table, pinfo, opcua_reqid, NULL);
698 col_clear_fence(pinfo->cinfo, COL_INFO);
699 col_set_str(pinfo->cinfo, COL_INFO, "Abort message");
701 offset = 0;
702 (*pfctParse)(transport_tree, tvb, pinfo, &offset, &metadata);
703 parseAbort(transport_tree, tvb, pinfo, &offset, &metadata);
705 return tvb_reported_length(tvb);
708 /* check if tvb is part of a chunked message:
709 the UA protocol does not tell us that, so we look into
710 opcua_reassembly_table if the opcua_reqid belongs to a
711 chunked message */
712 frag_msg = fragment_get(&opcua_reassembly_table, pinfo, opcua_reqid, NULL);
713 if (frag_msg == NULL)
715 frag_msg = fragment_get_reassembled_id(&opcua_reassembly_table, pinfo, opcua_reqid);
718 if (frag_msg != NULL || chunkType == 'C')
720 bool bSaveFragmented = pinfo->fragmented;
721 bool bMoreFragments = true;
722 tvbuff_t *reassembled_tvb = NULL;
723 bool first_frag = false;
725 pinfo->fragmented = true;
727 if (frag_msg == NULL)
729 first_frag = true;
731 else
733 if (chunkType == 'F')
735 bMoreFragments = false;
739 frag_msg = fragment_add_seq_check(&opcua_reassembly_table,
740 tvb,
741 offset,
742 pinfo,
743 opcua_reqid, /* ID for fragments belonging together */
744 NULL,
745 first_frag ? 0 : opcua_seqno, /* fragment sequence number */
746 payload_len,
747 bMoreFragments); /* More fragments? */
749 if (first_frag) {
750 /* the UA protocol does not number the chunks beginning
751 * from 0 but uses the common sequence number. We
752 * handle that in Wireshark by setting the sequence
753 * offset here, after passing in 0 for the first
754 * fragment. For later fragments we can use the
755 * sequence number as contained in the protocol.
758 fragment_add_seq_offset(&opcua_reassembly_table, pinfo, opcua_reqid, NULL, opcua_seqno);
760 reassembled_tvb = process_reassembled_data(tvb,
761 offset,
762 pinfo,
763 "Reassembled UA Message",
764 frag_msg,
765 &opcua_frag_items,
766 NULL,
767 transport_tree);
769 if (reassembled_tvb)
771 /* Reassembled */
772 bIsFinalChunk = true;
773 /* take it all */
774 tvb = reassembled_tvb;
775 /* new tvb starts at payload */
776 offset = 0;
778 else
780 /* Not last packet of reassembled UA message */
781 col_append_fstr(pinfo->cinfo, COL_INFO, " (Message fragment %u)", opcua_seqno);
782 /* only show transport header */
783 bParseService = false;
784 tvb = tvb_new_subset_remaining(tvb, 0);
787 pinfo->fragmented = bSaveFragmented;
791 /* parse payload if not encrypted */
792 if (!metadata.encrypted && bParseService) {
793 if (msgtype == MSG_CLOSESECURECHANNEL) {
794 iServiceId = parseService(transport_tree, tvb, pinfo, &offset, &metadata);
795 if (iServiceId == OpcUaId_CloseSecureChannelRequest_Encoding_DefaultBinary) {
796 col_append_str(pinfo->cinfo, COL_INFO, ": CloseSecureChannelRequest");
797 } else if (iServiceId == OpcUaId_CloseSecureChannelResponse_Encoding_DefaultBinary) {
798 col_append_str(pinfo->cinfo, COL_INFO, ": CloseSecureChannelResponse");
799 } else {
800 const char *szServiceName = val_to_str((uint32_t)iServiceId, g_requesttypes, "ServiceId %d");
801 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s (Wrong ServiceId)", szServiceName);
803 } else if (msgtype == MSG_MESSAGE) {
804 /* parse the service if not chunked or message was reassembled */
805 iServiceId = parseService(transport_tree, tvb, pinfo, &offset, &metadata);
807 /* display the service type in addition to the message type */
808 if (iServiceId != -1)
810 const char *szServiceName = val_to_str((uint32_t)iServiceId, g_requesttypes, "ServiceId %d");
812 if (bIsFinalChunk == false)
814 /* normal message in one chunk */
815 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", szServiceName);
817 else
819 /* reassembled message from multiple chunks */
820 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s (Message Reassembled)", szServiceName);
824 if (mode == UA_MessageMode_SignAndEncrypt && decrypted) {
825 /* parse padding and signature */
826 parseSecurityFooterSAE(transport_tree, decrypted_tvb, 8 + payload_len, pad_len, sig_len);
827 } else if (mode == UA_MessageMode_Sign) {
828 /* parse signature */
829 parseSecurityFooterSO(transport_tree, decrypted_tvb, 24 + payload_len, sig_len);
832 if (metadata.encrypted) {
833 col_append_str(pinfo->cinfo, COL_INFO, " (encrypted)");
834 } else if (mode == UA_MessageMode_SignAndEncrypt) {
835 col_append_str(pinfo->cinfo, COL_INFO, " (decrypted)");
839 return tvb_reported_length(tvb);
842 /** The main OpcUa dissector functions.
843 * It uses tcp_dissect_pdus from packet-tcp.h
844 * to reassemble the TCP data.
846 static int dissect_opcua(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
848 tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
849 get_opcua_message_len, dissect_opcua_message, data);
850 return tvb_reported_length(tvb);
853 /** Init plugin resources */
854 void proto_init_opcua(void)
856 debugprintf("proto_init_opcua called.\n");
857 ua_keysets_init();
858 opcua_load_keylog_file(g_opcua_debug_file_name);
861 /** Cleanup plugin resources */
862 void proto_cleanup_opcua(void)
864 debugprintf("proto_cleanup_opcua called.\n");
865 ua_keysets_clear();
868 /** secrets callback called from Wireshark when loading a capture file with OPC UA Keylog File. */
869 static void opcua_secrets_block_callback(const void *secrets, unsigned size)
871 char *tmp = g_memdup2(secrets, size + 1);
872 if (tmp == NULL) return; /* OOM */
874 debugprintf("Loading secrets block '%s'...\n", (const char*)secrets);
875 debugprintf("size = %u\n", size);
876 /* ensure data is zero terminated */
877 tmp[size] = 0;
878 /* parse data */
879 opcua_keylog_process_lines(tmp);
880 g_free(tmp);
883 /** plugin entry functions.
884 * This registers the OpcUa protocol.
886 void proto_register_opcua(void)
888 static hf_register_info hf[] =
890 /* id full name abbreviation type display strings bitmask blurb HFILL */
891 {&hf_opcua_fragments, {"Message fragments", "opcua.fragments", FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL}},
892 {&hf_opcua_fragment, {"Message fragment", "opcua.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
893 {&hf_opcua_fragment_overlap, {"Message fragment overlap", "opcua.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
894 {&hf_opcua_fragment_overlap_conflicts, {"Message fragment overlapping with conflicting data", "opcua.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
895 {&hf_opcua_fragment_multiple_tails, {"Message has multiple tail fragments", "opcua.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
896 {&hf_opcua_fragment_too_long_fragment, {"Message fragment too long", "opcua.fragment.too_long_fragment", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
897 {&hf_opcua_fragment_error, {"Message defragmentation error", "opcua.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
898 {&hf_opcua_fragment_count, {"Message fragment count", "opcua.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL}},
899 {&hf_opcua_reassembled_in, {"Reassembled in", "opcua.reassembled.in", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
900 {&hf_opcua_reassembled_length, {"Reassembled length", "opcua.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL}}
903 /** Setup protocol subtree array */
904 static int *ett[] =
906 &ett_opcua_extensionobject,
907 &ett_opcua_nodeid,
908 &ett_opcua_transport,
909 &ett_opcua_fragment,
910 &ett_opcua_fragments
913 proto_opcua = proto_register_protocol("OpcUa Binary Protocol", "OpcUa", "opcua");
914 opcua_handle = register_dissector("opcua", dissect_opcua, proto_opcua);
916 register_init_routine(proto_init_opcua);
917 register_cleanup_routine(proto_cleanup_opcua);
919 opcua_module = prefs_register_protocol(proto_opcua, proto_reg_handoff_opcua);
920 prefs_register_filename_preference(opcua_module, "debug_file", "OPCUA debug file",
921 "Redirect OPC UA Secure Conversion session keys to the file specified to enable decryption.",
922 &g_opcua_debug_file_name, false);
924 prefs_register_enum_preference(opcua_module, "signature_length", "Default signature length",
925 "Default signature length to use if the OpenSecureChannel message is missing.",
926 &g_opcua_default_sig_len, opcua_sig_len_enum, false);
928 registerTransportLayerTypes(proto_opcua);
929 registerSecurityLayerTypes(proto_opcua);
930 registerSequenceLayerTypes(proto_opcua);
931 registerApplicationLayerTypes(proto_opcua);
932 registerSimpleTypes(proto_opcua);
933 registerEnumTypes(proto_opcua);
934 registerComplexTypes();
935 registerServiceTypes();
936 registerFieldTypes(proto_opcua);
938 proto_register_subtree_array(ett, array_length(ett));
939 proto_register_field_array(proto_opcua, hf, array_length(hf));
941 reassembly_table_register(&opcua_reassembly_table,
942 &addresses_reassembly_table_functions);
943 secrets_register_type(SECRETS_TYPE_OPCUA, opcua_secrets_block_callback);
946 void proto_reg_handoff_opcua(void)
948 dissector_add_uint_range_with_preference("tcp.port", OPCUA_PORT_RANGE, opcua_handle);
952 * Editor modelines - https://www.wireshark.org/tools/modelines.html
954 * Local variables:
955 * c-basic-offset: 4
956 * tab-width: 8
957 * indent-tabs-mode: nil
958 * End:
960 * vi: set shiftwidth=4 tabstop=8 expandtab:
961 * :indentSize=4:tabSize=8:noTabs=true: