1 /*
2 * libpri: An implementation of Primary Rate ISDN
3 *
4 * Copyright (C) 2009 Digium, Inc.
5 *
6 * Richard Mudgett <rmudgett@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2 as published by the
16 * Free Software Foundation. See the LICENSE file included with
17 * this program for more details.
18 *
19 * In addition, when this program is distributed with Asterisk in
20 * any form that would qualify as a 'combined work' or as a
21 * 'derivative work' (but not mere aggregation), you can redistribute
22 * and/or modify the combination under the terms of the license
23 * provided with that copy of Asterisk, instead of the license
24 * terms granted here.
25 */
26
27 /*!
28 * \file
29 * \brief ASN.1 BER encode/decode primitives
30 *
31 * \author Richard Mudgett <rmudgett@digium.com>
32 */
33
34
35 #include <stdio.h>
36 #include <ctype.h>
37
38 #include "compat.h"
39 #include "libpri.h"
40 #include "pri_internal.h"
41 #include "asn1.h"
42
43 /* ------------------------------------------------------------------- */
44
45 /*!
46 * \internal
47 * \brief Dump the memory contents indicated in printable characters. (Helper function.)
48 *
49 * \param ctrl D channel controller for any diagnostic messages.
50 * \param start Dump memory starting position.
51 * \param end Dump memory ending position. (Not included in dump.)
52 *
53 * \return Nothing
54 */
asn1_dump_mem_helper(struct pri * ctrl,const unsigned char * start,const unsigned char * end)55 static void asn1_dump_mem_helper(struct pri *ctrl, const unsigned char *start,
56 const unsigned char *end)
57 {
58 pri_message(ctrl, " - \"");
59 for (; start < end; ++start) {
60 pri_message(ctrl, "%c", (isprint(*start)) ? *start : '~');
61 }
62 pri_message(ctrl, "\"\n");
63 }
64
65 /*!
66 * \internal
67 * \brief Dump the memory contents indicated.
68 *
69 * \param ctrl D channel controller for any diagnostic messages.
70 * \param indent Number of spaces to indent for each new memory dump line.
71 * \param pos Dump memory starting position.
72 * \param length Number of bytes to dump.
73 *
74 * \return Nothing
75 */
asn1_dump_mem(struct pri * ctrl,unsigned indent,const unsigned char * pos,unsigned length)76 static void asn1_dump_mem(struct pri *ctrl, unsigned indent, const unsigned char *pos,
77 unsigned length)
78 {
79 const unsigned char *seg_start;
80 const unsigned char *end;
81 unsigned delimiter;
82 unsigned count;
83
84 seg_start = pos;
85 end = pos + length;
86 if (pos < end) {
87 delimiter = '<';
88 for (;;) {
89 pri_message(ctrl, "%*s", indent, "");
90 for (count = 0; count++ < 16 && pos < end;) {
91 pri_message(ctrl, "%c%02X", delimiter, *pos++);
92 delimiter = (count == 8) ? '-' : ' ';
93 }
94 if (end <= pos) {
95 break;
96 }
97 asn1_dump_mem_helper(ctrl, seg_start, pos);
98 seg_start = pos;
99 }
100 } else {
101 pri_message(ctrl, "%*s<", indent, "");
102 }
103 pri_message(ctrl, ">");
104 asn1_dump_mem_helper(ctrl, seg_start, end);
105 }
106
107 /*!
108 * \brief Convert the given tag value to a descriptive string.
109 *
110 * \param tag Component tag value to convert to a string.
111 *
112 * \return Converted tag string.
113 */
asn1_tag2str(unsigned tag)114 const char *asn1_tag2str(unsigned tag)
115 {
116 static const char *primitives[32] = {
117 [ASN1_TYPE_INDEF_TERM] = "Indefinite length terminator",
118 [ASN1_TYPE_BOOLEAN] = "Boolean",
119 [ASN1_TYPE_INTEGER] = "Integer",
120 [ASN1_TYPE_BIT_STRING] = "Bit String",
121 [ASN1_TYPE_OCTET_STRING] = "Octet String",
122 [ASN1_TYPE_NULL] = "NULL",
123 [ASN1_TYPE_OBJECT_IDENTIFIER] = "OID",
124 [ASN1_TYPE_OBJECT_DESCRIPTOR] = "Object Descriptor",
125 [ASN1_TYPE_EXTERN] = "External",
126 [ASN1_TYPE_REAL] = "Real",
127 [ASN1_TYPE_ENUMERATED] = "Enumerated",
128 [ASN1_TYPE_EMBEDDED_PDV] = "Embedded PDV",
129 [ASN1_TYPE_UTF8_STRING] = "UTF8 String",
130 [ASN1_TYPE_RELATIVE_OID] = "Relative OID",
131 [ASN1_TYPE_SEQUENCE] = "Sequence",
132 [ASN1_TYPE_SET] = "Set",
133 [ASN1_TYPE_NUMERIC_STRING] = "Numeric String",
134 [ASN1_TYPE_PRINTABLE_STRING] = "Printable String",
135 [ASN1_TYPE_TELETEX_STRING] = "Teletex String",
136 [ASN1_TYPE_VIDEOTEX_STRING] = "Videotex String",
137 [ASN1_TYPE_IA5_STRING] = "IA5 String",
138 [ASN1_TYPE_UTC_TIME] = "UTC Time",
139 [ASN1_TYPE_GENERALIZED_TIME] = "Generalized Time",
140 [ASN1_TYPE_GRAPHIC_STRING] = "Graphic String",
141 [ASN1_TYPE_VISIBLE_STRING] = "Visible/ISO646 String",
142 [ASN1_TYPE_GENERAL_STRING] = "General String",
143 [ASN1_TYPE_UNIVERSAL_STRING] = "Universal String",
144 [ASN1_TYPE_CHAR_STRING] = "Character String",
145 [ASN1_TYPE_BMP_STRING] = "BMP String",
146 [ASN1_TYPE_EXTENSION] = "Type Extension",
147 };
148 static char buf[64];
149 const char *description;
150 unsigned asn1_constructed; /*! TRUE if the tag is constructed. */
151 unsigned asn1_type;
152
153 asn1_constructed = ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED);
154 asn1_type = tag & ASN1_TYPE_MASK;
155
156 switch (tag & ASN1_CLASS_MASK) {
157 case ASN1_CLASS_UNIVERSAL:
158 if (tag == (ASN1_CLASS_UNIVERSAL | ASN1_PC_CONSTRUCTED | ASN1_TYPE_INDEF_TERM)) {
159 description = NULL;
160 } else {
161 description = primitives[asn1_type];
162 }
163 if (!description) {
164 description = "Reserved";
165 }
166 snprintf(buf, sizeof(buf), "%s%s(%u 0x%02X)", description,
167 asn1_constructed ? "/C" : "", tag, tag);
168 return buf;
169 case ASN1_CLASS_APPLICATION:
170 description = "Application";
171 break;
172 case ASN1_CLASS_CONTEXT_SPECIFIC:
173 description = "Context Specific";
174 break;
175 case ASN1_CLASS_PRIVATE:
176 description = "Private";
177 break;
178 default:
179 snprintf(buf, sizeof(buf), "Unknown tag (%u 0x%02X)", tag, tag);
180 return buf;
181 }
182 snprintf(buf, sizeof(buf), "%s%s [%u 0x%02X]", description,
183 asn1_constructed ? "/C" : "", asn1_type, asn1_type);
184 return buf;
185 }
186
187 /*!
188 * \brief Decode the ASN.1 tag value.
189 *
190 * \param tag_pos ASN.1 tag starting position.
191 * \param end End of ASN.1 encoded data buffer.
192 * \param tag Decoded tag value returned on success.
193 *
194 * \retval Next octet after the tag on success.
195 * \retval NULL on error.
196 */
asn1_dec_tag(const unsigned char * tag_pos,const unsigned char * end,unsigned * tag)197 const unsigned char *asn1_dec_tag(const unsigned char *tag_pos, const unsigned char *end,
198 unsigned *tag)
199 {
200 unsigned extended_tag;
201
202 if (end <= tag_pos) {
203 return NULL;
204 }
205 *tag = *tag_pos++;
206 if ((*tag & ASN1_TYPE_MASK) == ASN1_TYPE_EXTENSION) {
207 /* Extract the extended tag value */
208 extended_tag = 0;
209 do {
210 if (end <= tag_pos) {
211 return NULL;
212 }
213 extended_tag <<= 7;
214 extended_tag |= *tag_pos & ~0x80;
215 } while (*tag_pos++ & 0x80);
216 if (extended_tag && extended_tag < ASN1_TYPE_EXTENSION) {
217 /*
218 * The sender did not need to use the extended format.
219 * This is an encoding error on their part, but we will
220 * accept it anyway.
221 *
222 * Note we cannot return a null tag value from this path.
223 * We would misinterpret the indefinite length
224 * terminator.
225 */
226 *tag &= ~ASN1_TYPE_MASK;
227 *tag |= extended_tag;
228 }
229 }
230
231 return tag_pos;
232 }
233
234 /*!
235 * \brief Decode the length of an ASN.1 component length.
236 *
237 * \param len_pos Starting position of the ASN.1 component length.
238 * \param end End of ASN.1 decoding data buffer.
239 * \param length Decoded length value returned on success. (-1 if indefinite)
240 *
241 * \retval Next octet after the length on success.
242 * \retval NULL on error.
243 *
244 * \note The decoded length is checked to see if there is enough buffer
245 * left for the component body.
246 */
asn1_dec_length(const unsigned char * len_pos,const unsigned char * end,int * length)247 const unsigned char *asn1_dec_length(const unsigned char *len_pos,
248 const unsigned char *end, int *length)
249 {
250 unsigned length_size;
251
252 if (end <= len_pos) {
253 /* Not enough buffer to determine how the length is encoded */
254 return NULL;
255 }
256
257 if (*len_pos < 0x80) {
258 /* Short length encoding */
259 *length = *len_pos++;
260 } else if (*len_pos == 0x80) {
261 /* Indefinite length encoding */
262 *length = -1;
263 ++len_pos;
264 if (end < len_pos + ASN1_INDEF_TERM_LEN) {
265 /* Not enough buffer for the indefinite length terminator */
266 return NULL;
267 }
268 return len_pos;
269 } else {
270 /* Long length encoding */
271 length_size = *len_pos++ & 0x7f;
272 if (length_size == 0x7f) {
273 /* Reserved extension encoding that has not been defined. */
274 return NULL;
275 }
276 if (end < len_pos + length_size) {
277 /* Not enough buffer for the length value */
278 return NULL;
279 }
280 *length = 0;
281 while (length_size--) {
282 *length = (*length << 8) | *len_pos++;
283 }
284 }
285
286 if (end < len_pos + *length) {
287 /* Not enough buffer for the component body. */
288 return NULL;
289 }
290 return len_pos;
291 }
292
293 /*!
294 * \internal
295 * \brief Skip to the end of an indefinite length constructed component helper.
296 *
297 * \param pos ASN.1 tag starting position.
298 * \param end End of ASN.1 decoding data buffer.
299 *
300 * \retval Start of the next ASN.1 component on success.
301 * \retval NULL on error.
302 */
asn1_dec_indef_end_fixup_helper(const unsigned char * pos,const unsigned char * end)303 static const unsigned char *asn1_dec_indef_end_fixup_helper(const unsigned char *pos,
304 const unsigned char *end)
305 {
306 unsigned tag;
307 int length;
308
309 while (pos < end && *pos != ASN1_INDEF_TERM) {
310 ASN1_CALL(pos, asn1_dec_tag(pos, end, &tag));
311 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
312 if (length < 0) {
313 /* Skip over indefinite length sub-component */
314 if ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED
315 || tag == (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SET)
316 || tag ==
317 (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SEQUENCE)) {
318 /* This is an ITU encoded indefinite length component. */
319 ASN1_CALL(pos, asn1_dec_indef_end_fixup_helper(pos, end));
320 } else {
321 /* This is a non-ITU encoded indefinite length component. */
322 while (pos < end && *pos != ASN1_INDEF_TERM) {
323 ++pos;
324 }
325 pos += ASN1_INDEF_TERM_LEN;
326 }
327 } else {
328 /* Skip over defininte length sub-component */
329 pos += length;
330 }
331 }
332 if (end < pos + ASN1_INDEF_TERM_LEN) {
333 return NULL;
334 }
335
336 return pos + ASN1_INDEF_TERM_LEN;
337 }
338
339 /*!
340 * \brief Skip to the end of an indefinite length constructed component.
341 *
342 * \param ctrl D channel controller for any diagnostic messages.
343 * \param pos ASN.1 tag starting position.
344 * \param end End of ASN.1 decoding data buffer.
345 *
346 * \retval Start of the next ASN.1 component on success.
347 * \retval NULL on error.
348 */
asn1_dec_indef_end_fixup(struct pri * ctrl,const unsigned char * pos,const unsigned char * end)349 const unsigned char *asn1_dec_indef_end_fixup(struct pri *ctrl, const unsigned char *pos,
350 const unsigned char *end)
351 {
352 if (pos < end && *pos != ASN1_INDEF_TERM && (ctrl->debug & PRI_DEBUG_APDU)) {
353 pri_message(ctrl,
354 " Skipping unused indefinite length constructed component octets!\n");
355 }
356 return asn1_dec_indef_end_fixup_helper(pos, end);
357 }
358
359 /*!
360 * \brief Decode the boolean primitive.
361 *
362 * \param ctrl D channel controller for any diagnostic messages.
363 * \param name Field name
364 * \param tag Component tag that identified this primitive.
365 * \param pos Starting position of the ASN.1 component length.
366 * \param end End of ASN.1 decoding data buffer.
367 * \param value Decoded boolean value.
368 *
369 * \retval Start of the next ASN.1 component on success.
370 * \retval NULL on error.
371 */
asn1_dec_boolean(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,int32_t * value)372 const unsigned char *asn1_dec_boolean(struct pri *ctrl, const char *name, unsigned tag,
373 const unsigned char *pos, const unsigned char *end, int32_t *value)
374 {
375 int length;
376
377 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
378 if (length != 1) {
379 /*
380 * The encoding rules say the length can only be one.
381 * It is rediculus to get anything else anyway.
382 */
383 return NULL;
384 }
385
386 *value = *pos++ ? 1 : 0;
387
388 if (ctrl->debug & PRI_DEBUG_APDU) {
389 pri_message(ctrl, " %s %s = %d\n", name, asn1_tag2str(tag), *value);
390 }
391
392 return pos;
393 }
394
395 /*!
396 * \brief Decode the integer type primitive.
397 *
398 * \param ctrl D channel controller for any diagnostic messages.
399 * \param name Field name
400 * \param tag Component tag that identified this primitive.
401 * \param pos Starting position of the ASN.1 component length.
402 * \param end End of ASN.1 decoding data buffer.
403 * \param value Decoded integer type value.
404 *
405 * \retval Start of the next ASN.1 component on success.
406 * \retval NULL on error.
407 */
asn1_dec_int(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,int32_t * value)408 const unsigned char *asn1_dec_int(struct pri *ctrl, const char *name, unsigned tag,
409 const unsigned char *pos, const unsigned char *end, int32_t *value)
410 {
411 int length;
412
413 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
414 if (length <= 0) {
415 /*
416 * The encoding rules say the length can not be indefinite.
417 * It cannot be empty for that matter either.
418 */
419 return NULL;
420 }
421
422 #if 1
423 /* Read value as signed */
424 if (*pos & 0x80) {
425 /* The value is negative */
426 *value = -1;
427 } else {
428 *value = 0;
429 }
430 #else
431 /* Read value as unsigned */
432 *value = 0;
433 #endif
434 while (length--) {
435 *value = (*value << 8) | *pos;
436 pos++;
437 }
438
439 if (ctrl->debug & PRI_DEBUG_APDU) {
440 pri_message(ctrl, " %s %s = %d 0x%04X\n", name, asn1_tag2str(tag), *value,
441 *value);
442 }
443
444 return pos;
445 }
446
447 /*!
448 * \brief Decode the null primitive.
449 *
450 * \param ctrl D channel controller for any diagnostic messages.
451 * \param name Field name
452 * \param tag Component tag that identified this primitive.
453 * \param pos Starting position of the ASN.1 component length.
454 * \param end End of ASN.1 decoding data buffer.
455 *
456 * \retval Start of the next ASN.1 component on success.
457 * \retval NULL on error.
458 */
asn1_dec_null(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end)459 const unsigned char *asn1_dec_null(struct pri *ctrl, const char *name, unsigned tag,
460 const unsigned char *pos, const unsigned char *end)
461 {
462 int length;
463
464 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
465 if (length != 0) {
466 /*
467 * The encoding rules say the length can only be zero.
468 * It is rediculus to get anything else anyway.
469 */
470 return NULL;
471 }
472
473 if (ctrl->debug & PRI_DEBUG_APDU) {
474 pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
475 }
476
477 return pos;
478 }
479
480 /*!
481 * \brief Decode the object identifier primitive.
482 *
483 * \param ctrl D channel controller for any diagnostic messages.
484 * \param name Field name
485 * \param tag Component tag that identified this primitive.
486 * \param pos Starting position of the ASN.1 component length.
487 * \param end End of ASN.1 decoding data buffer.
488 * \param oid Decoded OID type value.
489 *
490 * \retval Start of the next ASN.1 component on success.
491 * \retval NULL on error.
492 */
asn1_dec_oid(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct asn1_oid * oid)493 const unsigned char *asn1_dec_oid(struct pri *ctrl, const char *name, unsigned tag,
494 const unsigned char *pos, const unsigned char *end, struct asn1_oid *oid)
495 {
496 int length;
497 unsigned num_values;
498 unsigned value;
499 unsigned delimiter;
500
501 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
502 if (length < 0) {
503 /*
504 * The encoding rules say the length can not be indefinite.
505 */
506 return NULL;
507 }
508
509 if (ctrl->debug & PRI_DEBUG_APDU) {
510 pri_message(ctrl, " %s %s =", name, asn1_tag2str(tag));
511 }
512 delimiter = ' ';
513 num_values = 0;
514 while (length) {
515 value = 0;
516 for (;;) {
517 --length;
518 value = (value << 7) | (*pos & 0x7F);
519 if (!(*pos++ & 0x80)) {
520 /* Last octet in the OID subidentifier value */
521 if (num_values < ARRAY_LEN(oid->value)) {
522 oid->value[num_values] = value;
523 if (ctrl->debug & PRI_DEBUG_APDU) {
524 pri_message(ctrl, "%c%u", delimiter, value);
525 }
526 delimiter = '.';
527 } else {
528 /* Too many OID subidentifier values */
529 delimiter = '~';
530 if (ctrl->debug & PRI_DEBUG_APDU) {
531 pri_message(ctrl, "%c%u", delimiter, value);
532 }
533 }
534 ++num_values;
535 break;
536 }
537 if (!length) {
538 oid->num_values = 0;
539 if (ctrl->debug & PRI_DEBUG_APDU) {
540 pri_message(ctrl, "\n"
541 " Last OID subidentifier value not terminated!\n");
542 }
543 return NULL;
544 }
545 }
546 }
547 if (ctrl->debug & PRI_DEBUG_APDU) {
548 pri_message(ctrl, "\n");
549 }
550
551 if (num_values <= ARRAY_LEN(oid->value)) {
552 oid->num_values = num_values;
553 return pos;
554 } else {
555 /* Need to increase the size of the OID subidentifier list. */
556 oid->num_values = 0;
557 if (ctrl->debug & PRI_DEBUG_APDU) {
558 pri_message(ctrl, " Too many OID values!\n");
559 }
560 return NULL;
561 }
562 }
563
564 /*!
565 * \brief Decode a binary string primitive.
566 *
567 * \param ctrl D channel controller for any diagnostic messages.
568 * \param name Field name
569 * \param tag Component tag that identified this primitive.
570 * \param pos Starting position of the ASN.1 component length.
571 * \param end End of ASN.1 decoding data buffer.
572 * \param buf_size Size of the supplied string buffer. (Must be nonzero)
573 * \param str Where to put the decoded string.
574 * \param str_len Length of the decoded string.
575 *
576 * \note The string will be null terminated just in case.
577 * The buffer needs to have enough room for a null terminator.
578 * \note The parse will fail if the parsed string is too large for
579 * the supplied buffer.
580 *
581 * \retval Start of the next ASN.1 component on success.
582 * \retval NULL on error.
583 */
asn1_dec_string_bin(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,size_t buf_size,unsigned char * str,size_t * str_len)584 const unsigned char *asn1_dec_string_bin(struct pri *ctrl, const char *name,
585 unsigned tag, const unsigned char *pos, const unsigned char *end, size_t buf_size,
586 unsigned char *str, size_t *str_len)
587 {
588 int length;
589 size_t sub_buf_size;
590 size_t sub_str_len;
591 unsigned char *sub_str;
592
593 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
594 if (length < 0) {
595 /* This is an indefinite length string */
596 if (ctrl->debug & PRI_DEBUG_APDU) {
597 pri_message(ctrl, " %s %s = Indefinite length string\n", name,
598 asn1_tag2str(tag));
599 }
600 if ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED) {
601 /*
602 * This is an ITU encoded indefinite length string
603 * and could contain null.
604 */
605
606 /* Ensure that an empty string is null terminated. */
607 *str = 0;
608
609 /* Collect all substrings into the original string buffer. */
610 *str_len = 0;
611 sub_str = str;
612 sub_buf_size = buf_size;
613 for (;;) {
614 ASN1_CALL(pos, asn1_dec_tag(pos, end, &tag));
615 if (tag == ASN1_INDEF_TERM) {
616 /* End-of-contents octets */
617 break;
618 }
619
620 /* Append the substring to the accumulated indefinite string. */
621 ASN1_CALL(pos, asn1_dec_string_bin(ctrl, name, tag, pos, end,
622 sub_buf_size, sub_str, &sub_str_len));
623
624 sub_buf_size -= sub_str_len;
625 sub_str += sub_str_len;
626 *str_len += sub_str_len;
627 }
628 } else {
629 /*
630 * This is a non-ITU encoded indefinite length string
631 * and must not contain null's.
632 */
633 for (length = 0;; ++length) {
634 if (end <= pos + length) {
635 /* Not enough buffer left */
636 return NULL;
637 }
638 if (pos[length] == 0) {
639 /* Found End-of-contents octets */
640 break;
641 }
642 }
643
644 if (buf_size - 1 < length) {
645 /* The destination buffer is not large enough for the data */
646 if (ctrl->debug & PRI_DEBUG_APDU) {
647 pri_message(ctrl, " String buffer not large enough!\n");
648 }
649 return NULL;
650 }
651
652 /* Extract the string and null terminate it. */
653 memcpy(str, pos, length);
654 str[length] = 0;
655 *str_len = length;
656
657 pos += length + 1;
658 }
659 if (end <= pos) {
660 /* Not enough buffer left for End-of-contents octets */
661 return NULL;
662 }
663 if (*pos++ != 0) {
664 /* We actually did not find the End-of-contents octets. */
665 return NULL;
666 }
667 if (ctrl->debug & PRI_DEBUG_APDU) {
668 /* Dump the collected string buffer contents. */
669 pri_message(ctrl, " Completed string =\n");
670 asn1_dump_mem(ctrl, 6, str, *str_len);
671 }
672 } else {
673 /* This is a definite length string */
674 if (buf_size - 1 < length) {
675 /* The destination buffer is not large enough for the data */
676 if (ctrl->debug & PRI_DEBUG_APDU) {
677 pri_message(ctrl, " %s %s = Buffer not large enough!\n", name,
678 asn1_tag2str(tag));
679 }
680 return NULL;
681 }
682
683 /* Extract the string and null terminate it. */
684 memcpy(str, pos, length);
685 str[length] = 0;
686 *str_len = length;
687
688 pos += length;
689
690 if (ctrl->debug & PRI_DEBUG_APDU) {
691 /* Dump the collected string buffer contents. */
692 pri_message(ctrl, " %s %s =\n", name, asn1_tag2str(tag));
693 asn1_dump_mem(ctrl, 4, str, *str_len);
694 }
695 }
696
697 return pos;
698 }
699
700 /*!
701 * \brief Decode a string that can be truncated to a maximum length primitive.
702 *
703 * \param ctrl D channel controller for any diagnostic messages.
704 * \param name Field name
705 * \param tag Component tag that identified this primitive.
706 * \param pos Starting position of the ASN.1 component length.
707 * \param end End of ASN.1 decoding data buffer.
708 * \param buf_size Size of the supplied string buffer. (Must be nonzero)
709 * \param str Where to put the decoded null terminated string.
710 * \param str_len Length of the decoded string.
711 * (computed for convenience since you could just do a strlen())
712 *
713 * \note The parsed string will be truncated if the string buffer
714 * cannot contain it.
715 *
716 * \retval Start of the next ASN.1 component on success.
717 * \retval NULL on error.
718 */
asn1_dec_string_max(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,size_t buf_size,unsigned char * str,size_t * str_len)719 const unsigned char *asn1_dec_string_max(struct pri *ctrl, const char *name,
720 unsigned tag, const unsigned char *pos, const unsigned char *end, size_t buf_size,
721 unsigned char *str, size_t *str_len)
722 {
723 int length;
724 size_t str_length;
725 size_t sub_buf_size;
726 size_t sub_str_len;
727 unsigned char *sub_str;
728
729 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
730 if (length < 0) {
731 /* This is an indefinite length string */
732 if (ctrl->debug & PRI_DEBUG_APDU) {
733 pri_message(ctrl, " %s %s = Indefinite length string\n", name,
734 asn1_tag2str(tag));
735 }
736 if ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED) {
737 /* This is an ITU encoded indefinite length string. */
738
739 /* Ensure that an empty string is null terminated. */
740 *str = 0;
741
742 /* Collect all substrings into the original string buffer. */
743 *str_len = 0;
744 sub_str = str;
745 sub_buf_size = buf_size;
746 for (;;) {
747 ASN1_CALL(pos, asn1_dec_tag(pos, end, &tag));
748 if (tag == ASN1_INDEF_TERM) {
749 /* End-of-contents octets */
750 break;
751 }
752
753 /* Append the substring to the accumulated indefinite string. */
754 ASN1_CALL(pos, asn1_dec_string_max(ctrl, name, tag, pos, end,
755 sub_buf_size, sub_str, &sub_str_len));
756
757 sub_buf_size -= sub_str_len;
758 sub_str += sub_str_len;
759 *str_len += sub_str_len;
760 }
761 } else {
762 /* This is a non-ITU encoded indefinite length string. */
763 for (length = 0;; ++length) {
764 if (end <= pos + length) {
765 /* Not enough buffer left */
766 return NULL;
767 }
768 if (pos[length] == 0) {
769 /* Found End-of-contents octets */
770 break;
771 }
772 }
773
774 /* Extract the string, truncate if necessary, and terminate it. */
775 str_length = (buf_size - 1 < length) ? buf_size - 1 : length;
776 memcpy(str, pos, str_length);
777 str[str_length] = 0;
778 *str_len = str_length;
779
780 pos += length + 1;
781 }
782 if (end <= pos) {
783 /* Not enough buffer left for End-of-contents octets */
784 return NULL;
785 }
786 if (*pos++ != 0) {
787 /* We actually did not find the End-of-contents octets. */
788 return NULL;
789 }
790 if (ctrl->debug & PRI_DEBUG_APDU) {
791 pri_message(ctrl, " Completed string = \"%s\"\n", str);
792 }
793 } else {
794 /*
795 * This is a definite length string
796 *
797 * Extract the string, truncate if necessary, and terminate it.
798 */
799 str_length = (buf_size - 1 < length) ? buf_size - 1 : length;
800 memcpy(str, pos, str_length);
801 str[str_length] = 0;
802 *str_len = str_length;
803
804 pos += length;
805
806 if (ctrl->debug & PRI_DEBUG_APDU) {
807 pri_message(ctrl, " %s %s = \"%s\"\n", name, asn1_tag2str(tag), str);
808 }
809 }
810
811 return pos;
812 }
813
814 /*!
815 * \internal
816 * \brief Recursive ASN.1 buffer decoding dump helper.
817 *
818 * \param ctrl D channel controller for any diagnostic messages.
819 * \param pos ASN.1 tag starting position.
820 * \param end End of ASN.1 decoding data buffer.
821 * \param level Indentation level to use.
822 * \param indefinite_term TRUE if to stop on an indefinite length terminator.
823 *
824 * \retval Start of the next ASN.1 component on success.
825 * \retval NULL on error.
826 */
asn1_dump_helper(struct pri * ctrl,const unsigned char * pos,const unsigned char * end,unsigned level,unsigned indefinite_term)827 static const unsigned char *asn1_dump_helper(struct pri *ctrl, const unsigned char *pos,
828 const unsigned char *end, unsigned level, unsigned indefinite_term)
829 {
830 unsigned delimiter;
831 unsigned tag;
832 int length;
833 const unsigned char *len_pos;
834
835 while (pos < end && (!indefinite_term || *pos != ASN1_INDEF_TERM)) {
836 /* Decode the tag */
837 pri_message(ctrl, "%*s", 2 * level, "");
838 len_pos = asn1_dec_tag(pos, end, &tag);
839 if (!len_pos) {
840 pri_message(ctrl, "Invalid tag encoding!\n");
841 return NULL;
842 }
843
844 /* Dump the tag contents. */
845 pri_message(ctrl, "%s ", asn1_tag2str(tag));
846 delimiter = '<';
847 while (pos < len_pos) {
848 pri_message(ctrl, "%c%02X", delimiter, *pos);
849 delimiter = ' ';
850 ++pos;
851 }
852 pri_message(ctrl, "> ");
853
854 /* Decode the length */
855 pos = asn1_dec_length(len_pos, end, &length);
856 if (!pos) {
857 pri_message(ctrl, "Invalid length encoding!\n");
858 return NULL;
859 }
860
861 /* Dump the length contents. */
862 if (length < 0) {
863 pri_message(ctrl, "Indefinite length ");
864 } else {
865 pri_message(ctrl, "Len:%d ", length);
866 }
867 delimiter = '<';
868 while (len_pos < pos) {
869 pri_message(ctrl, "%c%02X", delimiter, *len_pos);
870 delimiter = ' ';
871 ++len_pos;
872 }
873 pri_message(ctrl, ">\n");
874
875 /* Dump the body contents */
876 ++level;
877 if (length < 0) {
878 /* Indefinite length */
879 if ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED) {
880 /* This is an ITU encoded indefinite length component. */
881 ASN1_CALL(pos, asn1_dump_helper(ctrl, pos, end, level, 1));
882 } else if (tag == (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SET)
883 || tag ==
884 (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SEQUENCE)) {
885 pri_message(ctrl, "%*sThis tag must always be constructed!\n", 2 * level,
886 "");
887 /* Assume tag was constructed to keep going */
888 ASN1_CALL(pos, asn1_dump_helper(ctrl, pos, end, level, 1));
889 } else {
890 /* This is a non-ITU encoded indefinite length component. */
891 pri_message(ctrl, "%*sNon-ITU indefininte length component.\n",
892 2 * level, "");
893 length = 0;
894 while (pos + length < end && pos[length] != ASN1_INDEF_TERM) {
895 ++length;
896 }
897 if (length) {
898 asn1_dump_mem(ctrl, 2 * level, pos, length);
899 pos += length;
900 }
901 }
902 --level;
903 if (end < pos + ASN1_INDEF_TERM_LEN) {
904 pri_message(ctrl, "%*sNot enough room for the End-of-contents octets!\n",
905 2 * level, "");
906 pos = end;
907 } else {
908 pri_message(ctrl, "%*sEnd-of-contents <%02X %02X>%s\n", 2 * level, "",
909 pos[0], pos[1], (pos[1] != 0) ? " Invalid!" : "");
910 pos += ASN1_INDEF_TERM_LEN;
911 }
912 } else {
913 /* Defininte length */
914 if ((tag & ASN1_PC_MASK) == ASN1_PC_CONSTRUCTED) {
915 /* Dump constructed contents */
916 ASN1_CALL(pos, asn1_dump_helper(ctrl, pos, pos + length, level, 0));
917 } else if (tag == (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SET)
918 || tag ==
919 (ASN1_CLASS_UNIVERSAL | ASN1_PC_PRIMITIVE | ASN1_TYPE_SEQUENCE)) {
920 /* Assume tag was constructed to keep going */
921 pri_message(ctrl, "%*sThis tag must always be constructed!\n", 2 * level,
922 "");
923 ASN1_CALL(pos, asn1_dump_helper(ctrl, pos, pos + length, level, 0));
924 } else if (0 < length) {
925 /* Dump primitive contents. */
926 asn1_dump_mem(ctrl, 2 * level, pos, length);
927 pos += length;
928 }
929 --level;
930 }
931
932 #if 0
933 pri_message(ctrl, "%*sEnd\n", 2 * level, "");
934 #endif
935 }
936
937 return pos;
938 }
939
940 /*!
941 * \brief Dump the given ASN.1 buffer contents.
942 *
943 * \param ctrl D channel controller for any diagnostic messages.
944 * \param start_asn1 First octet in the ASN.1 buffer. (ASN.1 tag starting position)
945 * \param end One beyond the last octet in the ASN.1 buffer.
946 *
947 * \return Nothing
948 */
asn1_dump(struct pri * ctrl,const unsigned char * start_asn1,const unsigned char * end)949 void asn1_dump(struct pri *ctrl, const unsigned char *start_asn1,
950 const unsigned char *end)
951 {
952 pri_message(ctrl, "ASN.1 dump\n");
953 if (start_asn1) {
954 asn1_dump_helper(ctrl, start_asn1, end, 1, 0);
955 }
956 pri_message(ctrl, "ASN.1 end\n");
957 }
958
959 /*!
960 * \brief Encode the length of an ASN.1 component body of predetermined size.
961 *
962 * \param len_pos Starting position of the ASN.1 component length.
963 * \param end End of ASN.1 encoding data buffer.
964 * \param length Predetermined component body length.
965 *
966 * \note The encoding buffer does not need to be checked after calling.
967 * It is already checked to have the requested room.
968 *
969 * \retval Next octet after the length on success.
970 * \retval NULL on error.
971 */
asn1_enc_length(unsigned char * len_pos,unsigned char * end,size_t length)972 unsigned char *asn1_enc_length(unsigned char *len_pos, unsigned char *end, size_t length)
973 {
974 u_int32_t body_length; /* Length of component contents */
975 u_int32_t value;
976 u_int32_t test_mask;
977 unsigned length_size; /* Length of the length encoding */
978
979 body_length = length;
980
981 /* Determine length encoding length */
982 if (body_length < 128) {
983 length_size = 1;
984 } else {
985 /* Find most significant octet of 32 bit integer that carries meaning. */
986 test_mask = 0xFF000000;
987 for (length_size = 4; --length_size;) {
988 if (body_length & test_mask) {
989 /*
990 * Found the first 8 bits of a multiple octet length that
991 * is not all zeroes.
992 */
993 break;
994 }
995 test_mask >>= 8;
996 }
997 length_size += 1 + 1;
998 }
999
1000 if (end < len_pos + length_size + body_length) {
1001 /* No room for the length and component body in the buffer */
1002 return NULL;
1003 }
1004
1005 /* Encode the component body length */
1006 if (length_size == 1) {
1007 *len_pos++ = body_length;
1008 } else {
1009 *len_pos++ = 0x80 | --length_size;
1010 while (length_size--) {
1011 value = body_length;
1012 value >>= (8 * length_size);
1013 *len_pos++ = value & 0xFF;
1014 }
1015 }
1016
1017 return len_pos;
1018 }
1019
1020 /*!
1021 * \brief Encode the length of an already encoded ASN.1 component.
1022 *
1023 * \param len_pos Starting position of the ASN.1 component length.
1024 * \param component_end Next octet after the component body.
1025 * \param end End of ASN.1 encoding data buffer.
1026 *
1027 * \note The total component size could increase or decrease.
1028 * \note The component length field must have been initialized with
1029 * ASN1_LEN_INIT() or ASN1_CONSTRUCTED_BEGIN().
1030 *
1031 * \retval Next octet after the component body on success.
1032 * \retval NULL on error.
1033 */
asn1_enc_length_fixup(unsigned char * len_pos,unsigned char * component_end,unsigned char * end)1034 unsigned char *asn1_enc_length_fixup(unsigned char *len_pos,
1035 unsigned char *component_end, unsigned char *end)
1036 {
1037 u_int32_t body_length; /* Length of component contents */
1038 u_int32_t value;
1039 u_int32_t test_mask;
1040 unsigned length_size; /* Length of the length encoding */
1041
1042 if (component_end < len_pos + *len_pos) {
1043 /* Sanity check */
1044 return NULL;
1045 }
1046
1047 body_length = component_end - len_pos - *len_pos;
1048
1049 /* Determine length encoding length */
1050 if (body_length < 128) {
1051 length_size = 1;
1052 } else {
1053 /* Find most significant octet of 32 bit integer that carries meaning. */
1054 test_mask = 0xFF000000;
1055 for (length_size = 4; --length_size;) {
1056 if (body_length & test_mask) {
1057 /*
1058 * Found the first 8 bits of a multiple octet length that
1059 * is not all zeroes.
1060 */
1061 break;
1062 }
1063 test_mask >>= 8;
1064 }
1065 length_size += 1 + 1;
1066 }
1067
1068 component_end = len_pos + length_size + body_length;
1069 if (end < component_end) {
1070 /* No room for the component in the buffer */
1071 return NULL;
1072 }
1073 if (length_size != *len_pos) {
1074 /* Must shift the component body */
1075 memmove(len_pos + length_size, len_pos + *len_pos, body_length);
1076 }
1077
1078 /* Encode the component body length */
1079 if (length_size == 1) {
1080 *len_pos = body_length;
1081 } else {
1082 *len_pos++ = 0x80 | --length_size;
1083 while (length_size--) {
1084 value = body_length;
1085 value >>= (8 * length_size);
1086 *len_pos++ = value & 0xFF;
1087 }
1088 }
1089
1090 return component_end;
1091 }
1092
1093 /*!
1094 * \brief Encode the boolean primitive.
1095 *
1096 * \param pos Starting position to encode ASN.1 component.
1097 * \param end End of ASN.1 encoding data buffer.
1098 * \param tag Component tag to identify the encoded component.
1099 * \param value Component value to encode.
1100 *
1101 * \retval Start of the next ASN.1 component to encode on success.
1102 * \retval NULL on error.
1103 */
asn1_enc_boolean(unsigned char * pos,unsigned char * end,unsigned tag,int32_t value)1104 unsigned char *asn1_enc_boolean(unsigned char *pos, unsigned char *end, unsigned tag,
1105 int32_t value)
1106 {
1107 if (end < pos + 3) {
1108 /* No room for the component in the buffer */
1109 return NULL;
1110 }
1111
1112 /* Encode component */
1113 *pos++ = tag;
1114 *pos++ = 1;
1115 *pos++ = value ? 1 : 0;
1116
1117 return pos;
1118 }
1119
1120 /*!
1121 * \brief Encode the integer type primitive.
1122 *
1123 * \param pos Starting position to encode ASN.1 component.
1124 * \param end End of ASN.1 encoding data buffer.
1125 * \param tag Component tag to identify the encoded component.
1126 * \param value Component value to encode.
1127 *
1128 * \retval Start of the next ASN.1 component to encode on success.
1129 * \retval NULL on error.
1130 */
asn1_enc_int(unsigned char * pos,unsigned char * end,unsigned tag,int32_t value)1131 unsigned char *asn1_enc_int(unsigned char *pos, unsigned char *end, unsigned tag,
1132 int32_t value)
1133 {
1134 unsigned count;
1135 u_int32_t test_mask;
1136 u_int32_t val;
1137
1138 /* Find most significant octet of 32 bit integer that carries meaning. */
1139 test_mask = 0xFF800000;
1140 val = (u_int32_t) value;
1141 for (count = 4; --count;) {
1142 if ((val & test_mask) != test_mask && (val & test_mask) != 0) {
1143 /*
1144 * The first 9 bits of a multiple octet integer is not
1145 * all ones or zeroes.
1146 */
1147 break;
1148 }
1149 test_mask >>= 8;
1150 }
1151
1152 if (end < pos + 3 + count) {
1153 /* No room for the component in the buffer */
1154 return NULL;
1155 }
1156
1157 /* Encode component */
1158 *pos++ = tag;
1159 *pos++ = count + 1;
1160 do {
1161 val = (u_int32_t) value;
1162 val >>= (8 * count);
1163 *pos++ = val & 0xFF;
1164 } while (count--);
1165
1166 return pos;
1167 }
1168
1169 /*!
1170 * \brief Encode the null type primitive.
1171 *
1172 * \param pos Starting position to encode ASN.1 component.
1173 * \param end End of ASN.1 encoding data buffer.
1174 * \param tag Component tag to identify the encoded component.
1175 *
1176 * \retval Start of the next ASN.1 component to encode on success.
1177 * \retval NULL on error.
1178 */
asn1_enc_null(unsigned char * pos,unsigned char * end,unsigned tag)1179 unsigned char *asn1_enc_null(unsigned char *pos, unsigned char *end, unsigned tag)
1180 {
1181 if (end < pos + 2) {
1182 /* No room for the component in the buffer */
1183 return NULL;
1184 }
1185
1186 /* Encode component */
1187 *pos++ = tag;
1188 *pos++ = 0;
1189
1190 return pos;
1191 }
1192
1193 /*!
1194 * \brief Encode the object identifier (OID) primitive.
1195 *
1196 * \param pos Starting position to encode ASN.1 component.
1197 * \param end End of ASN.1 encoding data buffer.
1198 * \param tag Component tag to identify the encoded component.
1199 * \param oid Component value to encode.
1200 *
1201 * \retval Start of the next ASN.1 component to encode on success.
1202 * \retval NULL on error.
1203 */
asn1_enc_oid(unsigned char * pos,unsigned char * end,unsigned tag,const struct asn1_oid * oid)1204 unsigned char *asn1_enc_oid(unsigned char *pos, unsigned char *end, unsigned tag,
1205 const struct asn1_oid *oid)
1206 {
1207 unsigned char *len_pos;
1208 unsigned num_values;
1209 unsigned count;
1210 u_int32_t value;
1211
1212 if (end < pos + 2) {
1213 /* No room for the component tag and length in the buffer */
1214 return NULL;
1215 }
1216
1217 *pos++ = tag;
1218 len_pos = pos++;
1219
1220 /* For all OID subidentifer values */
1221 for (num_values = 0; num_values < oid->num_values; ++num_values) {
1222 /*
1223 * Count the number of 7 bit chunks that are needed
1224 * to encode the integer.
1225 */
1226 value = oid->value[num_values] >> 7;
1227 for (count = 0; value; ++count) {
1228 /* There are bits still set */
1229 value >>= 7;
1230 }
1231
1232 if (end < pos + count + 1) {
1233 /* No room for the component body in the buffer */
1234 return NULL;
1235 }
1236
1237 /* Store OID subidentifier value */
1238 do {
1239 value = oid->value[num_values];
1240 value >>= (7 * count);
1241 *pos++ = (value & 0x7F) | (count ? 0x80 : 0);
1242 } while (count--);
1243 }
1244
1245 /* length */
1246 *len_pos = pos - len_pos - 1;
1247
1248 return pos;
1249 }
1250
1251 /*!
1252 * \brief Encode the binary string type primitive.
1253 *
1254 * \param pos Starting position to encode ASN.1 component.
1255 * \param end End of ASN.1 encoding data buffer.
1256 * \param tag Component tag to identify the encoded component.
1257 * \param str Binary string to encode.
1258 * \param str_len Length of binary string to encode.
1259 *
1260 * \retval Start of the next ASN.1 component to encode on success.
1261 * \retval NULL on error.
1262 */
asn1_enc_string_bin(unsigned char * pos,unsigned char * end,unsigned tag,const unsigned char * str,size_t str_len)1263 unsigned char *asn1_enc_string_bin(unsigned char *pos, unsigned char *end, unsigned tag,
1264 const unsigned char *str, size_t str_len)
1265 {
1266 if (end < pos + 1) {
1267 /* No room for the component tag in the buffer */
1268 return NULL;
1269 }
1270
1271 /* Encode component */
1272 *pos++ = tag;
1273 ASN1_CALL(pos, asn1_enc_length(pos, end, str_len));
1274 memcpy(pos, str, str_len);
1275
1276 return pos + str_len;
1277 }
1278
1279 /*!
1280 * \brief Encode a string that can be truncated to a maximum length primitive.
1281 *
1282 * \param pos Starting position to encode ASN.1 component.
1283 * \param end End of ASN.1 encoding data buffer.
1284 * \param tag Component tag to identify the encoded component.
1285 * \param str Null terminated string to encode.
1286 * \param max_len Maximum length of string to encode.
1287 *
1288 * \note The string will be truncated if it is too long.
1289 *
1290 * \retval Start of the next ASN.1 component to encode on success.
1291 * \retval NULL on error.
1292 */
asn1_enc_string_max(unsigned char * pos,unsigned char * end,unsigned tag,const unsigned char * str,size_t max_len)1293 unsigned char *asn1_enc_string_max(unsigned char *pos, unsigned char *end, unsigned tag,
1294 const unsigned char *str, size_t max_len)
1295 {
1296 size_t str_len;
1297
1298 str_len = strlen((char *) str);
1299 if (max_len < str_len) {
1300 str_len = max_len;
1301 }
1302 return asn1_enc_string_bin(pos, end, tag, str, str_len);
1303 }
1304
1305 /* ------------------------------------------------------------------- */
1306 /* end asn1_primitive.c */
1307