1 /*
2 XXX all this offset>>3 and calculations of bytes in the tvb everytime
3 we put something in the tree is just silly.  should be replaced with some
4 proper helper routines
5 */
6 /* packet-per.c
7  * Routines for dissection of ASN.1 Aligned PER
8  * 2003  Ronnie Sahlberg
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * SPDX-License-Identifier: GPL-2.0-or-later
15  */
16 
17 #include "config.h"
18 
19 #include <math.h>
20 
21 #include <epan/packet.h>
22 #include <epan/exceptions.h>
23 #include <epan/oids.h>
24 #include <epan/to_str.h>
25 #include <epan/asn1.h>
26 #include <epan/expert.h>
27 #include <wsutil/str_util.h>
28 #include "packet-per.h"
29 
30 void proto_register_per(void);
31 
32 static int proto_per = -1;
33 static int hf_per_GeneralString_length = -1;
34 static int hf_per_extension_bit = -1;
35 static int hf_per_extension_present_bit = -1;
36 static int hf_per_choice_index = -1;
37 static int hf_per_choice_extension_index = -1;
38 static int hf_per_enum_index = -1;
39 static int hf_per_enum_extension_index = -1;
40 static int hf_per_num_sequence_extensions = -1;
41 static int hf_per_small_number_bit = -1;
42 static int hf_per_optional_field_bit = -1;
43 static int hf_per_sequence_of_length = -1;
44 static int hf_per_object_identifier_length = -1;
45 static int hf_per_open_type_length = -1;
46 static int hf_per_real_length = -1;
47 static int hf_per_octet_string_length = -1;
48 static int hf_per_bit_string_length = -1;
49 static int hf_per_normally_small_nonnegative_whole_number_length = -1;
50 static int hf_per_const_int_len = -1;
51 static int hf_per_direct_reference = -1; /* T_direct_reference */
52 static int hf_per_indirect_reference = -1; /* T_indirect_reference */
53 static int hf_per_data_value_descriptor = -1; /* T_data_value_descriptor */
54 static int hf_per_encoding = -1; /* External_encoding */
55 static int hf_per_single_ASN1_type = -1; /* T_single_ASN1_type */
56 static int hf_per_octet_aligned = -1; /* T_octet_aligned */
57 static int hf_per_arbitrary = -1; /* T_arbitrary */
58 static int hf_per_integer_length = -1; /* Show integer length if "show internal per fields" */
59 /* static int hf_per_debug_pos = -1; */
60 static int hf_per_internal_range = -1;
61 static int hf_per_internal_num_bits = -1;
62 static int hf_per_internal_min = -1;
63 static int hf_per_internal_value = -1;
64 
65 static gint ett_per_open_type = -1;
66 static gint ett_per_containing = -1;
67 static gint ett_per_sequence_of_item = -1;
68 static gint ett_per_External = -1;
69 static gint ett_per_External_encoding = -1;
70 static gint ett_per_named_bits = -1;
71 
72 static expert_field ei_per_size_constraint_value = EI_INIT;
73 static expert_field ei_per_size_constraint_too_few = EI_INIT;
74 static expert_field ei_per_size_constraint_too_many = EI_INIT;
75 static expert_field ei_per_choice_extension_unknown = EI_INIT;
76 static expert_field ei_per_sequence_extension_unknown = EI_INIT;
77 static expert_field ei_per_encoding_error = EI_INIT;
78 static expert_field ei_per_oid_not_implemented = EI_INIT;
79 static expert_field ei_per_undecoded = EI_INIT;
80 static expert_field ei_per_field_not_integer = EI_INIT;
81 static expert_field ei_per_external_type = EI_INIT;
82 static expert_field ei_per_open_type = EI_INIT;
83 static expert_field ei_per_open_type_len = EI_INIT;
84 
85 static dissector_table_t per_oid_dissector_table = NULL;
86 
87 /*
88 #define DEBUG_ENTRY(x) \
89 printf("#%u  %s   tvb:0x%08x\n",actx->pinfo->num,x,(int)tvb);
90 */
91 #define DEBUG_ENTRY(x) \
92 	;
93 
94 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
95 
96 /* whether the PER helpers should put the internal PER fields into the tree
97    or not.
98 */
99 static gboolean display_internal_per_fields = FALSE;
100 
101 
102 
103 static const true_false_string tfs_extension_bit = {
104 	"Extension bit is set",
105 	"Extension bit is clear"
106 };
107 static const true_false_string tfs_small_number_bit = {
108 	"The number is small, 0-63",
109 	"The number is large, >63"
110 };
111 
112 
113 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
114 
115 #define SEQ_MAX_COMPONENTS 128
116 
per_check_value(guint32 value,guint32 min_len,guint32 max_len,asn1_ctx_t * actx,proto_item * item,gboolean is_signed)117 static void per_check_value(guint32 value, guint32 min_len, guint32 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
118 {
119 	if ((is_signed == FALSE) && (value > max_len)) {
120 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %u (%u .. %u)", value, min_len, max_len);
121 	} else if ((is_signed == TRUE) && ((gint32)value > (gint32)max_len)) {
122 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %d (%d .. %d)", (gint32)value, (gint32)min_len, (gint32)max_len);
123 	}
124 }
125 
per_check_value64(guint64 value,guint64 min_len,guint64 max_len,asn1_ctx_t * actx,proto_item * item,gboolean is_signed)126 static void per_check_value64(guint64 value, guint64 min_len, guint64 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
127 {
128 	if ((is_signed == FALSE) && (value > max_len)) {
129 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "u (%" G_GINT64_MODIFIER "u .. %" G_GINT64_MODIFIER "u)", value, min_len, max_len);
130 	} else if ((is_signed == TRUE) && ((gint64)value > (gint64)max_len)) {
131 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", (gint64)value, (gint64)min_len, (gint64)max_len);
132 	}
133 }
134 
per_check_items(guint32 cnt,int min_len,int max_len,asn1_ctx_t * actx,proto_item * item)135 static void per_check_items(guint32 cnt, int min_len, int max_len, asn1_ctx_t *actx, proto_item *item)
136 {
137 	if (min_len != NO_BOUND && cnt < (guint32)min_len) {
138 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_few, "Size constraint: too few items: %d (%d .. %d)", cnt, min_len, max_len);
139 	} else if (max_len != NO_BOUND && cnt > (guint32)max_len) {
140 		expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_many, "Size constraint: too many items: %d (%d .. %d)", cnt, min_len, max_len);
141 	}
142 }
143 
144 
dissect_per_not_decoded_yet(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,const char * reason)145 void dissect_per_not_decoded_yet(proto_tree* tree, packet_info* pinfo, tvbuff_t *tvb, const char* reason)
146 {
147 	proto_tree_add_expert_format(tree, pinfo, &ei_per_undecoded, tvb, 0, 0, "something unknown here [%s]",reason);
148 	col_append_fstr(pinfo->cinfo, COL_INFO, "[UNKNOWN PER: %s]", reason);
149 	THROW(ReportedBoundsError);
150 }
151 
152 /* 10 Encoding procedures -------------------------------------------------- */
153 
154 /* 10.2 Open type fields --------------------------------------------------- */
155 static guint32
dissect_per_open_type_internal(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,void * type_cb,asn1_cb_variant variant)156 dissect_per_open_type_internal(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, void* type_cb, asn1_cb_variant variant)
157 {
158 	int type_length, start_offset, end_offset, fragmented_length = 0, pdu_length, pdu_offset;
159 	tvbuff_t *val_tvb = NULL, *pdu_tvb = NULL;
160 	header_field_info *hfi;
161 	proto_tree *subtree = tree;
162 	gboolean is_fragmented;
163 	int captured_pdu_length;
164 
165 	hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
166 
167 	start_offset = offset;
168 	do {
169 		offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length, &is_fragmented);
170 		if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
171 		if (is_fragmented) {
172 			if (fragmented_length == 0) {
173 				pdu_tvb = tvb_new_composite();
174 			}
175 			tvb_composite_append(pdu_tvb, tvb_new_octet_aligned(tvb, offset, 8*type_length));
176 			offset += 8*type_length;
177 			fragmented_length += type_length;
178 		}
179 	} while (is_fragmented);
180 	if (fragmented_length) {
181 		if (type_length) {
182 			tvb_composite_append(pdu_tvb, tvb_new_octet_aligned(tvb, offset, 8*type_length));
183 			fragmented_length += type_length;
184 		}
185 		tvb_composite_finalize(pdu_tvb);
186 		add_new_data_source(actx->pinfo, pdu_tvb, "Fragmented OCTET STRING");
187 		pdu_offset = 0;
188 		pdu_length = fragmented_length;
189 	} else {
190 		pdu_tvb = tvb;
191 		pdu_offset = offset;
192 		pdu_length = type_length;
193 	}
194 	end_offset = offset + type_length * 8;
195 
196 	if (variant==CB_NEW_DISSECTOR) {
197 		if (fragmented_length) {
198 			val_tvb = pdu_tvb;
199 		} else {
200 			if (!pdu_length) {
201 				return end_offset;
202 			}
203 			/* Check if we have a tvb that holds the whole PDU */
204 			captured_pdu_length = tvb_captured_length(pdu_tvb) - (pdu_offset>>3);
205 			if(captured_pdu_length < pdu_length){
206 				val_tvb = tvb_new_octet_aligned(pdu_tvb, pdu_offset, captured_pdu_length * 8);
207 				actx->created_item = proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_open_type_len, tvb, pdu_offset >> 3,
208 					captured_pdu_length,"Open type length(%i) > available data(%i)", pdu_length, captured_pdu_length);
209 				pdu_length = captured_pdu_length;
210 			} else {
211 				val_tvb = tvb_new_octet_aligned(pdu_tvb, pdu_offset, pdu_length * 8);
212 			}
213 			/* Add new data source if the offet was unaligned */
214 			if ((pdu_offset & 7) != 0) {
215 				add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
216 			}
217 		}
218 		if (hfi) {
219 			if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
220 				if (IS_FT_UINT(hfi->type))
221 					actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, pdu_length, pdu_length);
222 				else
223 					actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, pdu_length, pdu_length);
224 				proto_item_append_text(actx->created_item, plurality(pdu_length, " octet", " octets"));
225 			} else {
226 				actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, pdu_length, ENC_BIG_ENDIAN);
227 			}
228 			subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
229 		}
230 	}
231 
232 	if (type_cb) {
233 		switch (variant) {
234 			case CB_ASN1_ENC:
235 				((per_type_fn)type_cb)(pdu_tvb, pdu_offset, actx, tree, hf_index);
236 				break;
237 			case CB_NEW_DISSECTOR:
238 				/* Pas actx->private_data as "data" to the called function */
239 				((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree, actx->private_data);
240 				break;
241 			case CB_DISSECTOR_HANDLE:
242 				break;
243 		}
244 	} else {
245 		actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_open_type, tvb, start_offset>>3, BLEN(start_offset, end_offset));
246 	}
247 
248 	return end_offset;
249 }
250 
251 guint32
dissect_per_open_type(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,per_type_fn type_cb)252 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
253 {
254 	return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
255 }
256 
257 guint32
dissect_per_open_type_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,dissector_t type_cb)258 dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
259 {
260 	return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_NEW_DISSECTOR);
261 }
262 
263 /* 10.9 General rules for encoding a length determinant --------------------
264 
265 	  NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
266 				for some part of the encoding regardless of whether the length count is bounded above
267 				(by PER-visible constraints) or not. The part of the encoding to which the length applies may
268 				be a bit string (with the length count in bits), an octet string (with the length count in octets),
269 				a known-multiplier character string (with the length count in characters), or a list of fields
270 				(with the length count in components of a sequence-of or set-of).
271 
272 	  NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
273 				that is less than 64K, then the constrained whole number encoding is used for the length.
274 				For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
275 				is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
276 		a)	("n" less than 128) a single octet containing "n" with bit 8 set to zero;
277 		b)	("n" less than 16K) two octets containing "n" with bit 8 of the first octet set to 1 and bit 7 set to zero;
278 		c)	(large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
279 			The count "m" is one to four, and the length indicates that a fragment of the material follows
280 			(a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
281 			for the remainder of the material.
282 
283 	  NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
284 			than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
285 			bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
286 			field in the manner described above in Note 2.
287 
288  */
289 guint32
dissect_per_length_determinant(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx _U_,proto_tree * tree,int hf_index,guint32 * length,gboolean * is_fragmented)290 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, guint32 *length, gboolean *is_fragmented)
291 {
292 	guint8 byte;
293 	guint32 len;
294 	proto_item *pi;
295 	int num_bits;
296 	int i, bit, str_length, str_index;
297 	gboolean tmp;
298 
299 	if(!length){
300 		length=&len;
301 	}
302 	if (is_fragmented) {
303 		*is_fragmented = FALSE;
304 	}
305 
306 	/* byte aligned */
307 	if (actx->aligned){
308 		BYTE_ALIGN_OFFSET(offset);
309 		byte=tvb_get_guint8(tvb, offset>>3);
310 		offset+=8;
311 	}else{
312 		char *str;
313 		guint32 val;
314 
315 		val = 0;
316 
317 		/* prepare the string (max number of bits + quartet separators + prepended space) */
318 		str_length = 256+64+1;
319 		str=(char *)wmem_alloc(wmem_packet_scope(), str_length+1);
320 		str_index = 0;
321 
322 		str_length = g_snprintf(str, str_length+1, " ");
323 		for(bit=0;bit<((int)(offset&0x07));bit++){
324 			if(bit&&(!(bit%4))){
325 				if (str_index < str_length) str[str_index++] = ' ';
326 			}
327 			if (str_index < str_length) str[str_index++] = '.';
328 		}
329 		/* read the bits for the int */
330 		num_bits = 8;
331 		for(i=0;i<num_bits;i++){
332 			if(bit&&(!(bit%4))){
333 				if (str_index < str_length) str[str_index++] = ' ';
334 			}
335 			if(bit&&(!(bit%8))){
336 				if (str_index < str_length) str[str_index++] = ' ';
337 			}
338 			bit++;
339 			offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
340 			val<<=1;
341 			if(tmp){
342 				val|=1;
343 				if (str_index < str_length) str[str_index++] = '1';
344 				if (i==0) { /* bit 8 is 1, so not a single byte length */
345 					num_bits = 16;
346 				}
347 				else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
348 					if (!is_fragmented) {
349 						*length = 0;
350 						dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained");
351 						return offset;
352 					} else {
353 						num_bits = 8;
354 						*is_fragmented = TRUE;
355 					}
356 				}
357 			} else {
358 				if (str_index < str_length) str[str_index++] = '0';
359 			}
360 		}
361 		str[str_index] = '\0'; /* Terminate string */
362 		if(is_fragmented && *is_fragmented==TRUE){
363 			*length = val&0x3f;
364 			if (*length>4 || *length==0) {
365 				*length = 0;
366 				*is_fragmented = FALSE;
367 				dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
368 				return offset;
369 			}
370 			*length *= 0x4000;
371 			if(hf_index!=-1){
372 				pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
373 				if (display_internal_per_fields)
374 					proto_item_append_text(pi," %s", str);
375 				else
376 					proto_item_set_hidden(pi);
377 			}
378 
379 			return offset;
380 		}
381 		else if((val&0x80)==0 && num_bits==8){
382 			*length = val;
383 			if(hf_index!=-1){
384 				pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
385 				if (display_internal_per_fields)
386 					proto_item_append_text(pi," %s", str);
387 				else
388 					proto_item_set_hidden(pi);
389 			}
390 
391 			return offset;
392 		}
393 		else if (num_bits==16) {
394 			*length = val&0x3fff;
395 			if(hf_index!=-1){
396 				pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
397 				if (display_internal_per_fields)
398 					proto_item_append_text(pi," %s", str);
399 				else
400 					proto_item_set_hidden(pi);
401 			}
402 
403 			return offset;
404 		}
405 		*length = 0;
406 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unaligned");
407 		return offset;
408 
409 	}
410 
411 	/* 10.9.3.6 */
412 	if((byte&0x80)==0){
413 		*length=byte;
414 		if(hf_index!=-1){
415 			pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
416 			if (!display_internal_per_fields) proto_item_set_hidden(pi);
417 		}
418 		return offset;
419 	}
420 
421 	/* 10.9.3.7 */
422 	if((byte&0xc0)==0x80){
423 		*length=(byte&0x3f);
424 		*length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
425 		offset+=8;
426 		if(hf_index!=-1){
427 			pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
428 			if (!display_internal_per_fields) proto_item_set_hidden(pi);
429 		}
430 		return offset;
431 	}
432 	/* 10.9.3.8.1 */
433 	else if (is_fragmented){
434 		*length = byte&0x3f;
435 		if (*length>4 || *length==0) {
436 			*length = 0;
437 			dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
438 			return offset;
439 		}
440 		*length *= 0x4000;
441 		*is_fragmented = TRUE;
442 		if(hf_index!=-1){
443 			pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
444 			if (!display_internal_per_fields) proto_item_set_hidden(pi);
445 		}
446 		return offset;
447 	}
448 	*length = 0;
449 	dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9.3.8.1");
450 	return offset;
451 }
452 
453 /* 10.6   normally small non-negative whole number */
454 static guint32
dissect_per_normally_small_nonnegative_whole_number(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 * length)455 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 *length)
456 {
457 	gboolean small_number, length_bit;
458 	guint32 len, length_determinant;
459 	proto_item *pi;
460 
461 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
462 	if(!length){
463 		length=&len;
464 	}
465 
466 	offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_small_number_bit, &small_number);
467 	if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
468 	if(!small_number){
469 		int i;
470 		/* 10.6.1 */
471 		*length=0;
472 		for(i=0;i<6;i++){
473 			offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
474 			*length<<=1;
475 			if (length_bit) {
476 				*length|=1;
477 			}
478 		}
479 		if(hf_index!=-1){
480 			pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-6)>>3, (offset%8<6)?2:1, *length);
481 			if (!display_internal_per_fields) proto_item_set_hidden(pi);
482 		}
483 		return offset;
484 	}
485 
486 	/* 10.6.2 */
487 	offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_normally_small_nonnegative_whole_number_length, &length_determinant, NULL);
488 	switch (length_determinant) {
489 		case 0:
490 			*length = 0;
491 			break;
492 		case 1:
493 			*length = tvb_get_bits8(tvb, offset, 8);
494 			offset += 8;
495 			break;
496 		case 2:
497 			*length = tvb_get_bits16(tvb, offset, 16, ENC_BIG_ENDIAN);
498 			offset += 16;
499 			break;
500 		case 3:
501 			*length = tvb_get_bits32(tvb, offset, 24, ENC_BIG_ENDIAN);
502 			offset += 24;
503 			break;
504 		case 4:
505 			*length = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN);
506 			offset += 32;
507 			break;
508 		default:
509 			dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_normally_small_nonnegative_whole_number)");
510 			offset += 8*length_determinant;
511 			*length = 0;
512 			return offset;
513 	}
514 	if(hf_index!=-1){
515 		pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-(8*length_determinant))>>3, length_determinant, *length);
516 		if (!display_internal_per_fields) proto_item_set_hidden(pi);
517 	}
518 
519 	return offset;
520 }
521 
522 
523 
524 /* this function reads a GeneralString */
525 /* currently based on pure guesswork since RFC2833 didn't tell me much
526    i guess that the PER encoding for this is a normally-small-whole-number
527    followed by a ascii string.
528 
529    based on pure guesswork.  it looks ok in the only capture i have where
530    there is a 1 byte general string encoded
531 */
532 guint32
dissect_per_GeneralString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)533 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
534 {
535 	guint32 length;
536 
537 	offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_GeneralString_length, &length, NULL);
538 
539 	proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, ENC_BIG_ENDIAN);
540 
541 	offset+=length*8;
542 
543 	return offset;
544 }
545 
546 /* 17 Encoding the null type */
547 guint32
dissect_per_null(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx _U_,proto_tree * tree,int hf_index)548 dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
549 	proto_item *ti_tmp;
550 
551 	ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset>>3, 1, ENC_BIG_ENDIAN);
552 	proto_item_append_text(ti_tmp, ": NULL");
553 
554 	return offset;
555 }
556 
557 /* 19 this function dissects a sequence of */
558 static guint32
dissect_per_sequence_of_helper(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,per_type_fn func,int hf_index,guint32 length)559 dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, per_type_fn func, int hf_index, guint32 length)
560 {
561 	guint32 i;
562 
563 DEBUG_ENTRY("dissect_per_sequence_of_helper");
564 	for(i=0;i<length;i++){
565 		guint32 lold_offset=offset;
566 		proto_item *litem;
567 		proto_tree *ltree;
568 
569 		ltree=proto_tree_add_subtree_format(tree, tvb, offset>>3, 0, ett_per_sequence_of_item, &litem, "Item %d", i);
570 
571 		offset=(*func)(tvb, offset, actx, ltree, hf_index);
572 		proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
573 	}
574 
575 	return offset;
576 }
577 guint32
dissect_per_sequence_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq)578 dissect_per_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
579 {
580 	proto_item *item;
581 	proto_tree *tree;
582 	guint32 old_offset=offset;
583 	guint32 length;
584 	header_field_info *hfi;
585 
586 DEBUG_ENTRY("dissect_per_sequence_of");
587 
588 	/* semi-constrained whole number for number of elements */
589 	/* each element encoded as 10.9 */
590 
591 	offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
592 
593 	hfi = proto_registrar_get_nth(hf_index);
594 	if (IS_FT_UINT(hfi->type)) {
595 		item = proto_tree_add_uint(parent_tree, hf_index, tvb, old_offset>>3, 0, length);
596 		proto_item_append_text(item, (length==1)?" item":" items");
597 	} else {
598 		item=proto_tree_add_item(parent_tree, hf_index, tvb, old_offset>>3, 0, ENC_BIG_ENDIAN);
599 	}
600 	tree=proto_item_add_subtree(item, ett_index);
601 
602 	offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
603 
604 
605 	proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
606 	return offset;
607 }
608 
609 
610 /* XXX we don't do >64k length strings   yet */
611 static guint32
dissect_per_restricted_character_string_sorted(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_,guint16 lb _U_,guint16 ub,const char * alphabet,int alphabet_length,tvbuff_t ** value_tvb)612 dissect_per_restricted_character_string_sorted(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_, guint16 lb _U_, guint16 ub, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
613 {
614 	guint32 length;
615 	gboolean byte_aligned, use_canonical_order;
616 	guint8 *buf;
617 	guint char_pos;
618 	int bits_per_char;
619 	guint32 old_offset;
620 
621 DEBUG_ENTRY("dissect_per_restricted_character_string");
622 
623 	/* xx.x if the length is 0 bytes there will be no encoding */
624 	if(max_len==0){
625 		if (value_tvb) {
626 			*value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0);
627 		}
628 		return offset;
629 	}
630 
631 
632 	if (min_len == NO_BOUND) {
633 		min_len=0;
634 	}
635 
636 
637 	/* 27.5.2 depending of the alphabet length, find how many bits
638 	   are used to encode each character */
639 /* unaligned PER */
640 	if (actx->aligned){
641 
642 		if(alphabet_length<=2){
643 			bits_per_char=1;
644 		} else if(alphabet_length<=4){
645 			bits_per_char=2;
646 		} else if(alphabet_length<=16){
647 			bits_per_char=4;
648 		} else {
649 			bits_per_char=8;
650 		}
651 	}else{
652 		if(alphabet_length<=2){
653 			bits_per_char=1;
654 		} else if(alphabet_length<=4){
655 			bits_per_char=2;
656 		} else if(alphabet_length<=8){
657 			bits_per_char=3;
658 		} else if(alphabet_length<=16){
659 			bits_per_char=4;
660 		} else if(alphabet_length<=32){
661 			bits_per_char=5;
662 		} else if(alphabet_length<=64){
663 			bits_per_char=6;
664 		} else if(alphabet_length<=128){
665 			bits_per_char=7;
666 		} else {
667 			bits_per_char=8;
668 		}
669 	}
670 	/* 27.4	If the type is extensible for PER encodings (see 9.3.16),
671 	 * then a bit-field consisting of a single bit shall be added to the field-list.
672 	 * The single bit shall be set to zero if the value is within the range of the extension root,
673 	 * and to one otherwise. If the value is outside the range of the extension root,
674 	 * then the following encoding shall be as if there was no effective size constraint,
675 	 * and shall have an effective permitted-alphabet constraint that consists of the set of characters
676 	 * of the unconstrained type.
677 	 * 	NOTE - Only the known-multiplier character string types can be extensible for PER encodings.
678 	 * Extensibility markers on other character string types do not affect the PER encoding.
679 	 */
680 
681 	if (has_extension) {
682 		gboolean extension_present;
683 		offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
684 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
685 		if(extension_present){
686 			min_len = NO_BOUND;
687 			max_len = NO_BOUND;
688 		}
689 	}
690 
691 	byte_aligned=TRUE;
692 	if((min_len==max_len)&&(max_len<=2)){
693 		byte_aligned=FALSE;
694 	}
695 	if ((max_len != NO_BOUND) && (max_len < 2)) {
696 		byte_aligned=FALSE;
697 	}
698 
699 	/* xx.x */
700 	length=max_len;
701 	if (max_len == NO_BOUND) {
702 		offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length, NULL);
703 		/* the unconstrained strings are always byte aligned (27.6.3)*/
704 		byte_aligned=TRUE;
705 	} else if(min_len!=max_len){
706 		offset=dissect_per_constrained_integer(tvb, offset, actx,
707 			tree, hf_per_octet_string_length, min_len, max_len,
708 			&length, FALSE);
709 			if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
710 	}
711 
712 	if(!length){
713 		/* there is no string at all, so don't do any byte alignment */
714 		/* byte_aligned=FALSE; */
715 		/* Advance offset to next 'element' */
716 		offset = offset + 1;	}
717 
718 	if((byte_aligned)&&(actx->aligned)){
719 		BYTE_ALIGN_OFFSET(offset);
720 	}
721 
722 	/* 30.5: if "ub" is less than or equal to 2^b-1, then "v" is the value specified in above , else
723 	   the characters are placed in the canonical order defined in ITU-T Rec. X.680 | ISO/IEC 8824-1,
724 	   clause 43. The first is assigned the value zero and the next in canonical order is assigned a value
725 	   that is one greater than the value assigned to the previous character in the canonical order. These are the values "v" */
726 	use_canonical_order = (ub <= ((guint16)(1<<bits_per_char)-1)) ? FALSE : TRUE;
727 
728 	buf = (guint8 *)wmem_alloc(actx->pinfo->pool, length+1);
729 	old_offset=offset;
730 	for(char_pos=0;char_pos<length;char_pos++){
731 		guchar val;
732 		int i;
733 		gboolean bit;
734 
735 		val=0;
736 		for(i=0;i<bits_per_char;i++){
737 			offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
738 			val=(val<<1)|bit;
739 		}
740 		if(use_canonical_order == FALSE){
741 			buf[char_pos]=val;
742 		} else {
743 			if (val < alphabet_length){
744 				buf[char_pos]=alphabet[val];
745 			} else {
746 				buf[char_pos] = '?';	/* XXX - how to mark this? */
747 			}
748 		}
749 	}
750 	buf[char_pos]=0;
751 	proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), (char*)buf);
752 	if (value_tvb) {
753 		*value_tvb = tvb_new_child_real_data(tvb, buf, length, length);
754 	}
755 	return offset;
756 }
757 
758 static const char*
sort_alphabet(char * sorted_alphabet,const char * alphabet,int alphabet_length)759 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length)
760 {
761 	int i, j;
762 	guchar c, c_max, c_min;
763 	char tmp_buf[256];
764 
765 	/*
766 	 * XXX - presumably all members of alphabet will be in the
767 	 * range 0 to 127.
768 	 */
769 	if (!alphabet_length) return sorted_alphabet;
770 	memset(tmp_buf, 0, 256);
771 	c_min = c_max = (guchar)alphabet[0];
772 	for (i=0; i<alphabet_length; i++) {
773 		c = (guchar)alphabet[i];
774 		tmp_buf[c] = 1;
775 		if (c > c_max) c_max = c;
776 		else if (c < c_min) c_min = c;
777 	}
778 	for (i=c_min,j=0; i<=c_max; i++) {
779 		if (tmp_buf[i]) sorted_alphabet[j++] = i;
780 	}
781 	return sorted_alphabet;
782 }
783 
784 guint32
dissect_per_restricted_character_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,const char * alphabet,int alphabet_length,tvbuff_t ** value_tvb)785 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
786 {
787 	const char *alphabet_ptr;
788 	char sorted_alphabet[128];
789 
790 	if (alphabet_length > 127) {
791 		alphabet_ptr = alphabet;
792 	} else {
793 		alphabet_ptr = sort_alphabet(sorted_alphabet, alphabet, alphabet_length);
794 	}
795 	/* Not a known-multiplier character string: enforce lb and ub to max values */
796 	return dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, 0, 65535, alphabet_ptr, alphabet_length, value_tvb);
797 }
798 
799 guint32
dissect_per_IA5String(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)800 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
801 {
802 	offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
803 		0, 127, NULL, 128, NULL);
804 
805 	return offset;
806 }
807 
808 guint32
dissect_per_NumericString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)809 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
810 {
811 	offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
812 		32, 57, " 0123456789", 11, NULL);
813 
814 	return offset;
815 }
816 guint32
dissect_per_PrintableString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)817 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
818 {
819 	offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
820 		32, 122, " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL);
821 	return offset;
822 }
823 guint32
dissect_per_VisibleString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)824 dissect_per_VisibleString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
825 {
826 	offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
827 		32, 126, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL);
828 	return offset;
829 }
830 guint32
dissect_per_BMPString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_)831 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
832 {
833 	guint32 length;
834 
835 	/* xx.x if the length is 0 bytes there will be no encoding */
836 	if(max_len==0){
837 		return offset;
838 	}
839 
840 
841 	if (min_len == NO_BOUND) {
842 		min_len = 0;
843 	}
844 
845 
846 	/* xx.x */
847 	length=max_len;
848 	if(min_len!=max_len){
849 		offset=dissect_per_constrained_integer(tvb, offset, actx,
850 			tree, hf_per_octet_string_length, min_len, max_len,
851 			&length, FALSE);
852 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
853 	}
854 
855 
856 	/* align to byte boundary */
857 	BYTE_ALIGN_OFFSET(offset);
858 
859 	if(length>=1024){
860 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "BMPString too long");
861 		length=1024;
862 	}
863 
864 	proto_tree_add_item(tree, hf_index, tvb, offset>>3, length*2, ENC_UCS_2|ENC_BIG_ENDIAN);
865 
866 	offset+=(length<<3)*2;
867 
868 	return offset;
869 }
870 guint32
dissect_per_UTF8String(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_)871 dissect_per_UTF8String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
872 {
873 	offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree,
874 		hf_index, min_len, max_len, has_extension, 0, 255, NULL, 256, NULL);
875 	return offset;
876 }
877 
878 guint32
dissect_per_object_descriptor(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)879 dissect_per_object_descriptor(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
880 {
881 	offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, -1, -1, FALSE, value_tvb);
882 
883 	return offset;
884 }
885 
886 
887 /* this function dissects a constrained sequence of */
888 guint32
dissect_per_constrained_sequence_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq,int min_len,int max_len,gboolean has_extension _U_)889 dissect_per_constrained_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension _U_)
890 {
891 	proto_item *item;
892 	proto_tree *tree;
893 	guint32 old_offset=offset;
894 	guint32 length;
895 	header_field_info *hfi;
896 
897 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
898 
899 	/* 19.4	If there is a PER-visible constraint and an extension marker is present in it,
900 	 * a single bit shall be added to the field-list in a bit-field of length one
901 	 */
902 	if (has_extension) {
903 		gboolean extension_present;
904 		offset=dissect_per_boolean(tvb, offset, actx, parent_tree, hf_per_extension_present_bit, &extension_present);
905 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
906 		if (extension_present){
907 			/* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
908 			 * followed by the component values
909 			 */
910 			offset = dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
911 			goto call_sohelper;
912 		}
913 	}
914 
915 	/* 19.5 if min==max and min,max<64k ==> no length determinant */
916 	if((min_len==max_len) && (min_len<65536)){
917 		length=min_len;
918 		goto call_sohelper;
919 	}
920 
921 	/* 19.6 ub>=64k or unset */
922 	if ((max_len >= 65536) || (max_len == NO_BOUND)) {
923 		/* no constraint, see 10.9.4.2 */
924 		offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
925 		goto call_sohelper;
926 	}
927 
928 	/* constrained whole number for number of elements */
929 	offset=dissect_per_constrained_integer(tvb, offset, actx,
930 		parent_tree, hf_per_sequence_of_length, min_len, max_len,
931 		&length, FALSE);
932 	if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
933 
934 call_sohelper:
935 	hfi = proto_registrar_get_nth(hf_index);
936 	if (IS_FT_UINT(hfi->type)) {
937 		item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
938 		proto_item_append_text(item, (length==1)?" item":" items");
939 	} else {
940 		item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
941 	}
942 	tree=proto_item_add_subtree(item, ett_index);
943 	per_check_items(length, min_len, max_len, actx, item);
944 
945 	old_offset = offset;
946 	offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
947 
948 	if (offset == old_offset)
949 		length = 0;
950 	else if (offset >> 3 == old_offset >> 3)
951 			length = 1;
952 		else
953 			length = (offset >> 3) - (old_offset >> 3);
954 
955 	proto_item_set_len(item, length);
956 	return offset;
957 }
958 
959 /* this function dissects a constrained set of */
960 guint32
dissect_per_constrained_set_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq,int min_len,int max_len,gboolean has_extension)961 dissect_per_constrained_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension)
962 {
963 	/* for basic-per  a set-of is encoded in the same way as a sequence-of */
964 DEBUG_ENTRY("dissect_per_constrained_set_of");
965 	offset=dissect_per_constrained_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq, min_len, max_len, has_extension);
966 	return offset;
967 }
968 
969 
970 
971 
972 
973 
974 /* this function dissects a set of */
975 guint32
dissect_per_set_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq)976 dissect_per_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
977 {
978 	/* for basic-per  a set-of is encoded in the same way as a sequence-of */
979 DEBUG_ENTRY("dissect_per_set_of");
980 	offset=dissect_per_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
981 	return offset;
982 }
983 
984 
985 
986 
987 /* 23 Encoding the object identifier type */
988 static guint32
dissect_per_any_oid(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb,gboolean is_absolute)989 dissect_per_any_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb,
990 		    gboolean is_absolute)
991 {
992 	guint length;
993 	const char *str;
994 	tvbuff_t *val_tvb = NULL;
995 	header_field_info *hfi;
996 
997 	DEBUG_ENTRY("dissect_per_any_oid");
998 
999 	offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_object_identifier_length, &length, NULL);
1000 	if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1001 	val_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
1002 	/* Add new data source if the offet was unaligned */
1003 	if ((offset & 7) != 0) {
1004 		add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
1005 	}
1006 
1007 	hfi = proto_registrar_get_nth(hf_index);
1008 	if ((is_absolute && hfi->type == FT_OID) || (is_absolute && hfi->type == FT_REL_OID)) {
1009 		actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, length, ENC_BIG_ENDIAN);
1010 	} else if (IS_FT_STRING(hfi->type)) {
1011 		str = oid_encoded2string(wmem_packet_scope(), tvb_get_ptr(val_tvb, 0, length), length);
1012 		actx->created_item = proto_tree_add_string(tree, hf_index, val_tvb, 0, length, str);
1013 	} else {
1014 		DISSECTOR_ASSERT_NOT_REACHED();
1015 	}
1016 
1017 	if (value_tvb) *value_tvb = val_tvb;
1018 
1019 	offset += 8 * length;
1020 
1021 	return offset;
1022 }
1023 
1024 guint32
dissect_per_object_identifier(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)1025 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
1026 {
1027 	return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, TRUE);
1028 }
1029 
1030 guint32
dissect_per_relative_oid(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)1031 dissect_per_relative_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
1032 {
1033 	return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, FALSE);
1034 }
1035 
1036 static guint32
dissect_per_any_oid_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx,gboolean is_absolute)1037 dissect_per_any_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx,
1038 			gboolean is_absolute)
1039 {
1040 	tvbuff_t *value_tvb = NULL;
1041 	guint length;
1042 
1043 	offset = dissect_per_any_oid(tvb, offset, actx, tree, hf_index, (value_stringx) ? &value_tvb : NULL, is_absolute);
1044 
1045 	if (value_stringx) {
1046 		if (value_tvb && (length = tvb_captured_length(value_tvb))) {
1047 			*value_stringx = oid_encoded2string(wmem_packet_scope(), tvb_get_ptr(value_tvb, 0, length), length);
1048 		} else {
1049 			*value_stringx = "";
1050 		}
1051 	}
1052 
1053 	return offset;
1054 }
1055 
1056 guint32
dissect_per_object_identifier_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx)1057 dissect_per_object_identifier_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1058 {
1059 	return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, TRUE);
1060 }
1061 
1062 guint32
dissect_per_relative_oid_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx)1063 dissect_per_relative_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1064 {
1065 	return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, FALSE);
1066 }
1067 
1068 
1069 /* this function reads a single bit */
1070 guint32
dissect_per_boolean(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gboolean * bool_val)1071 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gboolean *bool_val)
1072 {
1073 	guint8 ch, mask;
1074 	gboolean value;
1075 	header_field_info *hfi;
1076 
1077 DEBUG_ENTRY("dissect_per_boolean");
1078 
1079 	ch=tvb_get_guint8(tvb, offset>>3);
1080 	mask=1<<(7-(offset&0x07));
1081 	if(ch&mask){
1082 		value=1;
1083 	} else {
1084 		value=0;
1085 	}
1086 	if(hf_index!=-1){
1087 		char bits[10];
1088 		bits[0] = mask&0x80?'0'+value:'.';
1089 		bits[1] = mask&0x40?'0'+value:'.';
1090 		bits[2] = mask&0x20?'0'+value:'.';
1091 		bits[3] = mask&0x10?'0'+value:'.';
1092 		bits[4] = ' ';
1093 		bits[5] = mask&0x08?'0'+value:'.';
1094 		bits[6] = mask&0x04?'0'+value:'.';
1095 		bits[7] = mask&0x02?'0'+value:'.';
1096 		bits[8] = mask&0x01?'0'+value:'.';
1097 		bits[9] = '\0';
1098 
1099 		hfi = proto_registrar_get_nth(hf_index);
1100 		actx->created_item = proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value,
1101 								   "%s %s: %s", bits, hfi->name,
1102 								   value?"True":"False");
1103 	} else {
1104 		actx->created_item = NULL;
1105 	}
1106 
1107 	if(bool_val){
1108 		*bool_val=value;
1109 	}
1110 	return offset+1;
1111 }
1112 
1113 
1114 
1115 
1116 /* we currently only handle integers up to 32 bits in length. */
1117 guint32
dissect_per_integer(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint32 * value)1118 dissect_per_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint32 *value)
1119 {
1120 	guint32 i, length;
1121 	guint32 val;
1122 	tvbuff_t *val_tvb=NULL;
1123 	proto_item *it=NULL;
1124 	header_field_info *hfi;
1125 
1126 	/* 12.2.6 b */
1127 	offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length, NULL);
1128 	/* gassert here? */
1129 	if(length>4){
1130 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_integer)");
1131 		length=4;
1132 	}
1133 
1134 	if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1135 	val_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
1136 	val=0;
1137 	for(i=0;i<length;i++){
1138 		if(i==0){
1139 			if(tvb_get_guint8(val_tvb, i)&0x80){
1140 				/* negative number */
1141 				val=0xffffffff;
1142 			} else {
1143 				/* positive number */
1144 				val=0;
1145 			}
1146 		}
1147 		val=(val<<8)|tvb_get_guint8(val_tvb,i);
1148 	}
1149 	offset += length * 8;
1150 
1151 	hfi = proto_registrar_get_nth(hf_index);
1152 	if (! hfi)
1153 		THROW(ReportedBoundsError);
1154 	if (IS_FT_INT(hfi->type)) {
1155 		it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1156 	} else if (IS_FT_UINT(hfi->type)) {
1157 		it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1158 	} else {
1159 		proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_field_not_integer, tvb, (offset>>3)-(length+1), length+1,
1160 										"Field is not an integer: %s", hfi->abbrev);
1161 		REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1162 	}
1163 
1164 
1165 	actx->created_item = it;
1166 
1167 	if(value){
1168 		*value=val;
1169 	}
1170 
1171 	return offset;
1172 }
1173 /* 64 bits experimental version, internal for now */
1174 static guint32
dissect_per_integer64b(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint64 * value)1175 dissect_per_integer64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint64 *value)
1176 {
1177 	guint32 i, length;
1178 	guint64 val;
1179 	proto_item *it=NULL;
1180 	header_field_info *hfi;
1181 
1182 	/* 12.2.6 b */
1183 	offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length, NULL);
1184 	/* gassert here? */
1185 	if(length>8){
1186 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer (64b)");
1187 		length=8;
1188 	}
1189 
1190 	val=0;
1191 	for(i=0;i<length;i++){
1192 		if(i==0){
1193 			if(tvb_get_guint8(tvb, offset>>3)&0x80){
1194 				/* negative number */
1195 				val=G_GUINT64_CONSTANT(0xffffffffffffffff);
1196 			} else {
1197 				/* positive number */
1198 				val=0;
1199 			}
1200 		}
1201 		val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1202 		offset+=8;
1203 	}
1204 
1205 	hfi = proto_registrar_get_nth(hf_index);
1206 	if (! hfi)
1207 		THROW(ReportedBoundsError);
1208 	if (IS_FT_INT(hfi->type)) {
1209 		it=proto_tree_add_int64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, (gint64)val);
1210 	} else if (IS_FT_UINT(hfi->type)) {
1211 		it=proto_tree_add_uint64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1212 	} else {
1213 		proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_field_not_integer, tvb, (offset>>3)-(length+1), length+1,
1214 										"Field is not an integer: %s", hfi->abbrev);
1215 		REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1216 	}
1217 
1218 
1219 	actx->created_item = it;
1220 
1221 	if(value){
1222 		*value=(gint64)val;
1223 	}
1224 
1225 	return offset;
1226 }
1227 /* this function reads a constrained integer  with or without a
1228    PER visible extension marker present
1229 
1230    has_extension==TRUE  would map to asn constructs such as:
1231 		rfc-number	INTEGER (1..32768, ...)
1232    while has_extension==FALSE would map to:
1233 		t35CountryCode	INTEGER (0..255)
1234 
1235    it only handles integers that fit inside a 32 bit integer
1236 10.5.1 info only
1237 10.5.2 info only
1238 10.5.3 range=ub-lb+1
1239 10.5.4 empty range
1240 10.5.5 info only
1241 	10.5.6 unaligned version
1242 10.5.7 aligned version
1243 10.5.7.1 decoding of 0-255 1-8 bits
1244 10.5.7.2 decoding og 0-256 8 bits
1245 10.5.7.3 decoding of 0-65535 16 bits
1246 	10.5.7.4
1247 */
1248 guint32
dissect_per_constrained_integer(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 min,guint32 max,guint32 * value,gboolean has_extension)1249 dissect_per_constrained_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 min, guint32 max, guint32 *value, gboolean has_extension)
1250 {
1251 	proto_item *it=NULL;
1252 	guint32 range, val;
1253 	gint val_start, val_length;
1254 	nstime_t timeval;
1255 	header_field_info *hfi;
1256 	int num_bits;
1257 
1258 DEBUG_ENTRY("dissect_per_constrained_integer");
1259 	if(has_extension){
1260 		gboolean extension_present;
1261 		offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1262 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1263 		if(extension_present){
1264 			offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, (gint32*)value);
1265 			return offset;
1266 		}
1267 	}
1268 
1269 	hfi = proto_registrar_get_nth(hf_index);
1270 
1271 	/* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb"   1), and let the value to be encoded be "n".
1272 	 * 10.5.7	In the case of the ALIGNED variant the encoding depends on whether
1273 	 *			d)	"range" is greater than 64K (the indefinite length case).
1274 	 */
1275 	if(((max-min)>65536)&&(actx->aligned)){
1276 		/* just set range really big so it will fall through
1277 		   to the bottom of the encoding */
1278 		range=1000000;
1279 	} else {
1280 		/* Really ugly hack.
1281 		 * We should really use guint64 as parameters for min/max.
1282 		 * This is to prevent range from being 0 if
1283 		 * the range for a signed integer spans the entire 32 bit range.
1284 		 * Special case the 2 common cases when this can happen until
1285 		 * a real fix is implemented.
1286 		 */
1287 		if( (max==0x7fffffff && min==0x80000000)
1288 		||  (max==0xffffffff && min==0x00000000) ){
1289 			range=0xffffffff;
1290 		} else {
1291 			range=max-min+1;
1292 		}
1293 	}
1294 
1295 	val=0;
1296 	timeval.secs=val; timeval.nsecs=0;
1297 	/* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1298 
1299 	/* something is really wrong if range is 0 */
1300 	DISSECTOR_ASSERT(range!=0);
1301 
1302 	if(range==1){
1303 		val_start = offset>>3; val_length = 0;
1304 		val = min;
1305 	} else if((range<=255)||(!actx->aligned)) {
1306 		/* 10.5.7.1
1307 		 * 10.5.6	In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1308 		 * as a non-negative  binary integer in a bit field as specified in 10.3 with the minimum
1309 		 * number of bits necessary to represent the range.
1310 		 */
1311 		char *str;
1312 		int i, length;
1313 		guint32 mask,mask2;
1314 		/* We only handle 32 bit integers */
1315 		mask  = 0x80000000;
1316 		mask2 = 0x7fffffff;
1317 		i = 32;
1318 		while ((range & mask)== 0){
1319 			i = i - 1;
1320 			mask = mask>>1;
1321 			mask2 = mask2>>1;
1322 		}
1323 		if ((range & mask2) == 0)
1324 			i = i-1;
1325 
1326 		num_bits = i;
1327 		length=(num_bits+7)>>3;
1328 		if(range<=2){
1329 			num_bits=1;
1330 		}
1331 
1332 		val_start = (offset)>>3;
1333 		val_length = length;
1334 		val = (guint32)tvb_get_bits64(tvb,offset,num_bits,ENC_BIG_ENDIAN);
1335 
1336 		if (display_internal_per_fields){
1337 			str = decode_bits_in_field(actx->pinfo->pool, (offset&0x07),num_bits,val,ENC_BIG_ENDIAN);
1338 			proto_tree_add_uint(tree, hf_per_internal_min, tvb, val_start,val_length, min);
1339 			proto_tree_add_uint64(tree, hf_per_internal_range, tvb, val_start, val_length, range);
1340 			proto_tree_add_uint(tree, hf_per_internal_num_bits, tvb, val_start, val_length, num_bits);
1341 			proto_tree_add_uint64_format_value(tree, hf_per_internal_value, tvb, val_start, val_length, val+min, "%s decimal value: %u", str, val+min);
1342 		}
1343 		/* The actual value */
1344 		val+=min;
1345 		offset = offset+num_bits;
1346 	} else if(range==256){
1347 		/* 10.5.7.2 */
1348 
1349 		/* in the aligned case, align to byte boundary */
1350 		BYTE_ALIGN_OFFSET(offset);
1351 		val=tvb_get_guint8(tvb, offset>>3);
1352 		offset+=8;
1353 
1354 		val_start = (offset>>3)-1; val_length = 1;
1355 		val+=min;
1356 	} else if(range<=65536){
1357 		/* 10.5.7.3 */
1358 
1359 		/* in the aligned case, align to byte boundary */
1360 		BYTE_ALIGN_OFFSET(offset);
1361 		val=tvb_get_guint8(tvb, offset>>3);
1362 		val<<=8;
1363 		offset+=8;
1364 		val|=tvb_get_guint8(tvb, offset>>3);
1365 		offset+=8;
1366 
1367 		val_start = (offset>>3)-2; val_length = 2;
1368 		val+=min;
1369 	} else {
1370 		int i,num_bytes;
1371 		gboolean bit;
1372 
1373 		/* 10.5.7.4 */
1374 		/* 12.2.6 */
1375 		offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1376 		num_bytes=bit;
1377 		offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1378 		num_bytes=(num_bytes<<1)|bit;
1379 
1380 		num_bytes++;  /* lower bound for length determinant is 1 */
1381 		if (display_internal_per_fields)
1382 			proto_tree_add_uint(tree, hf_per_const_int_len, tvb, (offset>>3), 1, num_bytes);
1383 
1384 		/* byte aligned */
1385 		BYTE_ALIGN_OFFSET(offset);
1386 		val=0;
1387 		for(i=0;i<num_bytes;i++){
1388 			val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1389 			offset+=8;
1390 		}
1391 		val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1392 		val+=min;
1393 	}
1394 
1395 	timeval.secs = val;
1396 	if (IS_FT_UINT(hfi->type)) {
1397 		it = proto_tree_add_uint(tree, hf_index, tvb, val_start, val_length, val);
1398 		per_check_value(val, min, max, actx, it, FALSE);
1399 	} else if (IS_FT_INT(hfi->type)) {
1400 		it = proto_tree_add_int(tree, hf_index, tvb, val_start, val_length, val);
1401 		per_check_value(val, min, max, actx, it, TRUE);
1402 	} else if (IS_FT_TIME(hfi->type)) {
1403 		it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1404 	} else {
1405 		THROW(ReportedBoundsError);
1406 	}
1407 	actx->created_item = it;
1408 	if (value) *value = val;
1409 	return offset;
1410 }
1411 
1412 guint32
dissect_per_constrained_integer_64b(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint64 min,guint64 max,guint64 * value,gboolean has_extension)1413 dissect_per_constrained_integer_64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint64 min, guint64 max, guint64 *value, gboolean has_extension)
1414 {
1415 	proto_item *it=NULL, *int_item=NULL;
1416 	guint64 range, val;
1417 	gint val_start, val_length;
1418 	nstime_t timeval;
1419 	header_field_info *hfi;
1420 	int num_bits;
1421 	gboolean tmp;
1422 
1423 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1424 	if(has_extension){
1425 		gboolean extension_present;
1426 		offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1427 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1428 		if(extension_present){
1429 			offset = dissect_per_integer64b(tvb, offset, actx, tree, hf_index, (gint64*)value);
1430 			return offset;
1431 		}
1432 	}
1433 
1434 	hfi = proto_registrar_get_nth(hf_index);
1435 
1436 	/* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb"   1), and let the value to be encoded be "n".
1437 	 * 10.5.7	In the case of the ALIGNED variant the encoding depends on whether
1438 	 *			d)	"range" is greater than 64K (the indefinite length case).
1439 	 */
1440 	if(((max-min)>65536)&&(actx->aligned)){
1441 		/* just set range really big so it will fall through
1442 		   to the bottom of the encoding */
1443 		/* range=1000000; */
1444 		range = max-min;
1445 		if (range==65536)
1446 			range++; /* make it fall trough? */
1447 	} else {
1448 		/* Copied from the 32 bit version, assuming the same problem occurs
1449 		 * at 64 bit boundary.
1450 		 * Really ugly hack.
1451 		 * We should really use guint64 as parameters for min/max.
1452 		 * This is to prevent range from being 0 if
1453 		 * the range for a signed integer spans the entire 32 bit range.
1454 		 * Special case the 2 common cases when this can happen until
1455 		 * a real fix is implemented.
1456 		 */
1457 		if( (max==G_GINT64_CONSTANT(0x7fffffffffffffff) && min==G_GINT64_CONSTANT(0x8000000000000000))
1458 		||  (max==G_GINT64_CONSTANT(0xffffffffffffffff) && min==0) ){
1459 			range=G_GINT64_CONSTANT(0xffffffffffffffff);
1460 		} else {
1461 			range=max-min+1;
1462 		}
1463 	}
1464 
1465 	val=0;
1466 	timeval.secs=0; timeval.nsecs=0;
1467 	/* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1468 
1469 	/* something is really wrong if range is 0 */
1470 	DISSECTOR_ASSERT(range!=0);
1471 
1472 	if(range==1){
1473 		val_start = offset>>3; val_length = 0;
1474 		val = min;
1475 	} else if((range<=255)||(!actx->aligned)) {
1476 		/* 10.5.7.1
1477 		 * 10.5.6	In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1478 		 * as a non-negative  binary integer in a bit field as specified in 10.3 with the minimum
1479 		 * number of bits necessary to represent the range.
1480 		 */
1481 		char *str;
1482 		int i, bit, length, str_length, str_index = 0;
1483 		guint64 mask,mask2;
1484 		/* We only handle 64 bit integers */
1485 		mask  = G_GUINT64_CONSTANT(0x8000000000000000);
1486 		mask2 = G_GUINT64_CONSTANT(0x7fffffffffffffff);
1487 		i = 64;
1488 		while ((range & mask)== 0){
1489 			i = i - 1;
1490 			mask = mask>>1;
1491 			mask2 = mask2>>1;
1492 		}
1493 		if ((range & mask2) == 0)
1494 			i = i-1;
1495 
1496 		num_bits = i;
1497 		length=1;
1498 		if(range<=2){
1499 			num_bits=1;
1500 		}
1501 
1502 		/* prepare the string (max number of bits + quartet separators) */
1503 		str_length = 512+128;
1504 		str = (char *)wmem_alloc(wmem_packet_scope(), str_length+1);
1505 		for(bit=0;bit<((int)(offset&0x07));bit++){
1506 			if(bit&&(!(bit%4))){
1507 				if (str_index < str_length) str[str_index++] = ' ';
1508 			}
1509 			if (str_index < str_length) str[str_index++] = '.';
1510 		}
1511 		/* read the bits for the int */
1512 		for(i=0;i<num_bits;i++){
1513 			if(bit&&(!(bit%4))){
1514 				if (str_index < str_length) str[str_index++] = ' ';
1515 			}
1516 			if(bit&&(!(bit%8))){
1517 				length+=1;
1518 				if (str_index < str_length) str[str_index++] = ' ';
1519 			}
1520 			bit++;
1521 			offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1522 			val<<=1;
1523 			if(tmp){
1524 				val|=1;
1525 				if (str_index < str_length) str[str_index++] = '1';
1526 			} else {
1527 				if (str_index < str_length) str[str_index++] = '0';
1528 			}
1529 		}
1530 		for(;bit%8;bit++){
1531 			if(bit&&(!(bit%4))){
1532 				if (str_index < str_length) str[str_index++] = ' ';
1533 			}
1534 			if (str_index < str_length) str[str_index++] = '.';
1535 		}
1536 		str[str_index] = '\0'; /* Terminate string */
1537 		val_start = (offset-num_bits)>>3; val_length = length;
1538 		val+=min;
1539 		if (display_internal_per_fields) {
1540 			proto_tree_add_uint64(tree, hf_per_internal_range, tvb, val_start, val_length, range);
1541 			proto_tree_add_uint(tree, hf_per_internal_num_bits, tvb, val_start,val_length, num_bits);
1542 			proto_tree_add_uint64_format_value(tree, hf_per_internal_value, tvb, val_start, val_length, val, "%s decimal value: %" G_GINT64_MODIFIER "u", str, val);
1543 		}
1544 	} else if(range==256){
1545 		/* 10.5.7.2 */
1546 
1547 		/* in the aligned case, align to byte boundary */
1548 		BYTE_ALIGN_OFFSET(offset);
1549 		val=tvb_get_guint8(tvb, offset>>3);
1550 		offset+=8;
1551 
1552 		val_start = (offset>>3)-1; val_length = 1;
1553 		val+=min;
1554 	} else if(range<=65536){
1555 		/* 10.5.7.3 */
1556 
1557 		/* in the aligned case, align to byte boundary */
1558 		BYTE_ALIGN_OFFSET(offset);
1559 		val=tvb_get_guint8(tvb, offset>>3);
1560 		val<<=8;
1561 		offset+=8;
1562 		val|=tvb_get_guint8(tvb, offset>>3);
1563 		offset+=8;
1564 
1565 		val_start = (offset>>3)-2; val_length = 2;
1566 		val+=min;
1567 	} else {
1568 		int i,num_bytes,n_bits;
1569 
1570 		/* 10.5.7.4 */
1571 		/* 12.2.6 */
1572 		/* calculate the number of bits to hold the length */
1573 		if ((range & G_GINT64_CONSTANT(0xffffffff00000000)) != 0){
1574 			n_bits=3;
1575 		}else{
1576 			n_bits=2;
1577 		}
1578 		num_bytes =tvb_get_bits8(tvb, offset, n_bits);
1579 		num_bytes++;  /* lower bound for length determinant is 1 */
1580 		if (display_internal_per_fields){
1581 			int_item = proto_tree_add_bits_item(tree, hf_per_const_int_len, tvb, offset,n_bits, ENC_BIG_ENDIAN);
1582 			proto_item_append_text(int_item,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER "u)",num_bytes, range);
1583 		}
1584 		offset = offset+n_bits;
1585 		/* byte aligned */
1586 		BYTE_ALIGN_OFFSET(offset);
1587 		val=0;
1588 		for(i=0;i<num_bytes;i++){
1589 			val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1590 			offset+=8;
1591 		}
1592 		val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1593 		val+=min;
1594 	}
1595 
1596 
1597 	if (IS_FT_UINT(hfi->type)) {
1598 		it = proto_tree_add_uint64(tree, hf_index, tvb, val_start, val_length, val);
1599 		per_check_value64(val, min, max, actx, it, FALSE);
1600 	} else if (IS_FT_INT(hfi->type)) {
1601 		it = proto_tree_add_int64(tree, hf_index, tvb, val_start, val_length, val);
1602 		per_check_value64(val, min, max, actx, it, TRUE);
1603 	} else if (IS_FT_TIME(hfi->type)) {
1604 		timeval.secs = (guint32)val;
1605 		it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1606 	} else {
1607 		THROW(ReportedBoundsError);
1608 	}
1609 	actx->created_item = it;
1610 	if (value) *value = val;
1611 	return offset;
1612 }
1613 
1614 /* 13 Encoding the enumerated type */
1615 guint32
dissect_per_enumerated(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 root_num,guint32 * value,gboolean has_extension,guint32 ext_num,guint32 * value_map)1616 dissect_per_enumerated(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 root_num, guint32 *value, gboolean has_extension, guint32 ext_num, guint32 *value_map)
1617 {
1618 
1619 	proto_item *it=NULL;
1620 	guint32 enum_index, val;
1621 	guint32 start_offset = offset;
1622 	gboolean extension_present = FALSE;
1623 	header_field_info *hfi;
1624 
1625 	if (has_extension) {
1626 		/* Extension bit */
1627 		offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1628 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1629 	}
1630 
1631 	if (!extension_present) {
1632 		/* 13.2  */
1633 		offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_per_enum_index, 0, root_num - 1, &enum_index, FALSE);
1634 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1635 	} else {
1636 		/* 13.3 ".. and the value shall be added to the field-list as a
1637 		 * normally small non-negative whole number whose value is the
1638 		 * enumeration index of the additional enumeration and with "lb" set to 0.."
1639 		 */
1640 		offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_enum_extension_index, &enum_index);
1641 		enum_index += root_num;
1642 	}
1643 	val = (value_map && (enum_index<(root_num+ext_num))) ? value_map[enum_index] : enum_index;
1644 	hfi = proto_registrar_get_nth(hf_index);
1645 	if (IS_FT_UINT(hfi->type)) {
1646 		it = proto_tree_add_uint(tree, hf_index, tvb, start_offset>>3, BLEN(start_offset, offset), val);
1647 	} else {
1648 		THROW(ReportedBoundsError);
1649 	}
1650 	actx->created_item = it;
1651 	if (value) *value = val;
1652 	return offset;
1653 }
1654 
1655 /* 14 Encoding the real type */
1656 guint32
dissect_per_real(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,double * value)1657 dissect_per_real(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, double *value)
1658 {
1659 	guint32 val_length, end_offset;
1660 	tvbuff_t *val_tvb;
1661 	double val = 0;
1662 
1663 	offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_real_length, &val_length, NULL);
1664 	if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1665 	val_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
1666 	/* Add new data source if the offet was unaligned */
1667 	if ((offset & 7) != 0) {
1668 		add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
1669 	}
1670 	end_offset = offset + val_length * 8;
1671 
1672 	val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1673 	actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1674 
1675 	if (value) *value = val;
1676 
1677 	return end_offset;
1678 }
1679 
1680 /* 22 Encoding the choice type */
1681 guint32
dissect_per_choice(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint ett_index,const per_choice_t * choice,gint * value)1682 dissect_per_choice(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint ett_index, const per_choice_t *choice, gint *value)
1683 {
1684 	gboolean /*extension_present,*/ extension_flag;
1685 	int extension_root_entries;
1686 	int extension_addition_entries;
1687 	guint32 choice_index;
1688 	int i, idx, cidx;
1689 	guint32 ext_length = 0;
1690 	guint32 old_offset = offset;
1691 	proto_item *choice_item = NULL;
1692 	proto_tree *choice_tree = NULL;
1693 
1694 DEBUG_ENTRY("dissect_per_choice");
1695 
1696 	if (value) *value = -1;
1697 
1698 	/* 22.5 */
1699 	if (choice[0].extension == ASN1_NO_EXTENSIONS){
1700 		/*extension_present = FALSE; ?? */
1701 		extension_flag = FALSE;
1702 	} else {
1703 		/*extension_present = TRUE; ?? */
1704 		offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1705 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1706 	}
1707 
1708 	/* count the number of entries in the extension root and extension addition */
1709 	extension_root_entries = 0;
1710 	extension_addition_entries = 0;
1711 	for (i=0; choice[i].p_id; i++) {
1712 		switch(choice[i].extension){
1713 			case ASN1_NO_EXTENSIONS:
1714 			case ASN1_EXTENSION_ROOT:
1715 				extension_root_entries++;
1716 				break;
1717 			case ASN1_NOT_EXTENSION_ROOT:
1718 				extension_addition_entries++;
1719 				break;
1720 		}
1721 	}
1722 
1723 	if (!extension_flag) {  /* 22.6, 22.7 */
1724 		if (extension_root_entries == 1) {  /* 22.5 */
1725 			choice_index = 0;
1726 		} else {
1727 			offset = dissect_per_constrained_integer(tvb, offset, actx,
1728 				tree, hf_per_choice_index, 0, extension_root_entries - 1,
1729 				&choice_index, FALSE);
1730 			if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1731 		}
1732 
1733 		idx = -1; cidx = choice_index;
1734 		for (i=0; choice[i].p_id; i++) {
1735 			if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1736 				if (!cidx) { idx = i; break; }
1737 				cidx--;
1738 			}
1739 		}
1740 	} else {  /* 22.8 */
1741 		offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1742 		offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length, NULL);
1743 
1744 		idx = -1; cidx = choice_index;
1745 		for (i=0; choice[i].p_id; i++) {
1746 			if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1747 				if (!cidx) { idx = i; break; }
1748 				cidx--;
1749 			}
1750 		}
1751 	}
1752 
1753 	if (idx != -1) {
1754 		choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[idx].value);
1755 		choice_tree = proto_item_add_subtree(choice_item, ett_index);
1756 		if (!extension_flag) {
1757 			offset = choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1758 		} else {
1759 			choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1760 			offset += ext_length * 8;
1761 		}
1762 		proto_item_set_len(choice_item, BLEN(old_offset, offset));
1763 	} else {
1764 		if (!extension_flag) {
1765 			dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unknown extension root index in choice");
1766 		} else {
1767 			offset += ext_length * 8;
1768 			proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_choice_extension_unknown,
1769 										tvb, old_offset>>3, BLEN(old_offset, offset),
1770 										"Choice no. %d in extension", choice_index);
1771 		}
1772 	}
1773 
1774 	if (value && (idx != -1))
1775 		*value = choice[idx].value;
1776 
1777 	return offset;
1778 }
1779 
1780 
1781 static const char *
index_get_optional_name(const per_sequence_t * sequence,int idx)1782 index_get_optional_name(const per_sequence_t *sequence, int idx)
1783 {
1784 	int i;
1785 	header_field_info *hfi;
1786 
1787 	for(i=0;sequence[i].p_id;i++){
1788 		if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1789 			if (idx == 0) {
1790 				hfi = proto_registrar_get_nth(*sequence[i].p_id);
1791 				return (hfi) ? hfi->name : "<unknown filed>";
1792 			}
1793 			idx--;
1794 		}
1795 	}
1796 	return "<unknown type>";
1797 }
1798 
1799 static const char *
index_get_extension_name(const per_sequence_t * sequence,int idx)1800 index_get_extension_name(const per_sequence_t *sequence, int idx)
1801 {
1802 	int i;
1803 	header_field_info *hfi;
1804 
1805 	for(i=0;sequence[i].p_id;i++){
1806 		if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1807 			if (idx == 0) {
1808 				if (*sequence[i].p_id == -1) return "extension addition group";
1809 				hfi = proto_registrar_get_nth(*sequence[i].p_id);
1810 				return (hfi) ? hfi->name : "<unknown filed>";
1811 			}
1812 			idx--;
1813 		}
1814 	}
1815 	return "<unknown type>";
1816 }
1817 
1818 static const char *
index_get_field_name(const per_sequence_t * sequence,int idx)1819 index_get_field_name(const per_sequence_t *sequence, int idx)
1820 {
1821 	if (sequence) {
1822 		header_field_info *hfi = proto_registrar_get_nth(*sequence[idx].p_id);
1823 
1824 		if (hfi) {
1825 			return hfi->name;
1826 		}
1827 	}
1828 	return "<unknown field>";
1829 }
1830 
1831 /* this functions decodes a SEQUENCE
1832    it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1833 18.1 extension bit
1834 18.2 optional/default items in root
1835 18.3 we ignore the case where n>64K
1836 18.4 the root sequence
1837 	   18.5
1838 	   18.6
1839 	   18.7
1840 	   18.8
1841 	   18.9
1842 */
1843 guint32
dissect_per_sequence(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * sequence)1844 dissect_per_sequence(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *sequence)
1845 {
1846 	gboolean /*extension_present,*/ extension_flag, optional_field_flag;
1847 	proto_item *item;
1848 	proto_tree *tree;
1849 	guint32 old_offset=offset;
1850 	guint32 i, j, num_opts;
1851 	guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
1852 
1853 DEBUG_ENTRY("dissect_per_sequence");
1854 	DISSECTOR_ASSERT(sequence);
1855 
1856 	item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
1857 	tree=proto_item_add_subtree(item, ett_index);
1858 
1859 
1860 	/* first check if there should be an extension bit for this CHOICE.
1861 	   we do this by just checking the first choice arm
1862 	 */
1863 	/* 18.1 */
1864 	extension_flag=0;
1865 	if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1866 		/*extension_present=0;  ?? */
1867 	} else {
1868 		/*extension_present=1; ?? */
1869 		offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1870 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1871 	}
1872 	/* 18.2 */
1873 	num_opts=0;
1874 	for(i=0;sequence[i].p_id;i++){
1875 		if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1876 			num_opts++;
1877 		}
1878 	}
1879 	if (num_opts > SEQ_MAX_COMPONENTS) {
1880 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
1881 	}
1882 
1883 	memset(optional_mask, 0, sizeof(optional_mask));
1884 	for(i=0;i<num_opts;i++){
1885 		offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1886 		if (tree) {
1887 			proto_item_append_text(actx->created_item, " (%s %s present)",
1888 				index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1889 		}
1890 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1891 		if(optional_field_flag){
1892 			optional_mask[i>>5]|=0x80000000>>(i&0x1f);
1893 		}
1894 	}
1895 
1896 
1897 	/* 18.4 */
1898 	for(i=0,j=0;sequence[i].p_id;i++){
1899 		if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1900 		||  (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1901 			if(sequence[i].optional==ASN1_OPTIONAL){
1902 				gboolean is_present;
1903 				if (num_opts == 0){
1904 					continue;
1905 				}
1906 				is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
1907 				num_opts--;
1908 				j++;
1909 				if(!is_present){
1910 					continue;
1911 				}
1912 			}
1913 			if(sequence[i].func){
1914 				offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
1915 			} else {
1916 				dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
1917 			}
1918 		}
1919 	}
1920 
1921 
1922 	if(extension_flag){
1923 		gboolean extension_bit;
1924 		guint32 num_known_extensions;
1925 		guint32 num_extensions;
1926 		guint32 extension_mask;
1927 
1928 		offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
1929 		/* the X.691 standard is VERY unclear here.
1930 		   there is no mention that the lower bound lb for this
1931 		   (apparently) semiconstrained value is 1,
1932 		   apart from the NOTE: comment in 18.8 that this value can
1933 		   not be 0.
1934 		   In my book, there is a semantic difference between having
1935 		   a comment that says that the value can not be zero
1936 		   and stating that the lb is 1.
1937 		   I don't know if this is right or not but it makes
1938 		   some of the very few captures I have decode properly.
1939 
1940 		   It could also be that the captures I have are generated by
1941 		   a broken implementation.
1942 		   If this is wrong and you don't report it as a bug
1943 		   then it won't get fixed!
1944 		*/
1945 		num_extensions+=1;
1946 		if (num_extensions > 32) {
1947 			dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many extensions");
1948 		}
1949 
1950 		extension_mask=0;
1951 		for(i=0;i<num_extensions;i++){
1952 			offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
1953 			if (tree) {
1954 				proto_item_append_text(actx->created_item, " (%s %s present)",
1955 					index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
1956 			}
1957 			if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1958 
1959 			extension_mask=(extension_mask<<1)|extension_bit;
1960 		}
1961 
1962 		/* find how many extensions we know about */
1963 		num_known_extensions=0;
1964 		for(i=0;sequence[i].p_id;i++){
1965 			if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1966 				num_known_extensions++;
1967 			}
1968 		}
1969 
1970 		/* decode the extensions one by one */
1971 		for(i=0;i<num_extensions;i++){
1972 			guint32 length;
1973 			guint32 new_offset;
1974 			gint32 difference;
1975 			guint32 extension_index;
1976 			guint32 k;
1977 
1978 			if(!((1U<<(num_extensions-1-i))&extension_mask)){
1979 				/* this extension is not encoded in this PDU */
1980 				continue;
1981 			}
1982 
1983 			offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length, NULL);
1984 
1985 			if(i>=num_known_extensions){
1986 				/* we don't know how to decode this extension */
1987 				offset+=length*8;
1988 				expert_add_info(actx->pinfo, item, &ei_per_sequence_extension_unknown);
1989 				continue;
1990 			}
1991 
1992 			extension_index=0;
1993 			for(j=0,k=0;sequence[j].p_id;j++){
1994 				if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1995 					if(k==i){
1996 						extension_index=j;
1997 						break;
1998 					}
1999 					k++;
2000 				}
2001 			}
2002 
2003 			if(sequence[extension_index].func){
2004 				new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
2005 				offset+=length*8;
2006 				difference = offset - new_offset;
2007 				/* A difference of 7 or less might be byte aligning */
2008 				/* Difference could be 8 if open type has no bits and the length is 1 */
2009 				if ((length > 1) && (difference > 7)) {
2010 					proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2011 						"Possible encoding error full length not decoded. Open type length %u, decoded %u",length, length - (difference>>3));
2012 				}
2013 				else if (difference < 0) {
2014 					proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2015 						"Possible encoding error open type length less than dissected bits. Open type length %u, decoded %u", length, length - (difference>>3));
2016 				}
2017 			} else {
2018 				dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, extension_index));
2019 				offset+=length*8;
2020 			}
2021 		}
2022 	}
2023 
2024 	proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
2025 	actx->created_item = item;
2026 	return offset;
2027 }
2028 
2029 guint32
dissect_per_sequence_eag(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,const per_sequence_t * sequence)2030 dissect_per_sequence_eag(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, const per_sequence_t *sequence)
2031 {
2032 	gboolean optional_field_flag;
2033 	guint32 i, j, num_opts;
2034 	guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
2035 
2036 DEBUG_ENTRY("dissect_per_sequence_eag");
2037 
2038 	num_opts=0;
2039 	for(i=0;sequence[i].p_id;i++){
2040 		if(sequence[i].optional==ASN1_OPTIONAL){
2041 			num_opts++;
2042 		}
2043 	}
2044 	if (num_opts > SEQ_MAX_COMPONENTS) {
2045 		dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
2046 	}
2047 
2048 	memset(optional_mask, 0, sizeof(optional_mask));
2049 	for(i=0;i<num_opts;i++){
2050 		offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
2051 		if (tree) {
2052 			proto_item_append_text(actx->created_item, " (%s %s present)",
2053 				index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
2054 		}
2055 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2056 		if(optional_field_flag){
2057 			optional_mask[i>>5]|=0x80000000>>(i&0x1f);
2058 		}
2059 	}
2060 
2061 	for(i=0,j=0;sequence[i].p_id;i++){
2062 		if(sequence[i].optional==ASN1_OPTIONAL){
2063 			gboolean is_present;
2064 			if (num_opts == 0){
2065 				continue;
2066 			}
2067 			is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2068 			num_opts--;
2069 			j++;
2070 			if(!is_present){
2071 				continue;
2072 			}
2073 		}
2074 		if(sequence[i].func){
2075 			offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2076 		} else {
2077 			dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2078 		}
2079 	}
2080 
2081 	return offset;
2082 }
2083 
2084 
2085 /* 15 Encoding the bitstring type
2086 
2087    max_len or min_len == NO_BOUND means there is no lower/upper constraint
2088 
2089 */
2090 
dissect_per_bit_string_display(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,header_field_info * hfi,guint32 length,int * const * named_bits,gint num_named_bits _U_)2091 static tvbuff_t *dissect_per_bit_string_display(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, header_field_info *hfi, guint32 length, int * const *named_bits, gint num_named_bits _U_)
2092 {
2093 	tvbuff_t *out_tvb = NULL;
2094 	guint32  pad_length=0;
2095 	guint64  value;
2096 
2097 	out_tvb = tvb_new_octet_aligned(tvb, offset, length);
2098 	add_new_data_source(actx->pinfo, out_tvb, "Bitstring tvb");
2099 
2100 	if (hfi) {
2101 		actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, ENC_BIG_ENDIAN);
2102 		proto_item_append_text(actx->created_item, " [bit length %u", length);
2103 		if (length%8) {
2104 			pad_length = 8-(length%8);
2105 			proto_item_append_text(actx->created_item, ", %u LSB pad bits", pad_length);
2106 		}
2107 
2108 		if (length<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2109 			if (length<=8) {
2110 				value = tvb_get_bits8(out_tvb, 0, length);
2111 			}else if (length<=16) {
2112 				value = tvb_get_bits16(out_tvb, 0, length, ENC_BIG_ENDIAN);
2113 			}else if (length<=24) { /* first read 16 and then the remaining bits */
2114 				value = tvb_get_bits16(out_tvb, 0, 16, ENC_BIG_ENDIAN);
2115 				value <<= 8 - pad_length;
2116 				value |= tvb_get_bits8(out_tvb, 16, length - 16);
2117 			}else if (length<=32) {
2118 				value = tvb_get_bits32(out_tvb, 0, length, ENC_BIG_ENDIAN);
2119 			}else if (length<=40) { /* first read 32 and then the remaining bits */
2120 				value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2121 				value <<= 8 - pad_length;
2122 				value |= tvb_get_bits8(out_tvb, 32, length - 32);
2123 			}else if (length<=48) { /* first read 32 and then the remaining bits */
2124 				value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2125 				value <<= 16 - pad_length;
2126 				value |= tvb_get_bits16(out_tvb, 32, length - 32, ENC_BIG_ENDIAN);
2127 			}else if (length<=56) { /* first read 32 and 16 then the remaining bits */
2128 				value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2129 				value <<= 16;
2130 				value |= tvb_get_bits16(out_tvb, 32, 16, ENC_BIG_ENDIAN);
2131 				value <<= 8 - pad_length;
2132 				value |= tvb_get_bits8(out_tvb, 48, length - 48);
2133 			}else {
2134 				value = tvb_get_bits64(out_tvb, 0, length, ENC_BIG_ENDIAN);
2135 			}
2136 			proto_item_append_text(actx->created_item, ", %s decimal value %" G_GINT64_MODIFIER "u",
2137 				decode_bits_in_field(actx->pinfo->pool, 0, length, value, ENC_BIG_ENDIAN), value);
2138 			if (named_bits) {
2139 				const guint32 named_bits_bytelen = (num_named_bits + 7) / 8;
2140 				proto_tree *subtree = proto_item_add_subtree(actx->created_item, ett_per_named_bits);
2141 				for (guint32 i = 0; i < named_bits_bytelen; i++) {
2142 					// If less data is available than the number of named bits, then
2143 					// the trailing (right) bits are assumed to be 0.
2144 					value = 0;
2145 					const guint32 bit_offset = 8 * i;
2146 					if (bit_offset < length) {
2147 						value = tvb_get_guint8(out_tvb, i);
2148 					}
2149 
2150 					// Process 8 bits at a time instead of 64, each field masks a
2151 					// single byte.
2152 					int* const * section_named_bits = named_bits + bit_offset;
2153 					int* flags[9];
2154 					if (num_named_bits - bit_offset > 8) {
2155 						memcpy(&flags[0], named_bits + bit_offset, 8 * sizeof(int*));
2156 						flags[8] = NULL;
2157 						section_named_bits = flags;
2158 					}
2159 
2160 					// TODO should non-zero pad bits be masked from the value?
2161 					// When trailing zeroes are not present in the data, mark the
2162 					// last byte for the lack of a better alternative.
2163 					proto_tree_add_bitmask_list_value(subtree, out_tvb, offset + MIN(i, length - 1), 1, section_named_bits, value);
2164 				}
2165 			}
2166 		}
2167 		proto_item_append_text(actx->created_item, "]");
2168 	}
2169 
2170 	return out_tvb;
2171 }
2172 guint32
dissect_per_bit_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,int * const * named_bits,gint num_named_bits,tvbuff_t ** value_tvb,int * len)2173 dissect_per_bit_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, int * const *named_bits, gint num_named_bits, tvbuff_t **value_tvb, int *len)
2174 {
2175 	/*gint val_start, val_length;*/
2176 	guint32 length, fragmented_length = 0;
2177 	header_field_info *hfi;
2178 	gboolean is_fragmented = FALSE;
2179 	tvbuff_t *fragmented_tvb = NULL, *out_tvb = NULL;
2180 
2181 	hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2182 
2183 DEBUG_ENTRY("dissect_per_bit_string");
2184 	/* 15.8 if the length is 0 bytes there will be no encoding */
2185 	if(max_len==0) {
2186 		if (value_tvb)
2187 			*value_tvb = out_tvb;
2188 		if (len)
2189 			*len = 0;
2190 		return offset;
2191 	}
2192 
2193 	if (min_len == NO_BOUND) {
2194 		min_len = 0;
2195 	}
2196 	/* 15.6	If an extension marker is present in the size constraint specification of the bitstring type,
2197 	 * a single bit shall be added to the field-list in a bit-field of length one.
2198 	 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2199 	 * and zero otherwise.
2200 	 */
2201 	 if (has_extension) {
2202 		 gboolean extension_present;
2203 		 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2204 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2205 		if(extension_present){
2206 		next_fragment1:
2207 			offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2208 			if(length || fragmented_length){
2209 				/* align to byte */
2210 				if (actx->aligned){
2211 					BYTE_ALIGN_OFFSET(offset);
2212 				}
2213 				if(is_fragmented){
2214 					if(fragmented_length==0)
2215 						fragmented_tvb = tvb_new_composite();
2216 					tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2217 					offset += length;
2218 					fragmented_length += length;
2219 					goto next_fragment1;
2220 				}
2221 				if(fragmented_length){
2222 					if(length){
2223 						tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2224 						fragmented_length += length;
2225 					}
2226 					tvb_composite_finalize(fragmented_tvb);
2227 					add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2228 					out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2229 										 fragmented_length, named_bits, num_named_bits);
2230 				}
2231 				else
2232 					out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2233 			}
2234 			/* XXX: ?? */
2235 			/*val_start = offset>>3;*/
2236 			/*val_length = (length+7)/8;*/
2237 			offset+=length;
2238 
2239 			if (value_tvb)
2240 				*value_tvb = out_tvb;
2241 			if (len)
2242 				*len = fragmented_length ? fragmented_length : length;
2243 
2244 			return offset;
2245 		 }
2246 	 }
2247 
2248 	/* 15.9 if length is fixed and less than or equal to sixteen bits*/
2249 	if ((min_len==max_len) && (max_len<=16)) {
2250 		out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2251 		offset+=min_len;
2252 		if (value_tvb)
2253 			*value_tvb = out_tvb;
2254 		if (len)
2255 			*len = min_len;
2256 		return offset;
2257 	}
2258 
2259 
2260 	/* 15.10 if length is fixed and less than to 64kbits*/
2261 	if((min_len==max_len)&&(min_len<65536)){
2262 		/* (octet-aligned in the ALIGNED variant)
2263 		 * align to byte
2264 		 */
2265 		if (actx->aligned){
2266 			BYTE_ALIGN_OFFSET(offset);
2267 		}
2268 		out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2269 		offset+=min_len;
2270 		if (value_tvb)
2271 			*value_tvb = out_tvb;
2272 		if (len)
2273 			*len = min_len;
2274 		return offset;
2275 	}
2276 
2277 	/* 15.11 */
2278 	if (max_len != NO_BOUND && max_len < 65536) {
2279 		offset=dissect_per_constrained_integer(tvb, offset, actx,
2280 			tree, hf_per_bit_string_length, min_len, max_len,
2281 			&length, FALSE);
2282 			if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2283 	} else {
2284 	next_fragment2:
2285 		offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2286 	}
2287 	if(length || fragmented_length){
2288 		/* align to byte */
2289 		if (actx->aligned){
2290 			BYTE_ALIGN_OFFSET(offset);
2291 		}
2292 		if(is_fragmented){
2293 			if(fragmented_length==0)
2294 				fragmented_tvb = tvb_new_composite();
2295 			tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2296 			offset += length;
2297 			fragmented_length += length;
2298 			goto next_fragment2;
2299 		}
2300 		if(fragmented_length){
2301 			if(length){
2302 				tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2303 				fragmented_length += length;
2304 			}
2305 			tvb_composite_finalize(fragmented_tvb);
2306 			add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2307 			out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2308 								 fragmented_length, named_bits, num_named_bits);
2309 		}
2310 		else
2311 			out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2312 	}
2313 	/* XXX: ?? */
2314 	/*val_start = offset>>3;*/
2315 	/*val_length = (length+7)/8;*/
2316 	offset+=length;
2317 
2318 	if (value_tvb)
2319 		*value_tvb = out_tvb;
2320 	if (len)
2321 		*len = fragmented_length ? fragmented_length : length;
2322 
2323 	return offset;
2324 }
2325 
dissect_per_bit_string_containing_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,dissector_t type_cb)2326 guint32 dissect_per_bit_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2327 {
2328 	tvbuff_t *val_tvb = NULL;
2329 	proto_tree *subtree = tree;
2330 
2331 	offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, NULL, 0, &val_tvb, NULL);
2332 
2333 	if (type_cb && val_tvb) {
2334 		subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2335 		type_cb(val_tvb, actx->pinfo, subtree, NULL);
2336 	}
2337 
2338 	return offset;
2339 }
2340 
2341 /* this function dissects an OCTET STRING
2342 	16.1
2343 	16.2
2344 	16.3
2345 	16.4
2346 	16.5
2347 	16.6
2348 	16.7
2349 	16.8
2350 
2351    max_len or min_len == NO_BOUND means there is no lower/upper constraint
2352 
2353    hf_index can either be a FT_BYTES or an FT_STRING
2354 */
2355 guint32
dissect_per_octet_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,tvbuff_t ** value_tvb)2356 dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
2357 {
2358 	gint val_start = 0, val_length;
2359 	guint32 length = 0, fragmented_length = 0;;
2360 	header_field_info *hfi;
2361 	gboolean is_fragmented = FALSE;
2362 	tvbuff_t *out_tvb = NULL;
2363 
2364 	hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2365 
2366 DEBUG_ENTRY("dissect_per_octet_string");
2367 
2368 	if (has_extension) {  /* 16.3 an extension marker is present */
2369 		gboolean extension_present;
2370 		offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2371 		if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2372 		if (extension_present) max_len = NO_BOUND;  /* skip to 16.8 */
2373 	}
2374 
2375 	if (min_len == NO_BOUND) {
2376 		min_len = 0;
2377 	}
2378 	if (max_len==0) {  /* 16.5 if the length is 0 bytes there will be no encoding */
2379 		val_start = offset>>3;
2380 		val_length = 0;
2381 
2382 	} else if((min_len==max_len)&&(max_len<=2)) {
2383 		/* 16.6 if length is fixed and less than or equal to two bytes*/
2384 		val_start = offset>>3;
2385 		val_length = min_len;
2386 		out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2387 		/* Add new data source if the offet was unaligned */
2388 		if ((offset & 7) != 0) {
2389 			add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2390 		}
2391 		offset+=min_len*8;
2392 
2393 	} else if ((min_len==max_len)&&(min_len<65536)) {
2394 		/* 16.7 if length is fixed and less than to 64k*/
2395 
2396 		/* align to byte */
2397 		if (actx->aligned){
2398 			BYTE_ALIGN_OFFSET(offset);
2399 		}
2400 		val_start = offset>>3;
2401 		val_length = min_len;
2402 		out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2403 		if ((offset & 7) != 0) {
2404 			add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2405 		}
2406 		offset+=min_len*8;
2407 
2408 	} else {  /* 16.8 */
2409 		if(max_len>0) {
2410 			offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2411 				hf_per_octet_string_length, min_len, max_len, &length, FALSE);
2412 
2413 				if (!display_internal_per_fields)
2414 					proto_item_set_hidden(actx->created_item);
2415 		} else {
2416 		next_fragment:
2417 			offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2418 				hf_per_octet_string_length, &length, &is_fragmented);
2419 		}
2420 
2421 		if(length || fragmented_length){
2422 			/* align to byte */
2423 			if (actx->aligned){
2424 				BYTE_ALIGN_OFFSET(offset);
2425 			}
2426 			if (is_fragmented) {
2427 				if (fragmented_length == 0)
2428 					out_tvb = tvb_new_composite();
2429 				tvb_composite_append(out_tvb, tvb_new_octet_aligned(tvb, offset, length * 8));
2430 				offset += length * 8;
2431 				fragmented_length += length;
2432 				goto next_fragment;
2433 			}
2434 			if (fragmented_length) {
2435 				if (length) {
2436 					tvb_composite_append(out_tvb, tvb_new_octet_aligned(tvb, offset, length * 8));
2437 					fragmented_length += length;
2438 				}
2439 				tvb_composite_finalize(out_tvb);
2440 				add_new_data_source(actx->pinfo, out_tvb, "Fragmented OCTET STRING");
2441 			} else {
2442 				out_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
2443 				if ((offset & 7) != 0) {
2444 					add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2445 				}
2446 			}
2447 		} else {
2448 			val_start = offset>>3;
2449 		}
2450 		val_length = fragmented_length ? fragmented_length : length;
2451 		offset+=length*8;
2452 	}
2453 
2454 	if (hfi) {
2455 		if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
2456 			/* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2457 			 * display the length of this octet string instead of the octetstring itself
2458 			 */
2459 			if (IS_FT_UINT(hfi->type))
2460 				actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2461 			else
2462 				actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2463 			proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2464 		} else {
2465 			if(out_tvb){
2466 				actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, ENC_BIG_ENDIAN);
2467 			}else{
2468 				/* Length = 0 */
2469 				actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, ENC_BIG_ENDIAN);
2470 			}
2471 		}
2472 	}
2473 
2474 	if (value_tvb)
2475 		*value_tvb = (out_tvb) ? out_tvb : tvb_new_subset_length(tvb, val_start, val_length);
2476 
2477 	return offset;
2478 }
2479 
dissect_per_octet_string_containing_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,dissector_t type_cb)2480 guint32 dissect_per_octet_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2481 {
2482 	tvbuff_t *val_tvb = NULL;
2483 	proto_tree *subtree = tree;
2484 
2485 	offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2486 
2487 	if (type_cb && val_tvb && (tvb_reported_length(val_tvb) > 0)) {
2488 		subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2489 		type_cb(val_tvb, actx->pinfo, subtree, NULL);
2490 	}
2491 
2492 	return offset;
2493 }
2494 
dissect_per_size_constrained_type(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,per_type_fn type_cb,const gchar * name,int min_len,int max_len,gboolean has_extension)2495 guint32 dissect_per_size_constrained_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb, const gchar *name, int min_len, int max_len, gboolean has_extension)
2496 {
2497 	asn1_stack_frame_push(actx, name);
2498 	asn1_param_push_integer(actx, min_len);
2499 	asn1_param_push_integer(actx, max_len);
2500 	asn1_param_push_boolean(actx, has_extension);
2501 
2502 	offset = type_cb(tvb, offset, actx, tree, hf_index);
2503 
2504 	asn1_stack_frame_pop(actx, name);
2505 
2506 	return offset;
2507 }
2508 
get_size_constraint_from_stack(asn1_ctx_t * actx,const gchar * name,int * pmin_len,int * pmax_len,gboolean * phas_extension)2509 gboolean get_size_constraint_from_stack(asn1_ctx_t *actx, const gchar *name, int *pmin_len, int *pmax_len, gboolean *phas_extension)
2510 {
2511 	asn1_par_t *par;
2512 
2513 	if (pmin_len) *pmin_len = NO_BOUND;
2514 	if (pmax_len) *pmax_len = NO_BOUND;
2515 	if (phas_extension) *phas_extension = FALSE;
2516 
2517 	if (!actx->stack) return FALSE;
2518 	if (strcmp(actx->stack->name, name)) return FALSE;
2519 
2520 	par = actx->stack->par;
2521 	if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2522 	if (pmin_len) *pmin_len = par->value.v_integer;
2523 	par = par->next;
2524 	if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2525 	if (pmax_len) *pmax_len = par->value.v_integer;
2526 	par = par->next;
2527 	if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return FALSE;
2528 	if (phas_extension) *phas_extension = par->value.v_boolean;
2529 
2530 	return TRUE;
2531 }
2532 
2533 
2534 /* 26 Encoding of a value of the external type */
2535 
2536 /* code generated from definition in 26.1 */
2537 /*
2538 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2539   direct-reference OBJECT IDENTIFIER OPTIONAL,
2540   indirect-reference INTEGER OPTIONAL,
2541   data-value-descriptor ObjectDescriptor OPTIONAL,
2542     encoding CHOICE {
2543     single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2544     octet-aligned [1] IMPLICIT OCTET STRING,
2545     arbitrary [2] IMPLICIT BIT STRING
2546   }
2547 }
2548 */
2549 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2550 
2551 static int
dissect_per_T_direct_reference(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2552 dissect_per_T_direct_reference(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2553 
2554 	DISSECTOR_ASSERT(actx);
2555 	offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2556 
2557 	actx->external.direct_ref_present = TRUE;
2558 	return offset;
2559 }
2560 
2561 
2562 
2563 static int
dissect_per_T_indirect_reference(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2564 dissect_per_T_indirect_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2565 	offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2566 
2567 	actx->external.indirect_ref_present = TRUE;
2568 	return offset;
2569 }
2570 
2571 
2572 
2573 static int
dissect_per_T_data_value_descriptor(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2574 dissect_per_T_data_value_descriptor(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2575 	offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2576 
2577 	actx->external.data_value_descr_present = TRUE;
2578 	return offset;
2579 }
2580 
2581 
2582 
2583 static int
dissect_per_T_single_ASN1_type(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2584 dissect_per_T_single_ASN1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2585 	offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2586 
2587 	return offset;
2588 }
2589 
2590 
2591 
2592 static int
dissect_per_T_octet_aligned(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2593 dissect_per_T_octet_aligned(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2594 	offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2595 					  NO_BOUND, NO_BOUND, FALSE, &actx->external.octet_aligned);
2596 
2597 	if (actx->external.octet_aligned) {
2598 		if (actx->external.u.per.type_cb) {
2599 			actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2600 		} else {
2601 			actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.octet_aligned, 0, -1);
2602 		}
2603 	}
2604 	return offset;
2605 }
2606 
2607 
2608 
2609 static int
dissect_per_T_arbitrary(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2610 dissect_per_T_arbitrary(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2611 	offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2612 					NO_BOUND, NO_BOUND, FALSE, NULL, 0, &actx->external.arbitrary, NULL);
2613 
2614 	if (actx->external.arbitrary) {
2615 		if (actx->external.u.per.type_cb) {
2616 			actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2617 		} else {
2618 			actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.arbitrary, 0, -1);
2619 		}
2620 	}
2621 	return offset;
2622 }
2623 
2624 
2625 static const value_string per_External_encoding_vals[] = {
2626 	{   0, "single-ASN1-type" },
2627 	{   1, "octet-aligned" },
2628 	{   2, "arbitrary" },
2629 	{ 0, NULL }
2630 };
2631 
2632 static const per_choice_t External_encoding_choice[] = {
2633 	{   0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS     , dissect_per_T_single_ASN1_type },
2634 	{   1, &hf_per_octet_aligned   , ASN1_NO_EXTENSIONS     , dissect_per_T_octet_aligned },
2635 	{   2, &hf_per_arbitrary       , ASN1_NO_EXTENSIONS     , dissect_per_T_arbitrary },
2636 	{ 0, NULL, 0, NULL }
2637 };
2638 
2639 static int
dissect_per_External_encoding(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2640 dissect_per_External_encoding(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2641 	// This assertion is used to remove clang's warning.
2642 	DISSECTOR_ASSERT(actx);
2643 	offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2644 				    ett_per_External_encoding, External_encoding_choice,
2645 				    &actx->external.encoding);
2646 
2647 	return offset;
2648 }
2649 
2650 
2651 static const per_sequence_t External_sequence[] = {
2652 	{ &hf_per_direct_reference, ASN1_NO_EXTENSIONS      , ASN1_OPTIONAL    , dissect_per_T_direct_reference },
2653 	{ &hf_per_indirect_reference, ASN1_NO_EXTENSIONS    , ASN1_OPTIONAL    , dissect_per_T_indirect_reference },
2654 	{ &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL    , dissect_per_T_data_value_descriptor },
2655 	{ &hf_per_encoding        , ASN1_NO_EXTENSIONS      , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2656 	{ NULL, 0, 0, NULL }
2657 };
2658 
2659 static int
dissect_per_External(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2660 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2661 	offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2662 				      ett_per_External, External_sequence);
2663 
2664 	return offset;
2665 }
2666 
2667 guint32
dissect_per_external_type(tvbuff_t * tvb _U_,guint32 offset,asn1_ctx_t * actx,proto_tree * tree _U_,int hf_index _U_,per_type_fn type_cb)2668 dissect_per_external_type(tvbuff_t *tvb _U_, guint32 offset, asn1_ctx_t *actx, proto_tree *tree _U_, int hf_index _U_, per_type_fn type_cb)
2669 {
2670 	asn1_ctx_clean_external(actx);
2671 	actx->external.u.per.type_cb = type_cb;
2672 	offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2673 
2674 	asn1_ctx_clean_external(actx);
2675 	return offset;
2676 }
2677 
2678 /*
2679  * Calls the callback defined with register_per_oid_dissector() if found.
2680  * Offset is in bits.
2681  */
2682 
2683 int
call_per_oid_callback(const char * oid,tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,asn1_ctx_t * actx,int hf_index)2684 call_per_oid_callback(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, asn1_ctx_t *actx, int hf_index)
2685 {
2686 	guint32 type_length, end_offset, start_offset;
2687 	tvbuff_t *val_tvb = NULL;
2688 
2689 	start_offset = offset;
2690 	offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length, NULL);
2691 	if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
2692 	end_offset = offset + type_length;
2693 
2694 
2695 	val_tvb = tvb_new_octet_aligned(tvb, offset, type_length);
2696 	if ((offset & 7) != 0) {
2697 		add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
2698 	}
2699 
2700 	if (oid == NULL ||
2701 		(dissector_try_string(per_oid_dissector_table, oid, val_tvb, pinfo, tree, actx)) == 0)
2702 	{
2703 		proto_tree_add_expert(tree, pinfo, &ei_per_oid_not_implemented, val_tvb, 0, -1);
2704 		dissect_per_open_type(tvb, start_offset, actx, tree, hf_index, NULL);
2705 	}
2706 
2707 	return end_offset;
2708 }
2709 
2710 void
register_per_oid_dissector(const char * oid,dissector_t dissector,int proto,const char * name)2711 register_per_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name)
2712 {
2713 	dissector_handle_t dissector_handle;
2714 
2715 	dissector_handle = create_dissector_handle(dissector, proto);
2716 	dissector_add_string("per.oid", oid, dissector_handle);
2717 	oid_add_from_string(name, oid);
2718 }
2719 
2720 
2721 void
proto_register_per(void)2722 proto_register_per(void)
2723 {
2724 	static hf_register_info hf[] = {
2725 		{ &hf_per_num_sequence_extensions,
2726 		  { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2727 		    NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2728 		{ &hf_per_choice_index,
2729 		  { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2730 		    NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2731 		{ &hf_per_choice_extension_index,
2732 		  { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2733 		    NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2734 		{ &hf_per_enum_index,
2735 		  { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2736 		    NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2737 		{ &hf_per_enum_extension_index,
2738 		  { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2739 		    NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2740 		{ &hf_per_GeneralString_length,
2741 		  { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2742 		    NULL, 0, "Length of the GeneralString", HFILL }},
2743 		{ &hf_per_extension_bit,
2744 		  { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2745 		    TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2746 		{ &hf_per_extension_present_bit,
2747 		  { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2748 		    NULL, 0x01, "Whether this optional extension is present or not", HFILL }},
2749 		{ &hf_per_small_number_bit,
2750 		  { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2751 		    TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2752 		{ &hf_per_optional_field_bit,
2753 		  { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2754 		    NULL, 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2755 		{ &hf_per_sequence_of_length,
2756 		  { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2757 		    NULL, 0, "Number of items in the Sequence Of", HFILL }},
2758 		{ &hf_per_object_identifier_length,
2759 		  { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2760 		    NULL, 0, "Length of the object identifier", HFILL }},
2761 		{ &hf_per_open_type_length,
2762 		  { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2763 		    NULL, 0, "Length of an open type encoding", HFILL }},
2764 		{ &hf_per_real_length,
2765 		  { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2766 		    NULL, 0, "Length of an real encoding", HFILL }},
2767 		{ &hf_per_octet_string_length,
2768 		  { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2769 		    NULL, 0, "Number of bytes in the Octet String", HFILL }},
2770 		{ &hf_per_bit_string_length,
2771 		  { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2772 		    NULL, 0, "Number of bits in the Bit String", HFILL }},
2773 		{ &hf_per_normally_small_nonnegative_whole_number_length,
2774 		  { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32, BASE_DEC,
2775 		    NULL, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL }},
2776 		{ &hf_per_const_int_len,
2777 		  { "Constrained Integer Length", "per.const_int_len", FT_UINT32, BASE_DEC,
2778 		    NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2779 		{ &hf_per_direct_reference,
2780 		  { "direct-reference", "per.direct_reference",
2781 		    FT_OID, BASE_NONE, NULL, 0,
2782 		    "per.T_direct_reference", HFILL }},
2783 		{ &hf_per_indirect_reference,
2784 		  { "indirect-reference", "per.indirect_reference",
2785 		    FT_INT32, BASE_DEC, NULL, 0,
2786 		    "per.T_indirect_reference", HFILL }},
2787 		{ &hf_per_data_value_descriptor,
2788 		  { "data-value-descriptor", "per.data_value_descriptor",
2789 		    FT_STRING, BASE_NONE, NULL, 0,
2790 		    "per.T_data_value_descriptor", HFILL }},
2791 		{ &hf_per_encoding,
2792 		  { "encoding", "per.encoding",
2793 		    FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2794 		    "per.External_encoding", HFILL }},
2795 		{ &hf_per_single_ASN1_type,
2796 		  { "single-ASN1-type", "per.single_ASN1_type",
2797 		    FT_NONE, BASE_NONE, NULL, 0,
2798 		    "per.T_single_ASN1_type", HFILL }},
2799 		{ &hf_per_octet_aligned,
2800 		  { "octet-aligned", "per.octet_aligned",
2801 		    FT_BYTES, BASE_NONE, NULL, 0,
2802 		    "per.T_octet_aligned", HFILL }},
2803 		{ &hf_per_arbitrary,
2804 		  { "arbitrary", "per.arbitrary",
2805 		    FT_BYTES, BASE_NONE, NULL, 0,
2806 		    "per.T_arbitrary", HFILL }},
2807 		{ &hf_per_integer_length,
2808 		  { "integer length", "per.integer_length",
2809 		    FT_UINT32, BASE_DEC, NULL, 0,
2810 		    NULL, HFILL }},
2811 #if 0
2812 		{ &hf_per_debug_pos,
2813 		  { "Current bit offset", "per.debug_pos",
2814 		    FT_UINT32, BASE_DEC, NULL, 0,
2815 		    NULL, HFILL }},
2816 #endif
2817 		{ &hf_per_internal_range,
2818 		  { "Range", "per.internal.range",
2819 		    FT_UINT64, BASE_DEC, NULL, 0,
2820 		    NULL, HFILL }},
2821 		{ &hf_per_internal_num_bits,
2822 		  { "Bitfield length", "per.internal.num_bits",
2823 		    FT_UINT32, BASE_DEC, NULL, 0,
2824 		    NULL, HFILL }},
2825 		{ &hf_per_internal_min,
2826 		  { "Min", "per.internal.min",
2827 		    FT_UINT32, BASE_DEC, NULL, 0,
2828 		    NULL, HFILL }},
2829 		{ &hf_per_internal_value,
2830 		  { "Bits", "per.internal.value",
2831 		    FT_UINT64, BASE_DEC, NULL, 0,
2832 		    NULL, HFILL }},
2833 	};
2834 
2835 	static gint *ett[] = {
2836 		&ett_per_open_type,
2837 		&ett_per_containing,
2838 		&ett_per_sequence_of_item,
2839 		&ett_per_External,
2840 		&ett_per_External_encoding,
2841 		&ett_per_named_bits,
2842 	};
2843 	static ei_register_info ei[] = {
2844 		{ &ei_per_size_constraint_value,
2845 		  { "per.size_constraint.value", PI_PROTOCOL, PI_WARN, "Size constraint: value too big", EXPFILL }},
2846 		{ &ei_per_size_constraint_too_few,
2847 		  { "per.size_constraint.too_few", PI_PROTOCOL, PI_WARN, "Size constraint: too few items", EXPFILL }},
2848 		{ &ei_per_size_constraint_too_many,
2849 		  { "per.size_constraint.too_many", PI_PROTOCOL, PI_WARN, "Size constraint: too many items", EXPFILL }},
2850 		{ &ei_per_choice_extension_unknown,
2851 		  { "per.choice_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown choice extension", EXPFILL }},
2852 		{ &ei_per_sequence_extension_unknown,
2853 		  { "per.sequence_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown sequence extension", EXPFILL }},
2854 		{ &ei_per_encoding_error,
2855 		  { "per.encoding_error", PI_MALFORMED, PI_WARN, "Encoding error", EXPFILL }},
2856 		{ &ei_per_oid_not_implemented,
2857 		  { "per.error.oid_not_implemented", PI_UNDECODED, PI_WARN, "PER: Dissector for OID not implemented. Contact Wireshark developers if you want this supported", EXPFILL }},
2858 		{ &ei_per_undecoded,
2859 		  { "per.error.undecoded", PI_UNDECODED, PI_WARN, "PER: Something unknown here", EXPFILL }},
2860 		{ &ei_per_field_not_integer,
2861 		  { "per.field_not_integer", PI_PROTOCOL, PI_ERROR, "Field is not an integer", EXPFILL }},
2862 		{ &ei_per_external_type,
2863 		  { "per.external_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown EXTERNAL Type", EXPFILL }},
2864 		{ &ei_per_open_type,
2865 		  { "per.open_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown Open Type", EXPFILL }},
2866 		{ &ei_per_open_type_len,
2867 		  { "per.open_type.len", PI_PROTOCOL, PI_ERROR, "Open Type length > available data(tvb)", EXPFILL }}
2868 	};
2869 
2870 	module_t *per_module;
2871 	expert_module_t* expert_per;
2872 
2873 	proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2874 	proto_register_field_array(proto_per, hf, array_length(hf));
2875 	proto_register_subtree_array(ett, array_length(ett));
2876 	expert_per = expert_register_protocol(proto_per);
2877 	expert_register_field_array(expert_per, ei, array_length(ei));
2878 
2879 	proto_set_cant_toggle(proto_per);
2880 
2881 	per_module = prefs_register_protocol(proto_per, NULL);
2882 	prefs_register_bool_preference(per_module, "display_internal_per_fields",
2883 				       "Display the internal PER fields in the tree",
2884 				       "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2885 				       &display_internal_per_fields);
2886 
2887 	per_oid_dissector_table = register_dissector_table("per.oid", "PER OID", proto_per, FT_STRING, BASE_NONE);
2888 
2889 
2890 }
2891 
2892 /*
2893  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2894  *
2895  * Local variables:
2896  * c-basic-offset: 8
2897  * tab-width: 8
2898  * indent-tabs-mode: t
2899  * End:
2900  *
2901  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2902  * :indentSize=8:tabSize=8:noTabs=false:
2903  */
2904