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.
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)"
32 void proto_register_oer(void);
33 void proto_reg_handoff_oer(void);
35 /* Initialize the protocol and registered fields */
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 */
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.
74 oer_tvb_new_subset_length(tvbuff_t
*tvb
, const int backing_offset
, const int backing_length
)
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
);
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*/
92 index_get_optional_name(const oer_sequence_t
*sequence
, int idx
)
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
)) {
100 hfi
= proto_registrar_get_nth(*sequence
[i
].p_id
);
101 return (hfi
) ? hfi
->name
: "<unknown field>";
106 return "<unknown type>";
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 */
122 dissect_oer_length_determinant(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, uint32_t *length
)
125 uint8_t oct
, value_len
;
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) {
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
);
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;
159 *length
= tvb_get_uint8(tvb
, offset
);
163 *length
= tvb_get_ntohs(tvb
, offset
);
167 *length
= tvb_get_ntoh24(tvb
, offset
);
171 *length
= tvb_get_ntohl(tvb
, offset
);
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
);
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
)
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
);
194 *bool_val
= (bool)val
;
200 /* 10 Encoding of integer values */
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");
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.
214 proto_tree_add_item_ret_uint(tree
, hf_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &val
);
216 } else if (max
< 0x10000) {
218 proto_tree_add_item_ret_uint(tree
, hf_index
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &val
);
220 } else if (max
== 0xFFFFFFFF) {
222 proto_tree_add_item_ret_uint(tree
, hf_index
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &val
);
225 /* To large not handlet yet*/
226 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer to large value");
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
);
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
);
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
);
250 /* To large not handlet yet*/
251 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer to large value");
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_
)
269 /* XXX Negative numbers ???*/
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.
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
);
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
);
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
);
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
);
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");
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");
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_
)
316 /* Negative numbers ???*/
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
);
327 proto_tree_add_item_ret_uint64(tree
, hf_index
, tvb
, offset
, length
, ENC_BIG_ENDIAN
, &val
);
330 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer NO_BOUND to many octets");
333 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer unexpected length");
345 dissect_oer_integer(tvbuff_t
*tvb
, uint32_t offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
, int32_t *value
)
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
);
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. */
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
)) {
368 for (unsigned i
= 0; i
< length
; i
++) {
369 val
= ((uint32_t)val
<< 8) | tvb_get_uint8(tvb
, offset
);
373 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer NO_BOUND too many octets");
376 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, "constrained_integer unexpected length");
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
);
387 DISSECTOR_ASSERT_NOT_REACHED();
398 /* 11 Encoding of enumerated values */
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
;
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
);
417 /* 13 Encoding of bitstring values */
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.
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
);
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_
)
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
);
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
;
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
) {
470 /* 14 Encoding of octet string values */
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
)
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
);
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
);
492 *value_tvb
= oer_tvb_new_subset_length(tvb
, offset
, length
);
495 offset
= offset
+ length
;
501 /* 15 Encoding of the null value */
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. */
508 ti_tmp
= proto_tree_add_item(tree
, hf_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
509 proto_item_append_text(ti_tmp
, ": NULL");
514 static const value_string oer_class_vals
[] = {
516 { 1, "application" },
517 { 2, "context-specific" },
522 static const value_string oer_extension_present_bit_vals
[] = {
523 { 0, "Not present" },
530 /* 16 Encoding of sequence values */
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
;
537 uint32_t old_offset
= offset
;
538 uint32_t i
, j
, num_opts
;
539 uint32_t optional_mask
[SEQ_MAX_COMPONENTS
>> 5];
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; ?? */
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
);
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.
568 for (i
= 0; sequence
[i
].p_id
; i
++) {
569 if ((sequence
[i
].extension
!= ASN1_NOT_EXTENSION_ROOT
) && (sequence
[i
].optional
== ASN1_OPTIONAL
)) {
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
);
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;
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
) {
602 is_present
= (0x80000000 >> (j
& 0x1f))&optional_mask
[j
>> 5];
609 if (sequence
[i
].func
) {
610 offset
= sequence
[i
].func(tvb
, offset
, actx
, tree
, *sequence
[i
].p_id
);
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 */
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 */
625 for (seq_pos
= 0; sequence
[seq_pos
].p_id
; seq_pos
++) {
626 if (sequence
[seq_pos
].extension
== ASN1_NOT_EXTENSION_ROOT
) {
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;
635 /* If any extensions still known - use functions */
636 if (sequence
[seq_pos
].p_id
) {
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
);
642 dissect_oer_not_decoded_yet(tree
, actx
->pinfo
, tvb
, index_get_field_name(sequence
, seq_pos
));
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
) {
657 proto_item_set_len(item
, offset
- old_offset
);
658 actx
->created_item
= item
;
662 /* 17 Encoding of sequence-of values */
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
)
669 DEBUG_ENTRY("dissect_oer_sequence_of_helper");
670 for (i
= 0; i
<length
; i
++) {
671 uint32_t lold_offset
= offset
;
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
);
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
)
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
);
705 occurrence
= tvb_get_uint8(tvb
, offset
);
708 occurrence
= tvb_get_ntohs(tvb
, offset
);
711 occurrence
= tvb_get_ntoh24(tvb
, offset
);
714 occurrence
= tvb_get_ntohl(tvb
, offset
);
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");
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
);
740 /* As we are using the per ASN1 generator define this "dummy" function */
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 */
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;
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
);
767 tag
= tvb_get_bits8(tvb
, bit_offset
, 6);
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.*/
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");
778 /* Bits 7 to 1 of the first subsequent octet shall not be all set to 0.*/
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
);
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.
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
) {
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
);
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
);
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).
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
,
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
);
851 proto_item_append_text(actx
->created_item
, " (%s)", str
);
856 DISSECTOR_ASSERT_NOT_REACHED();
860 *value_tvb
= tvb_new_subset_length(tvb
, offset
, length
);
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.
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_
)
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
)){
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
;
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_
)
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
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.
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");
944 ((oer_type_fn
)type_cb
)(val_tvb
, 0, actx
, tree
, hf_index
);
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
);
950 case CB_DISSECTOR_HANDLE
:
955 actx
->created_item
= proto_tree_add_expert(tree
, actx
->pinfo
, &ei_oer_open_type
, tvb
, start_offset
, offset
- start_offset
);
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) {
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,
977 { "Class", "oer.class",
978 FT_UINT8
, BASE_DEC
, VALS(oer_class_vals
), 0x0,
983 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
986 { &hf_oer_length_determinant
,
987 { "length_determinant", "oer.length_determinant",
988 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
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,
995 { &hf_oer_open_type_length
,
996 { "Open Type Length", "oer.open_type_length",
997 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1003 /* List of subtrees hf_oer_extension*/
1004 static int *ett
[] = {
1006 &ett_oer_sequence_of_item
,
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
1055 * indent-tabs-mode: nil
1058 * vi: set shiftwidth=4 tabstop=8 expandtab:
1059 * :indentSize=4:tabSize=8:noTabs=true: