Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-oer.c
blob75bea0450fe86e4b804d39fb495c23769982ccb8
1 /* packet-oer.c
2 * Routines for ASN1 Octet Encoding Rules
4 * Copyright 2018, Anders Broman <anders.broman@ericsson.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 * Ref: ITU-T X.696 (08/2015) https://www.itu.int/itu-t/recommendations/rec.aspx?rec=12487
12 * Based on the BER and PER dissectors by Ronnie Sahlberg.
15 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/oids.h>
19 #include <epan/asn1.h>
20 #include <epan/expert.h>
21 #include <epan/exceptions.h>
23 #include <wsutil/array.h>
25 #include "packet-oer.h"
28 #define PNAME "Octet Encoding Rules (ASN.1)"
29 #define PSNAME "OER"
30 #define PFNAME "oer"
32 void proto_register_oer(void);
33 void proto_reg_handoff_oer(void);
35 /* Initialize the protocol and registered fields */
36 static int proto_oer;
38 static int hf_oer_optional_field_bit;
39 static int hf_oer_class;
40 static int hf_oer_tag;
41 static int hf_oer_length_determinant;
42 static int hf_oer_extension_present_bit;
43 static int hf_oer_open_type_length;
45 /* Initialize the subtree pointers */
46 static int ett_oer;
47 static int ett_oer_sequence_of_item;
48 static int ett_oer_open_type;
50 static expert_field ei_oer_not_decoded_yet;
51 static expert_field ei_oer_undecoded;
52 static expert_field ei_oer_open_type;
54 /* whether the OER helpers should put the internal OER fields into the tree or not. */
55 static bool display_internal_oer_fields;
58 #define DEBUG_ENTRY(x) \
59 printf("#%u %s tvb:0x%08x\n",actx->pinfo->num,x,(int)tvb);
61 #define DEBUG_ENTRY(x) \
64 #define SEQ_MAX_COMPONENTS 128
67 * XXX - if the specified length is less than the remaining length
68 * of data in the tvbuff, either 1) the specified length is bad and
69 * we should report that with an expert info or 2) the tvbuff is
70 * unreassembled and we should make the new tvbuff also be an
71 * unreassembled tvbuff.
73 static tvbuff_t *
74 oer_tvb_new_subset_length(tvbuff_t *tvb, const int backing_offset, const int backing_length)
76 int length_remaining;
78 length_remaining = tvb_reported_length_remaining(tvb, backing_offset);
79 return tvb_new_subset_length(tvb, backing_offset, (length_remaining > backing_length) ? backing_length : length_remaining);
82 static void
83 dissect_oer_not_decoded_yet(proto_tree* tree, packet_info* pinfo, tvbuff_t *tvb, const char* reason)
85 proto_tree_add_expert_format(tree, pinfo, &ei_oer_undecoded, tvb, 0, 0, "something unknown here [%s]", reason);
86 col_append_fstr(pinfo->cinfo, COL_INFO, "[UNKNOWN OER: %s]", reason);
87 THROW(ReportedBoundsError);
90 /* Given the ordinal of the option in the sequence, print the name. eg find the 1:th then the 2:nd etc*/
91 static const char *
92 index_get_optional_name(const oer_sequence_t *sequence, int idx)
94 int i;
95 header_field_info *hfi;
97 for (i = 0; sequence[i].p_id; i++) {
98 if ((sequence[i].extension != ASN1_NOT_EXTENSION_ROOT) && (sequence[i].optional == ASN1_OPTIONAL)) {
99 if (idx == 0) {
100 hfi = proto_registrar_get_nth(*sequence[i].p_id);
101 return (hfi) ? hfi->name : "<unknown field>";
103 idx--;
106 return "<unknown type>";
110 static const char *
111 index_get_field_name(const oer_sequence_t *sequence, int idx)
113 header_field_info *hfi;
115 hfi = proto_registrar_get_nth(*sequence[idx].p_id);
116 return (hfi) ? hfi->name : "<unknown field>";
120 /* 8.6 Length determinant */
121 static uint32_t
122 dissect_oer_length_determinant(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, uint32_t *length)
124 proto_item *item;
125 uint8_t oct, value_len;
126 uint32_t len;
128 if (!length) {
129 length = &len;
132 *length = 0;
134 /* 8.6.3 There are two forms of length determinant - a short form and a long form...
135 * 8.6.4 The short form of length determinant consists of a single octet. Bit 8 of this octet shall be set to '0',
136 * and bits 7 to 1 of this octet shall contain the length (0 to 127) encoded as an unsigned binary integer into 7 bits.
138 oct = tvb_get_uint8(tvb, offset);
139 if ((oct & 0x80) == 0) {
140 /* Short form */
141 *length = oct;
142 if (hf_index > 0) {
143 item = proto_tree_add_item(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN);
144 if (!display_internal_oer_fields) proto_item_set_hidden(item);
146 offset++;
148 return offset;
150 offset++;
151 /* Long form */
152 /* 8.6.5 The long form of length determinant consists of an initial octet followed by one or more subsequent octets.
153 * Bit 8 of the initial octet shall be set to 1, and bits 7 to 1 of this octet shall indicate the number of subsequent octets (1 to 127).
154 * The length shall be encoded as a variable-size unsigned number into the subsequent octets.
156 value_len = oct & 0x7f;
157 switch (value_len) {
158 case 1:
159 *length = tvb_get_uint8(tvb, offset);
160 offset++;
161 break;
162 case 2:
163 *length = tvb_get_ntohs(tvb, offset);
164 offset+=2;
165 break;
166 case 3:
167 *length = tvb_get_ntoh24(tvb, offset);
168 offset+=3;
169 break;
170 case 4:
171 *length = tvb_get_ntohl(tvb, offset);
172 offset+=4;
173 break;
174 default:
175 proto_tree_add_expert_format(tree, actx->pinfo, &ei_oer_not_decoded_yet, tvb, offset, 1,
176 "Length determinant: Long form %u octets not handled", value_len);
177 return tvb_reported_length(tvb);
180 return offset;
184 /* 9 Encoding of Boolean values */
185 uint32_t dissect_oer_boolean(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, bool* bool_val)
187 uint32_t val = 0;
188 DEBUG_ENTRY("dissect_oer_boolean");
190 actx->created_item = proto_tree_add_item_ret_uint(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN, &val);
191 offset++;
193 if (bool_val) {
194 *bool_val = (bool)val;
197 return offset;
200 /* 10 Encoding of integer values */
202 uint32_t
203 dissect_oer_constrained_integer(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int64_t min, int64_t max, uint32_t *value, bool has_extension _U_)
205 DEBUG_ENTRY("dissect_oer_constrained_integer");
206 uint32_t val = 0;
208 if (min >= 0) {
209 /* 10.2 There are two main cases:
210 * a) The effective value constraint has a lower bound, and that lower bound is zero or positive.
212 if (max < 0x100) {
213 /* One octet */
214 proto_tree_add_item_ret_uint(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN, &val);
215 offset++;
216 } else if (max < 0x10000) {
217 /* Two octets */
218 proto_tree_add_item_ret_uint(tree, hf_index, tvb, offset, 2, ENC_BIG_ENDIAN, &val);
219 offset += 2;
220 } else if (max == 0xFFFFFFFF) {
221 /* Four octets */
222 proto_tree_add_item_ret_uint(tree, hf_index, tvb, offset, 4, ENC_BIG_ENDIAN, &val);
223 offset += 4;
224 } else {
225 /* To large not handlet yet*/
226 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer to large value");
229 } else {
230 /* b) The effective value constraint has either a negative lower bound or no lower bound. */
231 if ((min >= -128) && (max <= 127)) {
232 /* 10.4 a a) If the lower bound is greater than or equal to -2^7 (-128) and the upper bound is less than or equal to 2^7-1 (127),
233 * then every value of the integer type shall be encoded as a fixed-size signed number in a one-octet word;
235 proto_tree_add_item_ret_int(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN, &val);
236 offset++;
237 } else if ((min >= -32768) && (max <= 32767)) {
238 /* if the lower bound is greater than or equal to -2^15 (-32768) and the upper bound is less than or equal to 2^15-1 (32767),
239 * then every value of the integer type shall be encoded as a fixed-size signed number in a two octet word;
241 proto_tree_add_item_ret_int(tree, hf_index, tvb, offset, 2, ENC_BIG_ENDIAN, &val);
242 offset += 2;
243 } else if ((min >= -2147483648LL) && (max <= 2147483647)) {
244 /* if the lower bound is greater than or equal to -2^31 (-2147483648) and the upper bound is less than or equal to 2^31-1 (2147483647),
245 * then every value of the integer type shall be encoded as a fixed-size signed number in a four-octet word
247 proto_tree_add_item_ret_int(tree, hf_index, tvb, offset, 4, ENC_BIG_ENDIAN, &val);
248 offset += 4;
249 } else {
250 /* To large not handlet yet*/
251 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer to large value");
256 if (value) {
257 *value = val;
260 return offset;
264 uint32_t
265 dissect_oer_constrained_integer_64b(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int64_t min, uint64_t max, uint64_t *value, bool has_extension _U_)
267 uint64_t val = 0;
269 /* XXX Negative numbers ???*/
270 if (min >= 0) {
271 /* 10.2 There are two main cases:
272 * a) The effective value constraint has a lower bound, and that lower bound is zero or positive.
274 /* 10.3 */
275 if (max < 0x100) {
276 /* One octet, upper bound is less than or equal to 2 exp 8 - 1 (255) */
277 proto_tree_add_item_ret_uint64(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN, &val);
278 offset++;
279 } else if (max < 0x10000) {
280 /* Two octets, upper bound is less than or equal to 2 exp 16 - 1 (65535), */
281 proto_tree_add_item_ret_uint64(tree, hf_index, tvb, offset, 2, ENC_BIG_ENDIAN, &val);
282 offset += 2;
283 } else if (max < 0x100000000) {
284 /* Four octets, upper bound is less than or equal to 2 exp 32 - 1 (4294967295), */
285 proto_tree_add_item_ret_uint64(tree, hf_index, tvb, offset, 4, ENC_BIG_ENDIAN, &val);
286 offset += 4;
287 } else if (max == UINT64_C(18446744073709551615)) {
288 /* Eight octets, upper bound is less than or equal to 2 exp 64 - 1 (4294967295), */
289 proto_tree_add_item_ret_uint64(tree, hf_index, tvb, offset, 8, ENC_BIG_ENDIAN, &val);
290 offset += 8;
291 } else {
292 /* eight-octet, upper bound is less than or equal to 2 exp 64 - 1 (18446744073709551615) */
293 /* To large not handlet yet*/
294 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer to large value");
297 } else {
298 /* b) The effective value constraint has either a negative lower bound or no lower bound. */
299 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer negative value");
302 if (value) {
303 *value = val;
306 return offset;
310 uint32_t
311 dissect_oer_constrained_integer_64b_no_ub(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int64_t min, uint64_t max _U_, uint64_t *value, bool has_extension _U_)
313 uint64_t val = 0;
314 uint32_t length;
316 /* Negative numbers ???*/
317 if (min >= 0) {
319 /* (the effective value constraint has either an upper bound greater than 2 exp 64-1 or no upper bound)
320 * every value of the integer type shall be encoded as a length determinant (see 8.6)
321 * followed by a variable-size unsigned number
322 * (occupying at least as many whole octets as are necessary to carry the value).
324 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
325 if (length > 0) {
326 if (length < 5) {
327 proto_tree_add_item_ret_uint64(tree, hf_index, tvb, offset, length, ENC_BIG_ENDIAN, &val);
328 offset += length;
329 } else {
330 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer NO_BOUND to many octets");
332 } else {
333 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer unexpected length");
336 if (value) {
337 *value = val;
340 return offset;
344 uint32_t
345 dissect_oer_integer(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int32_t *value)
347 int32_t val = 0;
348 uint32_t length;
349 /* 10.4 e) (the effective value constraint has a lower bound less than -263, no lower bound,
350 * an upper bound greater than 2 exp 63-1, or no upper bound) every value of the integer type
351 * shall be encoded as a length determinant (see 8.6) followed by a variable-size signed number
352 * (occupying at least as many whole octets as are necessary to carry the value).
354 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
355 if (length > 0) {
356 if (length < 5) {
357 /* extend sign bit for signed fields */
358 enum ftenum type = FT_INT32;
359 /* This should be signed, because the field should only be
360 * unsigned if there's a constraint, and then we don't get here. */
361 if (hf_index > 0) {
362 type = proto_registrar_get_ftype(hf_index);
364 uint8_t first = tvb_get_uint8(tvb, offset);
365 if (first & 0x80 && FT_IS_INT(type)) {
366 val = -1;
368 for (unsigned i = 0; i < length; i++) {
369 val = ((uint32_t)val << 8) | tvb_get_uint8(tvb, offset);
370 offset++;
372 } else {
373 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer NO_BOUND too many octets");
375 } else {
376 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "constrained_integer unexpected length");
379 if (hf_index > 0) {
380 header_field_info* hfi;
381 hfi = proto_registrar_get_nth(hf_index);
382 if (FT_IS_UINT32(hfi->type)) {
383 actx->created_item = proto_tree_add_uint(tree, hf_index, tvb, offset - length, length, (uint32_t)val);
384 } else if (FT_IS_INT32(hfi->type)) {
385 actx->created_item = proto_tree_add_int(tree, hf_index, tvb, offset - length, length, val);
386 } else {
387 DISSECTOR_ASSERT_NOT_REACHED();
391 if (value) {
392 *value = val;
395 return offset;
398 /* 11 Encoding of enumerated values */
399 uint32_t
400 dissect_oer_enumerated(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, uint32_t root_num _U_, uint32_t *value, bool has_extension _U_, uint32_t ext_num _U_, uint32_t *value_map _U_)
402 int old_offset = offset;
403 uint32_t val;
404 /* 11.2 There are two forms of enumerated type encoding - a short form and a long form... */
406 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, -1 /*Don't show length value as internal field*/, &val);
407 actx->created_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset, offset - old_offset, val);
409 if (value) {
410 *value = val;
413 return offset;
417 /* 13 Encoding of bitstring values */
419 /* 13.1 General
420 * The encoding of a bitstring value depends on the effective size constraint of the bitstring type (see 8.2.8).
421 * If the lower and upper bounds of the effective size constraint are identical, 13.2 applies, otherwise 13.3 applies.
423 uint32_t
424 dissect_oer_bit_string(tvbuff_t *tvb, uint32_t offset _U_, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_, int min_len _U_, int max_len _U_, bool has_extension _U_, int * const *named_bits _U_, int num_named_bits _U_, tvbuff_t **value_tvb _U_, int *len _U_)
426 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "Encoding of bitstring values not handled yet");
428 return tvb_reported_length(tvb);
431 static uint32_t
432 dissect_oer_bit_string_unconstr(tvbuff_t *tvb, uint32_t offset _U_, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_, int min_len _U_, int max_len _U_, bool has_extension _U_, int * const *named_bits _U_, int num_named_bits _U_, tvbuff_t **value_tvb _U_, uint8_t * const values, int values_size, int *len _U_)
434 int length;
435 uint8_t unused_bit_count = 0;
437 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, -1 /*Don't show length value as internal field*/, &length);
438 if (length > 0) {
439 unused_bit_count = tvb_get_uint8(tvb, offset);
440 if (unused_bit_count > 7) {
441 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "too high unused bit count");
442 return offset + length;
444 offset += 1;
445 length -= 1;
448 *len = length;
449 if (values) {
450 memset(values, 0, values_size);
451 if (length > values_size) {
452 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "too many bitstring elements");
454 for (int i = 0; i < length; i++) {
455 uint8_t value = tvb_get_uint8(tvb, offset);
456 if (i + 1 == length) {
457 /* unused bits of the last octet shall be set to zeros */
458 value &= (0xFF << unused_bit_count);
460 if (i < values_size) {
461 values[i] = value;
463 offset += 1;
467 return offset;
470 /* 14 Encoding of octet string values */
471 uint32_t
472 dissect_oer_octet_string(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, bool has_extension _U_, tvbuff_t **value_tvb)
474 unsigned length;
475 /* 14.1 For an octetstring type in which the lower and upper bounds of the effective size constraint are identical,
476 * the encoding shall consist of the octets of the octetstring value (zero or more octets), with no length determinant.
478 if ((min_len != NO_BOUND ) && (min_len == max_len)) {
479 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, offset, min_len, ENC_NA);
480 if (value_tvb) {
481 *value_tvb = oer_tvb_new_subset_length(tvb, offset, min_len);
483 return offset + min_len;
486 /* 14.2 For any other octetstring type, the encoding shall consist of a length determinant (see 8.6)
487 * followed by the octets of the octetstring value (zero or more octets).
489 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
490 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, offset, length, ENC_NA);
491 if (value_tvb) {
492 *value_tvb = oer_tvb_new_subset_length(tvb, offset, length);
495 offset = offset + length;
497 return offset;
501 /* 15 Encoding of the null value */
502 uint32_t
503 dissect_oer_null(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index)
505 /* The encoding of the null value shall be empty. */
506 proto_item *ti_tmp;
508 ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset, 1, ENC_BIG_ENDIAN);
509 proto_item_append_text(ti_tmp, ": NULL");
511 return offset;
514 static const value_string oer_class_vals[] = {
515 { 0, "universal" },
516 { 1, "application" },
517 { 2, "context-specific" },
518 { 3, "private" },
519 { 0, NULL }
522 static const value_string oer_extension_present_bit_vals[] = {
523 { 0, "Not present" },
524 { 1, "Present" },
525 { 0, NULL }
530 /* 16 Encoding of sequence values */
531 uint32_t
532 dissect_oer_sequence(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, int ett_index, const oer_sequence_t *sequence)
534 uint64_t optional_field_flag;
535 proto_item *item;
536 proto_tree *tree;
537 uint32_t old_offset = offset;
538 uint32_t i, j, num_opts;
539 uint32_t optional_mask[SEQ_MAX_COMPONENTS >> 5];
540 int bit_offset = 0;
541 uint64_t extensions_present = 0;
543 DEBUG_ENTRY("dissect_oer_sequence");
545 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, 0, ENC_BIG_ENDIAN);
546 tree = proto_item_add_subtree(item, ett_index);
549 /* first check if there should be an extension bit for this SEQUENSE.
550 * we do this by just checking the first entry
552 bit_offset = offset << 3;
553 if (sequence[0].extension == ASN1_NO_EXTENSIONS) {
554 /*extension_present=0; ?? */
555 } else {
556 /* 16.2.2 The extension bit shall be present (as bit 8 of the first octet of the preamble)
557 * if, and only if, the sequence type definition contains an extension marker...
559 actx->created_item = proto_tree_add_bits_ret_val(tree, hf_oer_extension_present_bit, tvb, bit_offset, 1, &extensions_present, ENC_BIG_ENDIAN);
560 bit_offset++;
561 if (!display_internal_oer_fields) proto_item_set_hidden(actx->created_item);
563 /* The presence bitmap is encoded as a bit string with a fixed size constraint (see 16.2.3),
564 * and has one bit for each field of the sequence type that has the keyword OPTIONAL or DEFAULT,
565 * in specification order.
567 num_opts = 0;
568 for (i = 0; sequence[i].p_id; i++) {
569 if ((sequence[i].extension != ASN1_NOT_EXTENSION_ROOT) && (sequence[i].optional == ASN1_OPTIONAL)) {
570 num_opts++;
573 if (num_opts > SEQ_MAX_COMPONENTS) {
574 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
577 memset(optional_mask, 0, sizeof(optional_mask));
578 for (i = 0; i<num_opts; i++) {
579 actx->created_item = proto_tree_add_bits_ret_val(tree, hf_oer_optional_field_bit, tvb, bit_offset, 1, &optional_field_flag, ENC_BIG_ENDIAN);
580 bit_offset++;
581 if (tree) {
582 proto_item_append_text(actx->created_item, " (%s %s present)",
583 index_get_optional_name(sequence, i), optional_field_flag ? "is" : "is NOT");
585 if (!display_internal_oer_fields) proto_item_set_hidden(actx->created_item);
586 if (optional_field_flag) {
587 optional_mask[i >> 5] |= 0x80000000 >> (i & 0x1f);
590 /* 16.2.1 preamble as a whole (including extension bit) occupies a whole number of octets */
591 offset = (bit_offset + 7) >> 3;
593 /* */
594 for (i = 0, j = 0; sequence[i].p_id; i++) {
595 if ((sequence[i].extension == ASN1_NO_EXTENSIONS)
596 || (sequence[i].extension == ASN1_EXTENSION_ROOT)) {
597 if (sequence[i].optional == ASN1_OPTIONAL) {
598 bool is_present;
599 if (num_opts == 0) {
600 continue;
602 is_present = (0x80000000 >> (j & 0x1f))&optional_mask[j >> 5];
603 num_opts--;
604 j++;
605 if (!is_present) {
606 continue;
609 if (sequence[i].func) {
610 offset = sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
611 } else {
612 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
617 if (extensions_present) {
618 /* Parse the Extension Bitmap */
619 int ext_bmp_len;
620 uint8_t extension_mask[SEQ_MAX_COMPONENTS >> 3];
621 offset = dissect_oer_bit_string_unconstr(tvb, offset, actx, tree, hf_index, NO_BOUND, NO_BOUND, false, NULL, 0, NULL, extension_mask, SEQ_MAX_COMPONENTS >> 3, &ext_bmp_len);
623 /* find first extension */
624 int seq_pos;
625 for (seq_pos = 0; sequence[seq_pos].p_id; seq_pos++) {
626 if (sequence[seq_pos].extension == ASN1_NOT_EXTENSION_ROOT) {
627 break;
630 for (int bitstr_pos = 0; bitstr_pos < ext_bmp_len; bitstr_pos++) {
631 int8_t octet = extension_mask[bitstr_pos];
632 for (int octet_pos = 0; octet_pos < 8; octet_pos++) {
633 bool ext_present = ((octet << octet_pos) & (0x80)) >> 7;
634 if (ext_present) {
635 /* If any extensions still known - use functions */
636 if (sequence[seq_pos].p_id) {
637 unsigned length;
638 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
639 if (sequence[seq_pos].func) {
640 offset = sequence[seq_pos].func(tvb, offset, actx, tree, *sequence[seq_pos].p_id);
641 } else {
642 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, seq_pos ));
644 } else {
645 offset = dissect_oer_octet_string(tvb, offset, actx, tree, hf_index, NO_BOUND, NO_BOUND, false, NULL);
648 /* if still within known sequence elements - move to next */
649 if (sequence[seq_pos].p_id) {
650 seq_pos++;
657 proto_item_set_len(item, offset - old_offset);
658 actx->created_item = item;
659 return offset;
662 /* 17 Encoding of sequence-of values */
664 static uint32_t
665 dissect_oer_sequence_of_helper(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, oer_type_fn func, int hf_index, uint32_t length)
667 uint32_t i;
669 DEBUG_ENTRY("dissect_oer_sequence_of_helper");
670 for (i = 0; i<length; i++) {
671 uint32_t lold_offset = offset;
672 proto_item *litem;
673 proto_tree *ltree;
675 ltree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_oer_sequence_of_item, &litem, "Item %d", i);
677 offset = (*func)(tvb, offset, actx, ltree, hf_index);
678 proto_item_set_len(litem, offset - lold_offset);
681 return offset;
684 uint32_t
685 dissect_oer_sequence_of(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, int ett_index, const oer_sequence_t *seq)
687 proto_item *item;
688 proto_tree *tree;
689 uint32_t old_offset = offset;
690 uint32_t occ_len, occurrence;
691 header_field_info *hfi;
693 DEBUG_ENTRY("dissect_oer_sequence_of");
695 /* 17.1 The encoding of a sequence-of value shall consist of a quantity field...*/
697 /* 17.2 The quantity field shall be a non-negative integer value indicating the number of occurrences.
698 * This number shall be encoded as a length determinant (see 8.6) followed by a variable-size unsigned number
699 * (occupying at least as many whole octets as are necessary to carry the value).
701 offset = dissect_oer_length_determinant(tvb, offset, actx, parent_tree, hf_oer_length_determinant, &occ_len);
703 switch (occ_len) {
704 case 1:
705 occurrence = tvb_get_uint8(tvb, offset);
706 break;
707 case 2:
708 occurrence = tvb_get_ntohs(tvb, offset);
709 break;
710 case 3:
711 occurrence = tvb_get_ntoh24(tvb, offset);
712 break;
713 case 4:
714 occurrence = tvb_get_ntohl(tvb, offset);
715 break;
716 default:
717 proto_tree_add_expert_format(parent_tree, actx->pinfo, &ei_oer_not_decoded_yet, tvb, offset, 1,
718 "sequence_of Occurrence %u octets not handled", occ_len);
719 return tvb_reported_length(tvb);
722 offset = offset + occ_len;
723 hfi = proto_registrar_get_nth(hf_index);
724 if (FT_IS_UINT(hfi->type)) {
725 item = proto_tree_add_uint(parent_tree, hf_index, tvb, old_offset, occ_len, occurrence);
726 proto_item_append_text(item, (occurrence == 1) ? " item" : " items");
727 } else {
728 item = proto_tree_add_item(parent_tree, hf_index, tvb, old_offset, 0, ENC_BIG_ENDIAN);
730 tree = proto_item_add_subtree(item, ett_index);
732 offset = dissect_oer_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, occurrence);
735 proto_item_set_len(item, offset - old_offset);
736 return offset;
740 /* As we are using the per ASN1 generator define this "dummy" function */
741 uint32_t
742 dissect_oer_constrained_sequence_of(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, int ett_index, const oer_sequence_t *seq, int min_len _U_, int max_len _U_ , bool has_extension _U_)
744 return dissect_oer_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
747 /* 20 Encoding of choice values */
748 uint32_t
749 dissect_oer_choice(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int ett_index, const oer_choice_t *choice, int *value)
751 proto_tree *choice_tree;
752 proto_item *item, *choice_item;
753 int bit_offset = offset << 3;
754 uint64_t oer_class;
755 uint8_t tag, oct;
756 int old_offset = offset;
758 /* 20.1 The encoding of a value of a choice type shall consist of the encoding of the outermost tag of the type of the chosen alternative
759 * as specified in 8.7, followed by the encoding of the value of the chosen alternative.
762 /* 8.7.2.1 Bits 8 and 7 of the first octet shall denote the tag class */
763 item = proto_tree_add_bits_ret_val(tree, hf_oer_class, tvb, bit_offset, 2, &oer_class, ENC_BIG_ENDIAN);
764 if (!display_internal_oer_fields) proto_item_set_hidden(item);
765 bit_offset += 2;
767 tag = tvb_get_bits8(tvb, bit_offset, 6);
768 offset++;
769 /* 8.7.2.3 If the tag number is greater or equal to 63, Bits 6 to 1 of the initial octet shall be set to '111111'B.*/
770 if (tag == 0x3f) {
771 /* The tag number shall be encoded into bits 7 to 1 of each subsequent octet (seven bits in each octet),
772 * with bit 1 of the final subsequent octet containing the least significant bit of the tag number ("big-endian" encoding).
774 oct = tvb_get_uint8(tvb, offset);
775 if ((oct & 0x80) == 0x80) {
776 dissect_oer_not_decoded_yet(tree, actx->pinfo, tvb, "Choice, Tag value > 0x7f not implemented yet");
777 } else {
778 /* Bits 7 to 1 of the first subsequent octet shall not be all set to 0.*/
779 tag = oct;
780 item = proto_tree_add_uint(tree, hf_oer_tag, tvb, offset, 1, tag);
781 if (!display_internal_oer_fields) proto_item_set_hidden(item);
783 } else {
784 /* Tag value in first octet */
785 item = proto_tree_add_bits_item(tree, hf_oer_tag, tvb, bit_offset, 6, ENC_BIG_ENDIAN);
786 if (!display_internal_oer_fields) proto_item_set_hidden(item);
789 /* 20.2 If the choice type contains an extension marker in the "AlternativeTypeLists" and the chosen alternative
790 * is one of the extension additions, then the value of the chosen alternative shall be encoded as if it were contained
791 * in an open type (see clause 30), otherwise it shall be encoded normally.
793 if (value) {
794 (*value) = -1;
797 /* XXX Extension handling is not implemented */
798 while (choice->func) {
799 if (choice->value == tag) {
800 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset, 0, choice->value);
801 choice_tree = proto_item_add_subtree(choice_item, ett_index);
802 /* For known extensions parse length prefix */
803 if (choice->extension == ASN1_NOT_EXTENSION_ROOT) {
804 unsigned length;
805 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
807 offset = choice->func(tvb, offset, actx, choice_tree, *choice->p_id);
808 proto_item_set_len(choice_item, offset - old_offset);
809 if (value) {
810 (*value) = tag;
812 return offset;
814 choice++;
816 /* None of the known choice options matched, parse the contents as an extension */
817 // XXX : should check if the extensions are present in the CHOICE definition
818 offset = dissect_oer_octet_string(tvb, offset, actx, tree, hf_index, NO_BOUND, NO_BOUND, false, NULL);
820 return offset;
823 /* 21 Encoding of object identifier values
824 * The encoding of an object identifier value shall consist of a length determinant (see 8.6) followed by a series of octets,
825 * which are the contents octets of BER encoding of the object identifier value (see Rec. ITU-T X.690 | ISO/IEC 8825-1,8.19).
827 static uint32_t
828 dissect_oer_any_oid(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, tvbuff_t** value_tvb,
829 bool is_absolute)
831 unsigned length;
832 const char* str;
833 header_field_info* hfi;
835 DEBUG_ENTRY("dissect_oer_any_oid");
837 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
839 actx->created_item = NULL;
840 hfi = proto_registrar_get_nth(hf_index);
841 if ((is_absolute && hfi->type == FT_OID) || (!is_absolute && hfi->type == FT_REL_OID)) {
842 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, offset, length, ENC_BIG_ENDIAN);
844 else if (FT_IS_STRING(hfi->type)) {
845 str = oid_encoded2string(actx->pinfo->pool, tvb_get_ptr(tvb, offset, length), length);
846 actx->created_item = proto_tree_add_string(tree, hf_index, tvb, offset, length, str);
847 if (actx->created_item) {
848 /* see if we know the name of this oid */
849 str = oid_resolved_from_encoded(actx->pinfo->pool, tvb_get_ptr(tvb, offset, length), length);
850 if (str) {
851 proto_item_append_text(actx->created_item, " (%s)", str);
855 else {
856 DISSECTOR_ASSERT_NOT_REACHED();
859 if (value_tvb)
860 *value_tvb = tvb_new_subset_length(tvb, offset, length);
862 return offset;
865 uint32_t
866 dissect_oer_object_identifier(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, tvbuff_t** value_tvb)
868 return dissect_oer_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, true);
871 /* 27 Encoding of values of the restricted character string types
872 * 27.1 The encoding of a restricted character string type depends on whether the type is a known-multiplier character
873 * string type or not. The following types are known-multiplier character string types:
874 * IA5String, VisibleString, ISO646String, PrintableString, NumericString, BMPString, and UniversalString.
878 uint32_t
879 dissect_oer_IA5String(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, int min_len, int max_len, bool has_extension _U_)
881 uint32_t length = 0;
883 /* 27.2 For a known-multiplier character string type in which the lower and upper bounds of the effective size constraint
884 * are identical, the encoding shall consist of the series of octets specified in 27.4, with no length determinant.
886 if ((min_len == max_len) && (min_len != NO_BOUND )){
887 length = min_len;
889 else {
890 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
892 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, offset, length, ENC_ASCII | ENC_NA);
894 return offset + length;
898 uint32_t
899 dissect_oer_UTF8String(tvbuff_t *tvb, uint32_t offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len _U_, int max_len _U_, bool has_extension _U_)
901 uint32_t length = 0;
902 /* 27.3 For every other character string type, the encoding shall consist of a length determinant
903 * (see 8.6) followed by the series of octets specified in 27.4.
905 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_length_determinant, &length);
906 actx->created_item = proto_tree_add_item( tree, hf_index, tvb, offset, length, ENC_UTF_8 | ENC_NA);
908 return offset + length;
912 /* 30 Encoding of open type values
913 *NOTE – An open type is an ASN.1 type that can take any abstract value of any ASN.1 type. Each value of an open type consists
914 * of:
915 * a) a contained type; and
916 * b) a value of the contained type.
917 * The encoding of an open type value shall consist of a length determinant (see 8.6) followed by a series of octets, which
918 * are the encoding of the value of the contained type.
921 static uint32_t
922 dissect_oer_open_type_internal(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, void* type_cb, asn1_cb_variant variant)
924 int type_length, start_offset;
925 tvbuff_t* val_tvb = NULL;
926 proto_tree* subtree = tree;
928 start_offset = offset;
931 offset = dissect_oer_length_determinant(tvb, offset, actx, tree, hf_oer_open_type_length, &type_length);
932 val_tvb = tvb_new_subset_length(tvb, offset, type_length);
934 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, type_length, ENC_BIG_ENDIAN);
935 subtree = proto_item_add_subtree(actx->created_item, ett_oer_open_type);
937 if (variant == CB_NEW_DISSECTOR) {
938 add_new_data_source(actx->pinfo, val_tvb, "OCTET STRING");
941 if (type_cb) {
942 switch (variant) {
943 case CB_ASN1_ENC:
944 ((oer_type_fn)type_cb)(val_tvb, 0, actx, tree, hf_index);
945 break;
946 case CB_NEW_DISSECTOR:
947 /* Pas actx->private_data as "data" to the called function */
948 ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree, actx->private_data);
949 break;
950 case CB_DISSECTOR_HANDLE:
951 break;
954 else {
955 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_oer_open_type, tvb, start_offset, offset - start_offset);
958 return offset;
960 uint32_t
961 dissect_oer_open_type(tvbuff_t* tvb, uint32_t offset, asn1_ctx_t* actx, proto_tree* tree, int hf_index, oer_type_fn type_cb)
963 return dissect_oer_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
966 /*--- proto_register_oer ----------------------------------------------*/
967 void proto_register_oer(void) {
969 /* List of fields */
970 static hf_register_info hf[] = {
971 { &hf_oer_optional_field_bit,
972 { "Optional Field Bit", "oer.optional_field_bit",
973 FT_UINT8, BASE_DEC, NULL, 0x0,
974 NULL, HFILL }
976 { &hf_oer_class,
977 { "Class", "oer.class",
978 FT_UINT8, BASE_DEC, VALS(oer_class_vals), 0x0,
979 NULL, HFILL }
981 { &hf_oer_tag,
982 { "Tag", "oer.tag",
983 FT_UINT32, BASE_DEC, NULL, 0x0,
984 NULL, HFILL }
986 { &hf_oer_length_determinant,
987 { "length_determinant", "oer.length_determinant",
988 FT_UINT32, BASE_DEC, NULL, 0x0,
989 NULL, HFILL }
991 { &hf_oer_extension_present_bit,
992 { "Extension Present Bit", "oer.extension_present_bit",
993 FT_UINT8, BASE_DEC, VALS(oer_extension_present_bit_vals), 0x00,
994 NULL, HFILL } },
995 { &hf_oer_open_type_length,
996 { "Open Type Length", "oer.open_type_length",
997 FT_UINT32, BASE_DEC, NULL, 0x0,
998 NULL, HFILL }
1003 /* List of subtrees hf_oer_extension*/
1004 static int *ett[] = {
1005 &ett_oer,
1006 &ett_oer_sequence_of_item,
1007 &ett_oer_open_type,
1010 module_t *oer_module;
1011 expert_module_t* expert_oer;
1013 /* Register protocol */
1014 proto_oer = proto_register_protocol(PNAME, PSNAME, PFNAME);
1016 /* Register fields and subtrees */
1017 proto_register_field_array(proto_oer, hf, array_length(hf));
1018 proto_register_subtree_array(ett, array_length(ett));
1020 static ei_register_info ei[] = {
1021 { &ei_oer_not_decoded_yet,
1022 { "oer.not_decoded_yet", PI_UNDECODED, PI_WARN, "Not decoded yet", EXPFILL }},
1023 { &ei_oer_undecoded,
1024 { "oer.error.undecoded", PI_UNDECODED, PI_WARN, "OER: Something unknown here", EXPFILL } },
1025 { &ei_oer_open_type,
1026 { "oer.open_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown Open Type", EXPFILL }},
1029 expert_oer = expert_register_protocol(proto_oer);
1030 expert_register_field_array(expert_oer, ei, array_length(ei));
1032 oer_module = prefs_register_protocol(proto_oer, NULL);
1033 prefs_register_bool_preference(oer_module, "display_internal_oer_fields",
1034 "Display the internal OER fields in the tree",
1035 "Whether the dissector should put the internal OER data in the tree or if it should hide it",
1036 &display_internal_oer_fields);
1039 proto_set_cant_toggle(proto_oer);
1044 /*--- proto_reg_handoff_oer -------------------------------------------*/
1045 void proto_reg_handoff_oer(void) {
1050 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1052 * Local variables:
1053 * c-basic-offset: 4
1054 * tab-width: 8
1055 * indent-tabs-mode: nil
1056 * End:
1058 * vi: set shiftwidth=4 tabstop=8 expandtab:
1059 * :indentSize=4:tabSize=8:noTabs=true: