Added functions to parse the certificate policies extention.
[gnutls.git] / lib / minitasn1 / decoding.c
blob79766a1802ceb64ec08bd6099b4def5da827414c
1 /*
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
6 * The LIBTASN1 library is free software; you can redistribute it
7 * and/or modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: decoding.c */
25 /* Description: Functions to manage DER decoding */
26 /*****************************************************/
28 #include <int.h>
29 #include "parser_aux.h"
30 #include <gstr.h>
31 #include "structure.h"
32 #include "element.h"
33 #include <limits.h>
35 static int
36 _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
38 static void
39 _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
42 Estrcpy (ErrorDescription, ":: tag error near element '");
43 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
44 ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
45 Estrcat (ErrorDescription, "'");
49 /**
50 * asn1_get_length_der:
51 * @der: DER data to decode.
52 * @der_len: Length of DER data to decode.
53 * @len: Output variable containing the length of the DER length field.
55 * Extract a length field from DER data.
57 * Returns: Return the decoded length value, or -1 on indefinite
58 * length, or -2 when the value was too big to fit in a int, or -4
59 * when the decoded length value plus @len would exceed @der_len.
60 **/
61 long
62 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
64 unsigned int ans, sum, last;
65 int k, punt;
67 *len = 0;
68 if (der_len <= 0)
69 return 0;
71 if (!(der[0] & 128))
73 /* short form */
74 *len = 1;
75 ans = der[0];
77 else
79 /* Long form */
80 k = der[0] & 0x7F;
81 punt = 1;
82 if (k)
83 { /* definite length method */
84 ans = 0;
85 while (punt <= k && punt < der_len)
87 last = ans;
89 ans = (ans*256) + der[punt++];
90 if (ans < last)
91 /* we wrapped around, no bignum support... */
92 return -2;
95 else
96 { /* indefinite length method */
97 *len = punt;
98 return -1;
101 *len = punt;
104 sum = ans + *len;
106 /* check for overflow as well INT_MAX as a maximum upper
107 * limit for length */
108 if (sum >= INT_MAX || sum < ans)
109 return -2;
111 if (((int) sum) > der_len)
112 return -4;
114 return ans;
118 * asn1_get_tag_der:
119 * @der: DER data to decode.
120 * @der_len: Length of DER data to decode.
121 * @cls: Output variable containing decoded class.
122 * @len: Output variable containing the length of the DER TAG data.
123 * @tag: Output variable containing the decoded tag.
125 * Decode the class and TAG from DER code.
127 * Returns: Returns %ASN1_SUCCESS on success, or an error.
130 asn1_get_tag_der (const unsigned char *der, int der_len,
131 unsigned char *cls, int *len, unsigned long *tag)
133 unsigned int ris;
134 int punt;
135 unsigned int last;
137 if (der == NULL || der_len < 2 || len == NULL)
138 return ASN1_DER_ERROR;
140 *cls = der[0] & 0xE0;
141 if ((der[0] & 0x1F) != 0x1F)
143 /* short form */
144 *len = 1;
145 ris = der[0] & 0x1F;
147 else
149 /* Long form */
150 punt = 1;
151 ris = 0;
152 while (punt <= der_len && der[punt] & 128)
154 last = ris;
156 ris = (ris * 128) + (der[punt++] & 0x7F);
157 if (ris < last)
158 /* wrapped around, and no bignums... */
159 return ASN1_DER_ERROR;
162 if (punt >= der_len)
163 return ASN1_DER_ERROR;
165 last = ris;
167 ris = (ris * 128) + (der[punt++] & 0x7F);
168 if (ris < last)
169 return ASN1_DER_ERROR;
171 *len = punt;
173 if (tag)
174 *tag = ris;
175 return ASN1_SUCCESS;
179 * asn1_get_length_ber:
180 * @ber: BER data to decode.
181 * @ber_len: Length of BER data to decode.
182 * @len: Output variable containing the length of the BER length field.
184 * Extract a length field from BER data. The difference to
185 * asn1_get_length_der() is that this function will return a length
186 * even if the value has indefinite encoding.
188 * Returns: Return the decoded length value, or negative value when
189 * the value was too big.
191 * Since: 2.0
193 long
194 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
196 int ret;
197 long err;
199 ret = asn1_get_length_der (ber, ber_len, len);
200 if (ret == -1)
201 { /* indefinite length method */
202 ret = ber_len;
203 err = _asn1_get_indefinite_length_string (ber + 1, &ret);
204 if (err != ASN1_SUCCESS)
205 return -3;
208 return ret;
212 * asn1_get_octet_der:
213 * @der: DER data to decode containing the OCTET SEQUENCE.
214 * @der_len: Length of DER data to decode.
215 * @ret_len: Output variable containing the length of the DER data.
216 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
217 * @str_size: Length of pre-allocated output buffer.
218 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
220 * Extract an OCTET SEQUENCE from DER data.
222 * Returns: Returns %ASN1_SUCCESS on success, or an error.
225 asn1_get_octet_der (const unsigned char *der, int der_len,
226 int *ret_len, unsigned char *str, int str_size,
227 int *str_len)
229 int len_len;
231 if (der_len <= 0)
232 return ASN1_GENERIC_ERROR;
234 /* if(str==NULL) return ASN1_SUCCESS; */
235 *str_len = asn1_get_length_der (der, der_len, &len_len);
237 if (*str_len < 0)
238 return ASN1_DER_ERROR;
240 *ret_len = *str_len + len_len;
241 if (str_size >= *str_len)
242 memcpy (str, der + len_len, *str_len);
243 else
245 return ASN1_MEM_ERROR;
248 return ASN1_SUCCESS;
251 /* Returns ASN1_SUCCESS on success or an error code on error.
253 static int
254 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
255 char *str, int str_size)
257 int len_len, str_len;
259 if (der_len <= 0 || str == NULL)
260 return ASN1_DER_ERROR;
261 str_len = asn1_get_length_der (der, der_len, &len_len);
262 if (str_len < 0 || str_size < str_len)
263 return ASN1_DER_ERROR;
264 memcpy (str, der + len_len, str_len);
265 str[str_len] = 0;
266 *ret_len = str_len + len_len;
268 return ASN1_SUCCESS;
271 static int
272 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
273 char *str, int str_size)
275 int len_len, len, k;
276 int leading;
277 char temp[20];
278 unsigned long val, val1, prev_val;
280 *ret_len = 0;
281 if (str && str_size > 0)
282 str[0] = 0; /* no oid */
284 if (str == NULL || der_len <= 0)
285 return ASN1_GENERIC_ERROR;
286 len = asn1_get_length_der (der, der_len, &len_len);
288 if (len < 0 || len > der_len || len_len > der_len)
289 return ASN1_DER_ERROR;
291 val1 = der[len_len] / 40;
292 val = der[len_len] - val1 * 40;
294 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
295 _asn1_str_cat (str, str_size, ".");
296 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
298 prev_val = 0;
299 val = 0;
300 leading = 1;
301 for (k = 1; k < len; k++)
303 /* X.690 mandates that the leading byte must never be 0x80
305 if (leading != 0 && der[len_len + k] == 0x80)
306 return ASN1_DER_ERROR;
307 leading = 0;
309 /* check for wrap around */
310 val = val << 7;
311 val |= der[len_len + k] & 0x7F;
313 if (val < prev_val)
314 return ASN1_DER_ERROR;
316 prev_val = val;
318 if (!(der[len_len + k] & 0x80))
320 _asn1_str_cat (str, str_size, ".");
321 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
322 val = 0;
323 prev_val = 0;
324 leading = 1;
327 *ret_len = len + len_len;
329 return ASN1_SUCCESS;
333 * asn1_get_bit_der:
334 * @der: DER data to decode containing the BIT SEQUENCE.
335 * @der_len: Length of DER data to decode.
336 * @ret_len: Output variable containing the length of the DER data.
337 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
338 * @str_size: Length of pre-allocated output buffer.
339 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
341 * Extract a BIT SEQUENCE from DER data.
343 * Returns: Return %ASN1_SUCCESS on success, or an error.
346 asn1_get_bit_der (const unsigned char *der, int der_len,
347 int *ret_len, unsigned char *str, int str_size,
348 int *bit_len)
350 int len_len, len_byte;
352 if (der_len <= 0)
353 return ASN1_GENERIC_ERROR;
354 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
355 if (len_byte < 0)
356 return ASN1_DER_ERROR;
358 *ret_len = len_byte + len_len + 1;
359 *bit_len = len_byte * 8 - der[len_len];
361 if (str_size >= len_byte)
362 memcpy (str, der + len_len + 1, len_byte);
363 else
365 return ASN1_MEM_ERROR;
368 return ASN1_SUCCESS;
371 static int
372 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
373 int *ret_len)
375 asn1_node p;
376 int counter, len2, len3, is_tag_implicit;
377 unsigned long tag, tag_implicit = 0;
378 unsigned char class, class2, class_implicit = 0;
380 if (der_len <= 0)
381 return ASN1_GENERIC_ERROR;
383 counter = is_tag_implicit = 0;
385 if (node->type & CONST_TAG)
387 p = node->down;
388 while (p)
390 if (type_field (p->type) == TYPE_TAG)
392 if (p->type & CONST_APPLICATION)
393 class2 = ASN1_CLASS_APPLICATION;
394 else if (p->type & CONST_UNIVERSAL)
395 class2 = ASN1_CLASS_UNIVERSAL;
396 else if (p->type & CONST_PRIVATE)
397 class2 = ASN1_CLASS_PRIVATE;
398 else
399 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
401 if (p->type & CONST_EXPLICIT)
403 if (asn1_get_tag_der
404 (der + counter, der_len - counter, &class, &len2,
405 &tag) != ASN1_SUCCESS)
406 return ASN1_DER_ERROR;
408 if (counter + len2 > der_len)
409 return ASN1_DER_ERROR;
410 counter += len2;
412 len3 =
413 asn1_get_length_ber (der + counter, der_len - counter,
414 &len2);
415 if (len3 < 0)
416 return ASN1_DER_ERROR;
418 counter += len2;
419 if (counter > der_len)
420 return ASN1_DER_ERROR;
422 if (!is_tag_implicit)
424 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
425 (tag != strtoul ((char *) p->value, NULL, 10)))
426 return ASN1_TAG_ERROR;
428 else
429 { /* ASN1_TAG_IMPLICIT */
430 if ((class != class_implicit) || (tag != tag_implicit))
431 return ASN1_TAG_ERROR;
433 is_tag_implicit = 0;
435 else
436 { /* ASN1_TAG_IMPLICIT */
437 if (!is_tag_implicit)
439 if ((type_field (node->type) == TYPE_SEQUENCE) ||
440 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
441 (type_field (node->type) == TYPE_SET) ||
442 (type_field (node->type) == TYPE_SET_OF))
443 class2 |= ASN1_CLASS_STRUCTURED;
444 class_implicit = class2;
445 tag_implicit = strtoul ((char *) p->value, NULL, 10);
446 is_tag_implicit = 1;
450 p = p->right;
454 if (is_tag_implicit)
456 if (asn1_get_tag_der
457 (der + counter, der_len - counter, &class, &len2,
458 &tag) != ASN1_SUCCESS)
459 return ASN1_DER_ERROR;
460 if (counter + len2 > der_len)
461 return ASN1_DER_ERROR;
463 if ((class != class_implicit) || (tag != tag_implicit))
465 if (type_field (node->type) == TYPE_OCTET_STRING)
467 class_implicit |= ASN1_CLASS_STRUCTURED;
468 if ((class != class_implicit) || (tag != tag_implicit))
469 return ASN1_TAG_ERROR;
471 else
472 return ASN1_TAG_ERROR;
475 else
477 if (type_field (node->type) == TYPE_TAG)
479 counter = 0;
480 *ret_len = counter;
481 return ASN1_SUCCESS;
484 if (asn1_get_tag_der
485 (der + counter, der_len - counter, &class, &len2,
486 &tag) != ASN1_SUCCESS)
487 return ASN1_DER_ERROR;
489 if (counter + len2 > der_len)
490 return ASN1_DER_ERROR;
492 switch (type_field (node->type))
494 case TYPE_NULL:
495 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
496 return ASN1_DER_ERROR;
497 break;
498 case TYPE_BOOLEAN:
499 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
500 return ASN1_DER_ERROR;
501 break;
502 case TYPE_INTEGER:
503 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
504 return ASN1_DER_ERROR;
505 break;
506 case TYPE_ENUMERATED:
507 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
508 return ASN1_DER_ERROR;
509 break;
510 case TYPE_OBJECT_ID:
511 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
512 return ASN1_DER_ERROR;
513 break;
514 case TYPE_TIME:
515 if (node->type & CONST_UTC)
517 if ((class != ASN1_CLASS_UNIVERSAL)
518 || (tag != ASN1_TAG_UTCTime))
519 return ASN1_DER_ERROR;
521 else
523 if ((class != ASN1_CLASS_UNIVERSAL)
524 || (tag != ASN1_TAG_GENERALIZEDTime))
525 return ASN1_DER_ERROR;
527 break;
528 case TYPE_OCTET_STRING:
529 if (((class != ASN1_CLASS_UNIVERSAL)
530 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
531 || (tag != ASN1_TAG_OCTET_STRING))
532 return ASN1_DER_ERROR;
533 break;
534 case TYPE_GENERALSTRING:
535 if ((class != ASN1_CLASS_UNIVERSAL)
536 || (tag != ASN1_TAG_GENERALSTRING))
537 return ASN1_DER_ERROR;
538 break;
539 case TYPE_BIT_STRING:
540 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
541 return ASN1_DER_ERROR;
542 break;
543 case TYPE_SEQUENCE:
544 case TYPE_SEQUENCE_OF:
545 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
546 || (tag != ASN1_TAG_SEQUENCE))
547 return ASN1_DER_ERROR;
548 break;
549 case TYPE_SET:
550 case TYPE_SET_OF:
551 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
552 || (tag != ASN1_TAG_SET))
553 return ASN1_DER_ERROR;
554 break;
555 case TYPE_ANY:
556 counter -= len2;
557 break;
558 default:
559 return ASN1_DER_ERROR;
560 break;
564 counter += len2;
565 *ret_len = counter;
566 return ASN1_SUCCESS;
569 static int
570 _asn1_delete_not_used (asn1_node node)
572 asn1_node p, p2;
574 if (node == NULL)
575 return ASN1_ELEMENT_NOT_FOUND;
577 p = node;
578 while (p)
580 if (p->type & CONST_NOT_USED)
582 p2 = NULL;
583 if (p != node)
585 p2 = _asn1_find_left (p);
586 if (!p2)
587 p2 = _asn1_find_up (p);
589 asn1_delete_structure (&p);
590 p = p2;
593 if (!p)
594 break; /* reach node */
596 if (p->down)
598 p = p->down;
600 else
602 if (p == node)
603 p = NULL;
604 else if (p->right)
605 p = p->right;
606 else
608 while (1)
610 p = _asn1_find_up (p);
611 if (p == node)
613 p = NULL;
614 break;
616 if (p->right)
618 p = p->right;
619 break;
625 return ASN1_SUCCESS;
628 static int
629 _asn1_extract_der_octet (asn1_node node, const unsigned char *der,
630 int der_len)
632 int len2, len3;
633 int counter2, counter_end;
635 len2 = asn1_get_length_der (der, der_len, &len3);
636 if (len2 < -1)
637 return ASN1_DER_ERROR;
639 counter2 = len3 + 1;
641 if (len2 == -1)
642 counter_end = der_len - 2;
643 else
644 counter_end = der_len;
646 while (counter2 < counter_end)
648 len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
650 if (len2 < -1)
651 return ASN1_DER_ERROR;
653 if (len2 > 0)
655 _asn1_append_value (node, der + counter2 + len3, len2);
657 else
658 { /* indefinite */
660 len2 =
661 _asn1_extract_der_octet (node, der + counter2 + len3,
662 der_len - counter2 - len3);
663 if (len2 < 0)
664 return len2;
667 counter2 += len2 + len3 + 1;
670 return ASN1_SUCCESS;
673 static int
674 _asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len)
676 int len2, len3, counter, tot_len, indefinite;
678 counter = 0;
680 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
682 tot_len = 0;
683 indefinite = asn1_get_length_der (der, *len, &len3);
684 if (indefinite < -1)
685 return ASN1_DER_ERROR;
687 counter += len3;
688 if (indefinite >= 0)
689 indefinite += len3;
691 while (1)
693 if (counter > (*len))
694 return ASN1_DER_ERROR;
696 if (indefinite == -1)
698 if ((der[counter] == 0) && (der[counter + 1] == 0))
700 counter += 2;
701 break;
704 else if (counter >= indefinite)
705 break;
707 if (der[counter] != ASN1_TAG_OCTET_STRING)
708 return ASN1_DER_ERROR;
710 counter++;
712 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
713 if (len2 <= 0)
714 return ASN1_DER_ERROR;
716 counter += len3 + len2;
717 tot_len += len2;
720 /* copy */
721 if (node)
723 unsigned char temp[DER_LEN];
724 int ret;
726 len2 = sizeof (temp);
728 asn1_length_der (tot_len, temp, &len2);
729 _asn1_set_value (node, temp, len2);
731 ret = _asn1_extract_der_octet (node, der, *len);
732 if (ret != ASN1_SUCCESS)
733 return ret;
737 else
738 { /* NOT STRUCTURED */
739 len2 = asn1_get_length_der (der, *len, &len3);
740 if (len2 < 0)
741 return ASN1_DER_ERROR;
743 counter = len3 + len2;
744 if (node)
745 _asn1_set_value (node, der, counter);
748 *len = counter;
749 return ASN1_SUCCESS;
753 static int
754 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
756 int len2, len3, counter, indefinite;
757 unsigned long tag;
758 unsigned char class;
760 counter = indefinite = 0;
762 while (1)
764 if ((*len) < counter)
765 return ASN1_DER_ERROR;
767 if ((der[counter] == 0) && (der[counter + 1] == 0))
769 counter += 2;
770 indefinite--;
771 if (indefinite <= 0)
772 break;
773 else
774 continue;
777 if (asn1_get_tag_der
778 (der + counter, *len - counter, &class, &len2,
779 &tag) != ASN1_SUCCESS)
780 return ASN1_DER_ERROR;
781 if (counter + len2 > *len)
782 return ASN1_DER_ERROR;
783 counter += len2;
784 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
785 if (len2 < -1)
786 return ASN1_DER_ERROR;
787 if (len2 == -1)
789 indefinite++;
790 counter += 1;
792 else
794 counter += len2 + len3;
798 *len = counter;
799 return ASN1_SUCCESS;
804 * asn1_der_decoding:
805 * @element: pointer to an ASN1 structure.
806 * @ider: vector that contains the DER encoding.
807 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
808 * @errorDescription: null-terminated string contains details when an
809 * error occurred.
811 * Fill the structure *@ELEMENT with values of a DER encoding
812 * string. The structure must just be created with function
813 * asn1_create_element(). If an error occurs during the decoding
814 * procedure, the *@ELEMENT is deleted and set equal to
815 * %NULL.
817 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
818 * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
819 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
820 * name (*@ELEMENT deleted).
823 asn1_der_decoding (asn1_node * element, const void *ider, int len,
824 char *errorDescription)
826 asn1_node node, p, p2, p3;
827 char temp[128];
828 int counter, len2, len3, len4, move, ris, tlen;
829 unsigned char class;
830 unsigned long tag;
831 int indefinite, result;
832 const unsigned char *der = ider;
834 node = *element;
836 if (errorDescription != NULL)
837 errorDescription[0] = 0;
839 if (node == NULL)
840 return ASN1_ELEMENT_NOT_FOUND;
842 if (node->type & CONST_OPTION)
844 result = ASN1_GENERIC_ERROR;
845 goto cleanup;
848 counter = 0;
849 move = DOWN;
850 p = node;
851 while (1)
853 ris = ASN1_SUCCESS;
854 if (move != UP)
856 if (p->type & CONST_SET)
858 p2 = _asn1_find_up (p);
859 len2 = _asn1_strtol (p2->value, NULL, 10);
860 if (len2 == -1)
862 if (!der[counter] && !der[counter + 1])
864 p = p2;
865 move = UP;
866 counter += 2;
867 continue;
870 else if (counter == len2)
872 p = p2;
873 move = UP;
874 continue;
876 else if (counter > len2)
878 result = ASN1_DER_ERROR;
879 goto cleanup;
881 p2 = p2->down;
882 while (p2)
884 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
886 if (type_field (p2->type) != TYPE_CHOICE)
887 ris =
888 _asn1_extract_tag_der (p2, der + counter,
889 len - counter, &len2);
890 else
892 p3 = p2->down;
893 while (p3)
895 ris =
896 _asn1_extract_tag_der (p3, der + counter,
897 len - counter, &len2);
898 if (ris == ASN1_SUCCESS)
899 break;
900 p3 = p3->right;
903 if (ris == ASN1_SUCCESS)
905 p2->type &= ~CONST_NOT_USED;
906 p = p2;
907 break;
910 p2 = p2->right;
912 if (p2 == NULL)
914 result = ASN1_DER_ERROR;
915 goto cleanup;
919 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
921 p2 = _asn1_find_up (p);
922 len2 = _asn1_strtol (p2->value, NULL, 10);
923 if (counter == len2)
925 if (p->right)
927 p2 = p->right;
928 move = RIGHT;
930 else
931 move = UP;
933 if (p->type & CONST_OPTION)
934 asn1_delete_structure (&p);
936 p = p2;
937 continue;
941 if (type_field (p->type) == TYPE_CHOICE)
943 while (p->down)
945 if (counter < len)
946 ris =
947 _asn1_extract_tag_der (p->down, der + counter,
948 len - counter, &len2);
949 else
950 ris = ASN1_DER_ERROR;
951 if (ris == ASN1_SUCCESS)
953 while (p->down->right)
955 p2 = p->down->right;
956 asn1_delete_structure (&p2);
958 break;
960 else if (ris == ASN1_ERROR_TYPE_ANY)
962 result = ASN1_ERROR_TYPE_ANY;
963 goto cleanup;
965 else
967 p2 = p->down;
968 asn1_delete_structure (&p2);
972 if (p->down == NULL)
974 if (!(p->type & CONST_OPTION))
976 result = ASN1_DER_ERROR;
977 goto cleanup;
980 else
981 p = p->down;
984 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
986 p2 = _asn1_find_up (p);
987 len2 = _asn1_strtol (p2->value, NULL, 10);
988 if ((len2 != -1) && (counter > len2))
989 ris = ASN1_TAG_ERROR;
992 if (ris == ASN1_SUCCESS)
993 ris =
994 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
995 if (ris != ASN1_SUCCESS)
997 if (p->type & CONST_OPTION)
999 p->type |= CONST_NOT_USED;
1000 move = RIGHT;
1002 else if (p->type & CONST_DEFAULT)
1004 _asn1_set_value (p, NULL, 0);
1005 move = RIGHT;
1007 else
1009 if (errorDescription != NULL)
1010 _asn1_error_description_tag_error (p, errorDescription);
1012 result = ASN1_TAG_ERROR;
1013 goto cleanup;
1016 else
1017 counter += len2;
1020 if (ris == ASN1_SUCCESS)
1022 switch (type_field (p->type))
1024 case TYPE_NULL:
1025 if (der[counter])
1027 result = ASN1_DER_ERROR;
1028 goto cleanup;
1030 counter++;
1031 move = RIGHT;
1032 break;
1033 case TYPE_BOOLEAN:
1034 if (der[counter++] != 1)
1036 result = ASN1_DER_ERROR;
1037 goto cleanup;
1039 if (der[counter++] == 0)
1040 _asn1_set_value (p, "F", 1);
1041 else
1042 _asn1_set_value (p, "T", 1);
1043 move = RIGHT;
1044 break;
1045 case TYPE_INTEGER:
1046 case TYPE_ENUMERATED:
1047 len2 =
1048 asn1_get_length_der (der + counter, len - counter, &len3);
1049 if (len2 < 0)
1051 result = ASN1_DER_ERROR;
1052 goto cleanup;
1055 _asn1_set_value (p, der + counter, len3 + len2);
1056 counter += len3 + len2;
1057 move = RIGHT;
1058 break;
1059 case TYPE_OBJECT_ID:
1060 result =
1061 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1062 temp, sizeof (temp));
1063 if (result != ASN1_SUCCESS)
1064 goto cleanup;
1066 tlen = strlen (temp);
1067 if (tlen > 0)
1068 _asn1_set_value (p, temp, tlen + 1);
1069 counter += len2;
1070 move = RIGHT;
1071 break;
1072 case TYPE_TIME:
1073 result =
1074 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1075 sizeof (temp) - 1);
1076 if (result != ASN1_SUCCESS)
1077 goto cleanup;
1079 tlen = strlen (temp);
1080 if (tlen > 0)
1081 _asn1_set_value (p, temp, tlen + 1);
1082 counter += len2;
1083 move = RIGHT;
1084 break;
1085 case TYPE_OCTET_STRING:
1086 len3 = len - counter;
1087 result = _asn1_get_octet_string (der + counter, p, &len3);
1088 if (result != ASN1_SUCCESS)
1089 goto cleanup;
1091 counter += len3;
1092 move = RIGHT;
1093 break;
1094 case TYPE_GENERALSTRING:
1095 len2 =
1096 asn1_get_length_der (der + counter, len - counter, &len3);
1097 if (len2 < 0)
1099 result = ASN1_DER_ERROR;
1100 goto cleanup;
1103 _asn1_set_value (p, der + counter, len3 + len2);
1104 counter += len3 + len2;
1105 move = RIGHT;
1106 break;
1107 case TYPE_BIT_STRING:
1108 len2 =
1109 asn1_get_length_der (der + counter, len - counter, &len3);
1110 if (len2 < 0)
1112 result = ASN1_DER_ERROR;
1113 goto cleanup;
1116 _asn1_set_value (p, der + counter, len3 + len2);
1117 counter += len3 + len2;
1118 move = RIGHT;
1119 break;
1120 case TYPE_SEQUENCE:
1121 case TYPE_SET:
1122 if (move == UP)
1124 len2 = _asn1_strtol (p->value, NULL, 10);
1125 _asn1_set_value (p, NULL, 0);
1126 if (len2 == -1)
1127 { /* indefinite length method */
1128 if (len - counter + 1 > 0)
1130 if ((der[counter]) || der[counter + 1])
1132 result = ASN1_DER_ERROR;
1133 goto cleanup;
1136 else
1138 result = ASN1_DER_ERROR;
1139 goto cleanup;
1141 counter += 2;
1143 else
1144 { /* definite length method */
1145 if (len2 != counter)
1147 result = ASN1_DER_ERROR;
1148 goto cleanup;
1151 move = RIGHT;
1153 else
1154 { /* move==DOWN || move==RIGHT */
1155 len3 =
1156 asn1_get_length_der (der + counter, len - counter, &len2);
1157 if (len3 < -1)
1159 result = ASN1_DER_ERROR;
1160 goto cleanup;
1162 counter += len2;
1163 if (len3 > 0)
1165 _asn1_ltostr (counter + len3, temp);
1166 tlen = strlen (temp);
1167 if (tlen > 0)
1168 _asn1_set_value (p, temp, tlen + 1);
1169 move = DOWN;
1171 else if (len3 == 0)
1173 p2 = p->down;
1174 while (p2)
1176 if (type_field (p2->type) != TYPE_TAG)
1178 p3 = p2->right;
1179 asn1_delete_structure (&p2);
1180 p2 = p3;
1182 else
1183 p2 = p2->right;
1185 move = RIGHT;
1187 else
1188 { /* indefinite length method */
1189 _asn1_set_value (p, "-1", 3);
1190 move = DOWN;
1193 break;
1194 case TYPE_SEQUENCE_OF:
1195 case TYPE_SET_OF:
1196 if (move == UP)
1198 len2 = _asn1_strtol (p->value, NULL, 10);
1199 if (len2 == -1)
1200 { /* indefinite length method */
1201 if ((counter + 2) > len)
1203 result = ASN1_DER_ERROR;
1204 goto cleanup;
1207 if ((der[counter]) || der[counter + 1])
1209 _asn1_append_sequence_set (p);
1210 p = p->down;
1211 while (p->right)
1212 p = p->right;
1213 move = RIGHT;
1214 continue;
1216 _asn1_set_value (p, NULL, 0);
1217 counter += 2;
1219 else
1220 { /* definite length method */
1221 if (len2 > counter)
1223 _asn1_append_sequence_set (p);
1224 p = p->down;
1225 while (p->right)
1226 p = p->right;
1227 move = RIGHT;
1228 continue;
1230 _asn1_set_value (p, NULL, 0);
1231 if (len2 != counter)
1233 result = ASN1_DER_ERROR;
1234 goto cleanup;
1238 else
1239 { /* move==DOWN || move==RIGHT */
1240 len3 =
1241 asn1_get_length_der (der + counter, len - counter, &len2);
1242 if (len3 < -1)
1244 result = ASN1_DER_ERROR;
1245 goto cleanup;
1247 counter += len2;
1248 if (len3)
1250 if (len3 > 0)
1251 { /* definite length method */
1252 _asn1_ltostr (counter + len3, temp);
1253 tlen = strlen (temp);
1255 if (tlen > 0)
1256 _asn1_set_value (p, temp, tlen + 1);
1258 else
1259 { /* indefinite length method */
1260 _asn1_set_value (p, "-1", 3);
1262 p2 = p->down;
1263 while ((type_field (p2->type) == TYPE_TAG)
1264 || (type_field (p2->type) == TYPE_SIZE))
1265 p2 = p2->right;
1266 if (p2->right == NULL)
1267 _asn1_append_sequence_set (p);
1268 p = p2;
1271 move = RIGHT;
1272 break;
1273 case TYPE_ANY:
1274 if (asn1_get_tag_der
1275 (der + counter, len - counter, &class, &len2,
1276 &tag) != ASN1_SUCCESS)
1278 result = ASN1_DER_ERROR;
1279 goto cleanup;
1282 if (counter + len2 > len)
1284 result = ASN1_DER_ERROR;
1285 goto cleanup;
1287 len4 =
1288 asn1_get_length_der (der + counter + len2,
1289 len - counter - len2, &len3);
1290 if (len4 < -1)
1292 result = ASN1_DER_ERROR;
1293 goto cleanup;
1295 if (len4 != -1)
1297 len2 += len4;
1298 _asn1_set_value_octet (p, der + counter, len2 + len3);
1299 counter += len2 + len3;
1301 else
1302 { /* indefinite length */
1303 /* Check indefinite lenth method in an EXPLICIT TAG */
1304 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1305 indefinite = 1;
1306 else
1307 indefinite = 0;
1309 len2 = len - counter;
1310 result =
1311 _asn1_get_indefinite_length_string (der + counter, &len2);
1312 if (result != ASN1_SUCCESS)
1313 goto cleanup;
1315 _asn1_set_value_octet (p, der + counter, len2);
1316 counter += len2;
1318 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1319 an indefinite length method. */
1320 if (indefinite)
1322 if (!der[counter] && !der[counter + 1])
1324 counter += 2;
1326 else
1328 result = ASN1_DER_ERROR;
1329 goto cleanup;
1333 move = RIGHT;
1334 break;
1335 default:
1336 move = (move == UP) ? RIGHT : DOWN;
1337 break;
1341 if (p == node && move != DOWN)
1342 break;
1344 if (move == DOWN)
1346 if (p->down)
1347 p = p->down;
1348 else
1349 move = RIGHT;
1351 if ((move == RIGHT) && !(p->type & CONST_SET))
1353 if (p->right)
1354 p = p->right;
1355 else
1356 move = UP;
1358 if (move == UP)
1359 p = _asn1_find_up (p);
1362 _asn1_delete_not_used (*element);
1364 if (counter != len)
1366 result = ASN1_DER_ERROR;
1367 goto cleanup;
1370 return ASN1_SUCCESS;
1372 cleanup:
1373 asn1_delete_structure (element);
1374 return result;
1377 #define FOUND 1
1378 #define SAME_BRANCH 2
1379 #define OTHER_BRANCH 3
1380 #define EXIT 4
1383 * asn1_der_decoding_element:
1384 * @structure: pointer to an ASN1 structure
1385 * @elementName: name of the element to fill
1386 * @ider: vector that contains the DER encoding of the whole structure.
1387 * @len: number of bytes of *der: der[0]..der[len-1]
1388 * @errorDescription: null-terminated string contains details when an
1389 * error occurred.
1391 * Fill the element named @ELEMENTNAME with values of a DER encoding
1392 * string. The structure must just be created with function
1393 * asn1_create_element(). The DER vector must contain the encoding
1394 * string of the whole @STRUCTURE. If an error occurs during the
1395 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1396 * %NULL.
1398 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1399 * if ELEMENT is %NULL or @elementName == NULL, and
1400 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1401 * match the structure @structure (*ELEMENT deleted).
1404 asn1_der_decoding_element (asn1_node * structure, const char *elementName,
1405 const void *ider, int len, char *errorDescription)
1407 asn1_node node, p, p2, p3, nodeFound = NULL;
1408 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1409 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1410 int counter, len2, len3, len4, move, ris, tlen;
1411 unsigned char class;
1412 unsigned long tag;
1413 int indefinite, result;
1414 const unsigned char *der = ider;
1416 node = *structure;
1418 if (node == NULL)
1419 return ASN1_ELEMENT_NOT_FOUND;
1421 if (elementName == NULL)
1423 result = ASN1_ELEMENT_NOT_FOUND;
1424 goto cleanup;
1427 if (node->type & CONST_OPTION)
1429 result = ASN1_GENERIC_ERROR;
1430 goto cleanup;
1433 if ((*structure)->name[0] != 0)
1434 { /* Has *structure got a name? */
1435 nameLen -= strlen ((*structure)->name);
1436 if (nameLen > 0)
1437 strcpy (currentName, (*structure)->name);
1438 else
1440 result = ASN1_MEM_ERROR;
1441 goto cleanup;
1443 if (!(strcmp (currentName, elementName)))
1445 state = FOUND;
1446 nodeFound = *structure;
1448 else if (!memcmp (currentName, elementName, strlen (currentName)))
1449 state = SAME_BRANCH;
1450 else
1451 state = OTHER_BRANCH;
1453 else
1454 { /* *structure doesn't have a name? */
1455 currentName[0] = 0;
1456 if (elementName[0] == 0)
1458 state = FOUND;
1459 nodeFound = *structure;
1461 else
1463 state = SAME_BRANCH;
1467 counter = 0;
1468 move = DOWN;
1469 p = node;
1470 while (1)
1473 ris = ASN1_SUCCESS;
1475 if (move != UP)
1477 if (p->type & CONST_SET)
1479 p2 = _asn1_find_up (p);
1480 len2 = _asn1_strtol (p2->value, NULL, 10);
1481 if (counter == len2)
1483 p = p2;
1484 move = UP;
1485 continue;
1487 else if (counter > len2)
1489 result = ASN1_DER_ERROR;
1490 goto cleanup;
1492 p2 = p2->down;
1493 while (p2)
1495 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1497 if (type_field (p2->type) != TYPE_CHOICE)
1498 ris =
1499 _asn1_extract_tag_der (p2, der + counter,
1500 len - counter, &len2);
1501 else
1503 p3 = p2->down;
1504 while (p3)
1506 ris =
1507 _asn1_extract_tag_der (p3, der + counter,
1508 len - counter, &len2);
1509 if (ris == ASN1_SUCCESS)
1510 break;
1511 p3 = p3->right;
1514 if (ris == ASN1_SUCCESS)
1516 p2->type &= ~CONST_NOT_USED;
1517 p = p2;
1518 break;
1521 p2 = p2->right;
1523 if (p2 == NULL)
1525 result = ASN1_DER_ERROR;
1526 goto cleanup;
1530 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1532 p2 = _asn1_find_up (p);
1533 len2 = _asn1_strtol (p2->value, NULL, 10);
1534 if (counter == len2)
1536 if (p->right)
1538 p2 = p->right;
1539 move = RIGHT;
1541 else
1542 move = UP;
1544 if (p->type & CONST_OPTION)
1545 asn1_delete_structure (&p);
1547 p = p2;
1548 continue;
1552 if (type_field (p->type) == TYPE_CHOICE)
1554 while (p->down)
1556 if (counter < len)
1557 ris =
1558 _asn1_extract_tag_der (p->down, der + counter,
1559 len - counter, &len2);
1560 else
1561 ris = ASN1_DER_ERROR;
1562 if (ris == ASN1_SUCCESS)
1564 while (p->down->right)
1566 p2 = p->down->right;
1567 asn1_delete_structure (&p2);
1569 break;
1571 else if (ris == ASN1_ERROR_TYPE_ANY)
1573 result = ASN1_ERROR_TYPE_ANY;
1574 goto cleanup;
1576 else
1578 p2 = p->down;
1579 asn1_delete_structure (&p2);
1583 if (p->down == NULL)
1585 if (!(p->type & CONST_OPTION))
1587 result = ASN1_DER_ERROR;
1588 goto cleanup;
1591 else
1592 p = p->down;
1595 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1597 p2 = _asn1_find_up (p);
1598 len2 = _asn1_strtol (p2->value, NULL, 10);
1599 if (counter > len2)
1600 ris = ASN1_TAG_ERROR;
1603 if (ris == ASN1_SUCCESS)
1604 ris =
1605 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1606 if (ris != ASN1_SUCCESS)
1608 if (p->type & CONST_OPTION)
1610 p->type |= CONST_NOT_USED;
1611 move = RIGHT;
1613 else if (p->type & CONST_DEFAULT)
1615 _asn1_set_value (p, NULL, 0);
1616 move = RIGHT;
1618 else
1620 if (errorDescription != NULL)
1621 _asn1_error_description_tag_error (p, errorDescription);
1623 result = ASN1_TAG_ERROR;
1624 goto cleanup;
1627 else
1628 counter += len2;
1631 if (ris == ASN1_SUCCESS)
1633 switch (type_field (p->type))
1635 case TYPE_NULL:
1636 if (der[counter])
1638 result = ASN1_DER_ERROR;
1639 goto cleanup;
1642 if (p == nodeFound)
1643 state = EXIT;
1645 counter++;
1646 move = RIGHT;
1647 break;
1648 case TYPE_BOOLEAN:
1649 if (der[counter++] != 1)
1651 result = ASN1_DER_ERROR;
1652 goto cleanup;
1655 if (state == FOUND)
1657 if (der[counter++] == 0)
1658 _asn1_set_value (p, "F", 1);
1659 else
1660 _asn1_set_value (p, "T", 1);
1662 if (p == nodeFound)
1663 state = EXIT;
1666 else
1667 counter++;
1669 move = RIGHT;
1670 break;
1671 case TYPE_INTEGER:
1672 case TYPE_ENUMERATED:
1673 len2 =
1674 asn1_get_length_der (der + counter, len - counter, &len3);
1675 if (len2 < 0)
1677 result = ASN1_DER_ERROR;
1678 goto cleanup;
1681 if (state == FOUND)
1683 if (len3 + len2 > len - counter)
1685 result = ASN1_DER_ERROR;
1686 goto cleanup;
1688 _asn1_set_value (p, der + counter, len3 + len2);
1690 if (p == nodeFound)
1691 state = EXIT;
1693 counter += len3 + len2;
1694 move = RIGHT;
1695 break;
1696 case TYPE_OBJECT_ID:
1697 if (state == FOUND)
1699 result =
1700 _asn1_get_objectid_der (der + counter, len - counter,
1701 &len2, temp, sizeof (temp));
1702 if (result != ASN1_SUCCESS)
1703 goto cleanup;
1705 tlen = strlen (temp);
1707 if (tlen > 0)
1708 _asn1_set_value (p, temp, tlen + 1);
1710 if (p == nodeFound)
1711 state = EXIT;
1713 else
1715 len2 =
1716 asn1_get_length_der (der + counter, len - counter, &len3);
1717 if (len2 < 0)
1719 result = ASN1_DER_ERROR;
1720 goto cleanup;
1722 len2 += len3;
1725 counter += len2;
1726 move = RIGHT;
1727 break;
1728 case TYPE_TIME:
1729 if (state == FOUND)
1731 result =
1732 _asn1_get_time_der (der + counter, len - counter, &len2,
1733 temp, sizeof (temp) - 1);
1734 if (result != ASN1_SUCCESS)
1735 goto cleanup;
1737 tlen = strlen (temp);
1738 if (tlen > 0)
1739 _asn1_set_value (p, temp, tlen + 1);
1741 if (p == nodeFound)
1742 state = EXIT;
1744 else
1746 len2 =
1747 asn1_get_length_der (der + counter, len - counter, &len3);
1748 if (len2 < 0)
1750 result = ASN1_DER_ERROR;
1751 goto cleanup;
1753 len2 += len3;
1756 counter += len2;
1757 move = RIGHT;
1758 break;
1759 case TYPE_OCTET_STRING:
1760 len3 = len - counter;
1761 if (state == FOUND)
1763 result = _asn1_get_octet_string (der + counter, p, &len3);
1764 if (p == nodeFound)
1765 state = EXIT;
1767 else
1768 result = _asn1_get_octet_string (der + counter, NULL, &len3);
1770 if (result != ASN1_SUCCESS)
1771 goto cleanup;
1773 counter += len3;
1774 move = RIGHT;
1775 break;
1776 case TYPE_GENERALSTRING:
1777 len2 =
1778 asn1_get_length_der (der + counter, len - counter, &len3);
1779 if (len2 < 0)
1781 result = ASN1_DER_ERROR;
1782 goto cleanup;
1785 if (state == FOUND)
1787 if (len3 + len2 > len - counter)
1789 result = ASN1_DER_ERROR;
1790 goto cleanup;
1792 _asn1_set_value (p, der + counter, len3 + len2);
1794 if (p == nodeFound)
1795 state = EXIT;
1797 counter += len3 + len2;
1798 move = RIGHT;
1799 break;
1800 case TYPE_BIT_STRING:
1801 len2 =
1802 asn1_get_length_der (der + counter, len - counter, &len3);
1803 if (len2 < 0)
1805 result = ASN1_DER_ERROR;
1806 goto cleanup;
1808 if (state == FOUND)
1810 if (len3 + len2 > len - counter)
1812 result = ASN1_DER_ERROR;
1813 goto cleanup;
1815 _asn1_set_value (p, der + counter, len3 + len2);
1817 if (p == nodeFound)
1818 state = EXIT;
1820 counter += len3 + len2;
1821 move = RIGHT;
1822 break;
1823 case TYPE_SEQUENCE:
1824 case TYPE_SET:
1825 if (move == UP)
1827 len2 = _asn1_strtol (p->value, NULL, 10);
1828 _asn1_set_value (p, NULL, 0);
1829 if (len2 == -1)
1830 { /* indefinite length method */
1831 if ((der[counter]) || der[counter + 1])
1833 result = ASN1_DER_ERROR;
1834 goto cleanup;
1836 counter += 2;
1838 else
1839 { /* definite length method */
1840 if (len2 != counter)
1842 result = ASN1_DER_ERROR;
1843 goto cleanup;
1846 if (p == nodeFound)
1847 state = EXIT;
1848 move = RIGHT;
1850 else
1851 { /* move==DOWN || move==RIGHT */
1852 if (state == OTHER_BRANCH)
1854 len3 =
1855 asn1_get_length_der (der + counter, len - counter,
1856 &len2);
1857 if (len3 < 0)
1859 result = ASN1_DER_ERROR;
1860 goto cleanup;
1862 counter += len2 + len3;
1863 move = RIGHT;
1865 else
1866 { /* state==SAME_BRANCH or state==FOUND */
1867 len3 =
1868 asn1_get_length_der (der + counter, len - counter,
1869 &len2);
1870 if (len3 < 0)
1872 result = ASN1_DER_ERROR;
1873 goto cleanup;
1875 counter += len2;
1876 if (len3 > 0)
1878 _asn1_ltostr (counter + len3, temp);
1879 tlen = strlen (temp);
1881 if (tlen > 0)
1882 _asn1_set_value (p, temp, tlen + 1);
1883 move = DOWN;
1885 else if (len3 == 0)
1887 p2 = p->down;
1888 while (p2)
1890 if (type_field (p2->type) != TYPE_TAG)
1892 p3 = p2->right;
1893 asn1_delete_structure (&p2);
1894 p2 = p3;
1896 else
1897 p2 = p2->right;
1899 move = RIGHT;
1901 else
1902 { /* indefinite length method */
1903 _asn1_set_value (p, "-1", 3);
1904 move = DOWN;
1908 break;
1909 case TYPE_SEQUENCE_OF:
1910 case TYPE_SET_OF:
1911 if (move == UP)
1913 len2 = _asn1_strtol (p->value, NULL, 10);
1914 if (len2 > counter)
1916 _asn1_append_sequence_set (p);
1917 p = p->down;
1918 while (p->right)
1919 p = p->right;
1920 move = RIGHT;
1921 continue;
1923 _asn1_set_value (p, NULL, 0);
1924 if (len2 != counter)
1926 result = ASN1_DER_ERROR;
1927 goto cleanup;
1930 if (p == nodeFound)
1931 state = EXIT;
1933 else
1934 { /* move==DOWN || move==RIGHT */
1935 if (state == OTHER_BRANCH)
1937 len3 =
1938 asn1_get_length_der (der + counter, len - counter,
1939 &len2);
1940 if (len3 < 0)
1942 result = ASN1_DER_ERROR;
1943 goto cleanup;
1945 counter += len2 + len3;
1946 move = RIGHT;
1948 else
1949 { /* state==FOUND or state==SAME_BRANCH */
1950 len3 =
1951 asn1_get_length_der (der + counter, len - counter,
1952 &len2);
1953 if (len3 < 0)
1955 result = ASN1_DER_ERROR;
1956 goto cleanup;
1958 counter += len2;
1959 if (len3)
1961 _asn1_ltostr (counter + len3, temp);
1962 tlen = strlen (temp);
1964 if (tlen > 0)
1965 _asn1_set_value (p, temp, tlen + 1);
1966 p2 = p->down;
1967 while ((type_field (p2->type) == TYPE_TAG)
1968 || (type_field (p2->type) == TYPE_SIZE))
1969 p2 = p2->right;
1970 if (p2->right == NULL)
1971 _asn1_append_sequence_set (p);
1972 p = p2;
1973 state = FOUND;
1978 break;
1979 case TYPE_ANY:
1980 if (asn1_get_tag_der
1981 (der + counter, len - counter, &class, &len2,
1982 &tag) != ASN1_SUCCESS)
1984 result = ASN1_DER_ERROR;
1985 goto cleanup;
1988 if (counter + len2 > len)
1990 result = ASN1_DER_ERROR;
1991 goto cleanup;
1994 len4 =
1995 asn1_get_length_der (der + counter + len2,
1996 len - counter - len2, &len3);
1997 if (len4 < -1)
1999 result = ASN1_DER_ERROR;
2000 goto cleanup;
2003 if (len4 != -1)
2005 len2 += len4;
2006 if (state == FOUND)
2008 _asn1_set_value_octet (p, der + counter, len2 + len3);
2010 if (p == nodeFound)
2011 state = EXIT;
2013 counter += len2 + len3;
2015 else
2016 { /* indefinite length */
2017 /* Check indefinite lenth method in an EXPLICIT TAG */
2018 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2019 indefinite = 1;
2020 else
2021 indefinite = 0;
2023 len2 = len - counter;
2024 result =
2025 _asn1_get_indefinite_length_string (der + counter, &len2);
2026 if (result != ASN1_SUCCESS)
2027 goto cleanup;
2029 if (state == FOUND)
2031 _asn1_set_value_octet (p, der + counter, len2);
2033 if (p == nodeFound)
2034 state = EXIT;
2037 counter += len2;
2039 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2040 an indefinite length method. */
2041 if (indefinite)
2043 if (!der[counter] && !der[counter + 1])
2045 counter += 2;
2047 else
2049 result = ASN1_DER_ERROR;
2050 goto cleanup;
2054 move = RIGHT;
2055 break;
2057 default:
2058 move = (move == UP) ? RIGHT : DOWN;
2059 break;
2063 if ((p == node && move != DOWN) || (state == EXIT))
2064 break;
2066 if (move == DOWN)
2068 if (p->down)
2070 p = p->down;
2072 if (state != FOUND)
2074 nameLen -= strlen (p->name) + 1;
2075 if (nameLen > 0)
2077 if (currentName[0])
2078 strcat (currentName, ".");
2079 strcat (currentName, p->name);
2081 else
2083 result = ASN1_MEM_ERROR;
2084 goto cleanup;
2086 if (!(strcmp (currentName, elementName)))
2088 state = FOUND;
2089 nodeFound = p;
2091 else
2092 if (!memcmp
2093 (currentName, elementName, strlen (currentName)))
2094 state = SAME_BRANCH;
2095 else
2096 state = OTHER_BRANCH;
2099 else
2100 move = RIGHT;
2103 if ((move == RIGHT) && !(p->type & CONST_SET))
2105 if (p->right)
2107 p = p->right;
2109 if (state != FOUND)
2111 dot_p = char_p = currentName;
2112 while ((char_p = strchr (char_p, '.')))
2114 dot_p = char_p++;
2115 dot_p++;
2118 nameLen += strlen (currentName) - (dot_p - currentName);
2119 *dot_p = 0;
2121 nameLen -= strlen (p->name);
2122 if (nameLen > 0)
2123 strcat (currentName, p->name);
2124 else
2126 result = ASN1_MEM_ERROR;
2127 goto cleanup;
2130 if (!(strcmp (currentName, elementName)))
2132 state = FOUND;
2133 nodeFound = p;
2135 else
2136 if (!memcmp
2137 (currentName, elementName, strlen (currentName)))
2138 state = SAME_BRANCH;
2139 else
2140 state = OTHER_BRANCH;
2143 else
2144 move = UP;
2147 if (move == UP)
2149 p = _asn1_find_up (p);
2151 if (state != FOUND)
2153 dot_p = char_p = currentName;
2154 while ((char_p = strchr (char_p, '.')))
2156 dot_p = char_p++;
2157 dot_p++;
2160 nameLen += strlen (currentName) - (dot_p - currentName);
2161 *dot_p = 0;
2163 if (!(strcmp (currentName, elementName)))
2165 state = FOUND;
2166 nodeFound = p;
2168 else
2169 if (!memcmp (currentName, elementName, strlen (currentName)))
2170 state = SAME_BRANCH;
2171 else
2172 state = OTHER_BRANCH;
2177 _asn1_delete_not_used (*structure);
2179 if (counter > len)
2181 result = ASN1_DER_ERROR;
2182 goto cleanup;
2185 return ASN1_SUCCESS;
2187 cleanup:
2188 asn1_delete_structure (structure);
2189 return result;
2193 * asn1_der_decoding_startEnd:
2194 * @element: pointer to an ASN1 element
2195 * @ider: vector that contains the DER encoding.
2196 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2197 * @name_element: an element of NAME structure.
2198 * @start: the position of the first byte of NAME_ELEMENT decoding
2199 * (@ider[*start])
2200 * @end: the position of the last byte of NAME_ELEMENT decoding
2201 * (@ider[*end])
2203 * Find the start and end point of an element in a DER encoding
2204 * string. I mean that if you have a der encoding and you have already
2205 * used the function asn1_der_decoding() to fill a structure, it may
2206 * happen that you want to find the piece of string concerning an
2207 * element of the structure.
2209 * One example is the sequence "tbsCertificate" inside an X509
2210 * certificate.
2212 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2213 * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
2214 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2215 * doesn't match the structure ELEMENT.
2218 asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
2219 const char *name_element, int *start, int *end)
2221 asn1_node node, node_to_find, p, p2, p3;
2222 int counter, len2, len3, len4, move, ris;
2223 unsigned char class;
2224 unsigned long tag;
2225 int indefinite;
2226 const unsigned char *der = ider;
2228 node = element;
2230 if (node == NULL)
2231 return ASN1_ELEMENT_NOT_FOUND;
2233 node_to_find = asn1_find_node (node, name_element);
2235 if (node_to_find == NULL)
2236 return ASN1_ELEMENT_NOT_FOUND;
2238 if (node_to_find == node)
2240 *start = 0;
2241 *end = len - 1;
2242 return ASN1_SUCCESS;
2245 if (node->type & CONST_OPTION)
2246 return ASN1_GENERIC_ERROR;
2248 counter = 0;
2249 move = DOWN;
2250 p = node;
2251 while (1)
2253 if (p == NULL)
2254 return ASN1_DER_ERROR;
2256 ris = ASN1_SUCCESS;
2258 if (move != UP)
2260 if (p->type & CONST_SET)
2262 p2 = _asn1_find_up (p);
2263 if (p2 == NULL)
2264 return ASN1_DER_ERROR;
2266 len2 = _asn1_strtol (p2->value, NULL, 10);
2267 if (len2 == -1)
2269 if (!der[counter] && !der[counter + 1])
2271 p = p2;
2272 move = UP;
2273 counter += 2;
2274 continue;
2277 else if (counter == len2)
2279 p = p2;
2280 move = UP;
2281 continue;
2283 else if (counter > len2)
2284 return ASN1_DER_ERROR;
2286 p2 = p2->down;
2288 while (p2)
2290 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2291 { /* CONTROLLARE */
2292 if (type_field (p2->type) != TYPE_CHOICE)
2293 ris =
2294 _asn1_extract_tag_der (p2, der + counter,
2295 len - counter, &len2);
2296 else
2298 p3 = p2->down;
2299 if (p3 == NULL)
2300 return ASN1_DER_ERROR;
2302 ris =
2303 _asn1_extract_tag_der (p3, der + counter,
2304 len - counter, &len2);
2306 if (ris == ASN1_SUCCESS)
2308 p2->type &= ~CONST_NOT_USED;
2309 p = p2;
2310 break;
2313 p2 = p2->right;
2315 if (p2 == NULL)
2316 return ASN1_DER_ERROR;
2319 if (p == node_to_find)
2320 *start = counter;
2322 if (type_field (p->type) == TYPE_CHOICE)
2324 p = p->down;
2325 if (p == NULL)
2326 return ASN1_DER_ERROR;
2328 ris =
2329 _asn1_extract_tag_der (p, der + counter, len - counter,
2330 &len2);
2331 if (p == node_to_find)
2332 *start = counter;
2335 if (ris == ASN1_SUCCESS)
2336 ris =
2337 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2338 if (ris != ASN1_SUCCESS)
2340 if (p->type & CONST_OPTION)
2342 p->type |= CONST_NOT_USED;
2343 move = RIGHT;
2345 else if (p->type & CONST_DEFAULT)
2347 move = RIGHT;
2349 else
2351 return ASN1_TAG_ERROR;
2354 else
2355 counter += len2;
2358 if (ris == ASN1_SUCCESS)
2360 switch (type_field (p->type))
2362 case TYPE_NULL:
2363 if (der[counter])
2364 return ASN1_DER_ERROR;
2365 counter++;
2366 move = RIGHT;
2367 break;
2368 case TYPE_BOOLEAN:
2369 if (der[counter++] != 1)
2370 return ASN1_DER_ERROR;
2371 counter++;
2372 move = RIGHT;
2373 break;
2374 case TYPE_INTEGER:
2375 case TYPE_ENUMERATED:
2376 len2 =
2377 asn1_get_length_der (der + counter, len - counter, &len3);
2378 if (len2 < 0)
2379 return ASN1_DER_ERROR;
2380 counter += len3 + len2;
2381 move = RIGHT;
2382 break;
2383 case TYPE_OBJECT_ID:
2384 len2 =
2385 asn1_get_length_der (der + counter, len - counter, &len3);
2386 if (len2 < 0)
2387 return ASN1_DER_ERROR;
2388 counter += len2 + len3;
2389 move = RIGHT;
2390 break;
2391 case TYPE_TIME:
2392 len2 =
2393 asn1_get_length_der (der + counter, len - counter, &len3);
2394 if (len2 < 0)
2395 return ASN1_DER_ERROR;
2396 counter += len2 + len3;
2397 move = RIGHT;
2398 break;
2399 case TYPE_OCTET_STRING:
2400 len3 = len - counter;
2401 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2402 if (ris != ASN1_SUCCESS)
2403 return ris;
2404 counter += len3;
2405 move = RIGHT;
2406 break;
2407 case TYPE_GENERALSTRING:
2408 len2 =
2409 asn1_get_length_der (der + counter, len - counter, &len3);
2410 if (len2 < 0)
2411 return ASN1_DER_ERROR;
2412 counter += len3 + len2;
2413 move = RIGHT;
2414 break;
2415 case TYPE_BIT_STRING:
2416 len2 =
2417 asn1_get_length_der (der + counter, len - counter, &len3);
2418 if (len2 < 0)
2419 return ASN1_DER_ERROR;
2420 counter += len3 + len2;
2421 move = RIGHT;
2422 break;
2423 case TYPE_SEQUENCE:
2424 case TYPE_SET:
2425 if (move != UP)
2427 len3 =
2428 asn1_get_length_der (der + counter, len - counter, &len2);
2429 if (len3 < -1)
2430 return ASN1_DER_ERROR;
2431 counter += len2;
2432 if (len3 == 0)
2433 move = RIGHT;
2434 else
2435 move = DOWN;
2437 else
2439 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2440 counter += 2;
2441 move = RIGHT;
2443 break;
2444 case TYPE_SEQUENCE_OF:
2445 case TYPE_SET_OF:
2446 if (move != UP)
2448 len3 =
2449 asn1_get_length_der (der + counter, len - counter, &len2);
2450 if (len3 < -1)
2451 return ASN1_DER_ERROR;
2452 counter += len2;
2453 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2454 counter += 2;
2455 else if (len3)
2457 p2 = p->down;
2458 while ((type_field (p2->type) == TYPE_TAG) ||
2459 (type_field (p2->type) == TYPE_SIZE))
2460 p2 = p2->right;
2461 p = p2;
2464 else
2466 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2467 counter += 2;
2469 move = RIGHT;
2470 break;
2471 case TYPE_ANY:
2472 if (asn1_get_tag_der
2473 (der + counter, len - counter, &class, &len2,
2474 &tag) != ASN1_SUCCESS)
2475 return ASN1_DER_ERROR;
2476 if (counter + len2 > len)
2477 return ASN1_DER_ERROR;
2479 len4 =
2480 asn1_get_length_der (der + counter + len2,
2481 len - counter - len2, &len3);
2482 if (len4 < -1)
2483 return ASN1_DER_ERROR;
2485 if (len4 != -1)
2487 counter += len2 + len4 + len3;
2489 else
2490 { /* indefinite length */
2491 /* Check indefinite lenth method in an EXPLICIT TAG */
2492 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2493 indefinite = 1;
2494 else
2495 indefinite = 0;
2497 len2 = len - counter;
2498 ris =
2499 _asn1_get_indefinite_length_string (der + counter, &len2);
2500 if (ris != ASN1_SUCCESS)
2501 return ris;
2502 counter += len2;
2504 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2505 an indefinite length method. */
2506 if (indefinite)
2508 if (!der[counter] && !der[counter + 1])
2509 counter += 2;
2510 else
2511 return ASN1_DER_ERROR;
2514 move = RIGHT;
2515 break;
2516 default:
2517 move = (move == UP) ? RIGHT : DOWN;
2518 break;
2522 if ((p == node_to_find) && (move == RIGHT))
2524 *end = counter - 1;
2525 return ASN1_SUCCESS;
2528 if (p == node && move != DOWN)
2529 break;
2531 if (move == DOWN)
2533 if (p->down)
2534 p = p->down;
2535 else
2536 move = RIGHT;
2538 if ((move == RIGHT) && !(p->type & CONST_SET))
2540 if (p->right)
2541 p = p->right;
2542 else
2543 move = UP;
2545 if (move == UP)
2546 p = _asn1_find_up (p);
2549 return ASN1_ELEMENT_NOT_FOUND;
2553 * asn1_expand_any_defined_by:
2554 * @definitions: ASN1 definitions
2555 * @element: pointer to an ASN1 structure
2557 * Expands every "ANY DEFINED BY" element of a structure created from
2558 * a DER decoding process (asn1_der_decoding function). The element
2559 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2560 * expand the element ANY is the first one following the definition of
2561 * the actual value of the OBJECT IDENTIFIER.
2563 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2564 * some "ANY DEFINED BY" element couldn't be expanded due to a
2565 * problem in OBJECT_ID -> TYPE association, or other error codes
2566 * depending on DER decoding.
2569 asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
2571 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2572 value[ASN1_MAX_NAME_SIZE];
2573 int retCode = ASN1_SUCCESS, result;
2574 int len, len2, len3;
2575 asn1_node p, p2, p3, aux = NULL;
2576 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2578 if ((definitions == NULL) || (*element == NULL))
2579 return ASN1_ELEMENT_NOT_FOUND;
2581 strcpy (definitionsName, definitions->name);
2582 strcat (definitionsName, ".");
2584 p = *element;
2585 while (p)
2588 switch (type_field (p->type))
2590 case TYPE_ANY:
2591 if ((p->type & CONST_DEFINED_BY) && (p->value))
2593 /* search the "DEF_BY" element */
2594 p2 = p->down;
2595 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2596 p2 = p2->right;
2598 if (!p2)
2600 retCode = ASN1_ERROR_TYPE_ANY;
2601 break;
2604 p3 = _asn1_find_up (p);
2606 if (!p3)
2608 retCode = ASN1_ERROR_TYPE_ANY;
2609 break;
2612 p3 = p3->down;
2613 while (p3)
2615 if (!(strcmp (p3->name, p2->name)))
2616 break;
2617 p3 = p3->right;
2620 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2621 (p3->value == NULL))
2624 p3 = _asn1_find_up (p);
2625 p3 = _asn1_find_up (p3);
2627 if (!p3)
2629 retCode = ASN1_ERROR_TYPE_ANY;
2630 break;
2633 p3 = p3->down;
2635 while (p3)
2637 if (!(strcmp (p3->name, p2->name)))
2638 break;
2639 p3 = p3->right;
2642 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2643 (p3->value == NULL))
2645 retCode = ASN1_ERROR_TYPE_ANY;
2646 break;
2650 /* search the OBJECT_ID into definitions */
2651 p2 = definitions->down;
2652 while (p2)
2654 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2655 (p2->type & CONST_ASSIGN))
2657 strcpy (name, definitionsName);
2658 strcat (name, p2->name);
2660 len = ASN1_MAX_NAME_SIZE;
2661 result =
2662 asn1_read_value (definitions, name, value, &len);
2664 if ((result == ASN1_SUCCESS)
2665 && (!_asn1_strcmp (p3->value, value)))
2667 p2 = p2->right; /* pointer to the structure to
2668 use for expansion */
2669 while ((p2) && (p2->type & CONST_ASSIGN))
2670 p2 = p2->right;
2672 if (p2)
2674 strcpy (name, definitionsName);
2675 strcat (name, p2->name);
2677 result =
2678 asn1_create_element (definitions, name, &aux);
2679 if (result == ASN1_SUCCESS)
2681 _asn1_cpy_name (aux, p);
2682 len2 =
2683 asn1_get_length_der (p->value,
2684 p->value_len, &len3);
2685 if (len2 < 0)
2686 return ASN1_DER_ERROR;
2688 result =
2689 asn1_der_decoding (&aux, p->value + len3,
2690 len2,
2691 errorDescription);
2692 if (result == ASN1_SUCCESS)
2695 _asn1_set_right (aux, p->right);
2696 _asn1_set_right (p, aux);
2698 result = asn1_delete_structure (&p);
2699 if (result == ASN1_SUCCESS)
2701 p = aux;
2702 aux = NULL;
2703 break;
2705 else
2706 { /* error with asn1_delete_structure */
2707 asn1_delete_structure (&aux);
2708 retCode = result;
2709 break;
2712 else
2713 { /* error with asn1_der_decoding */
2714 retCode = result;
2715 break;
2718 else
2719 { /* error with asn1_create_element */
2720 retCode = result;
2721 break;
2724 else
2725 { /* error with the pointer to the structure to exapand */
2726 retCode = ASN1_ERROR_TYPE_ANY;
2727 break;
2731 p2 = p2->right;
2732 } /* end while */
2734 if (!p2)
2736 retCode = ASN1_ERROR_TYPE_ANY;
2737 break;
2741 break;
2742 default:
2743 break;
2747 if (p->down)
2749 p = p->down;
2751 else if (p == *element)
2753 p = NULL;
2754 break;
2756 else if (p->right)
2757 p = p->right;
2758 else
2760 while (1)
2762 p = _asn1_find_up (p);
2763 if (p == *element)
2765 p = NULL;
2766 break;
2768 if (p->right)
2770 p = p->right;
2771 break;
2777 return retCode;
2781 * asn1_expand_octet_string:
2782 * @definitions: ASN1 definitions
2783 * @element: pointer to an ASN1 structure
2784 * @octetName: name of the OCTECT STRING field to expand.
2785 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2786 * the type for expansion.
2788 * Expands an "OCTET STRING" element of a structure created from a DER
2789 * decoding process (the asn1_der_decoding() function). The type used
2790 * for expansion is the first one following the definition of the
2791 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2793 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2794 * if @objectName or @octetName are not correct,
2795 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2796 * use for expansion, or other errors depending on DER decoding.
2799 asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
2800 const char *octetName, const char *objectName)
2802 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2803 int retCode = ASN1_SUCCESS, result;
2804 int len, len2, len3;
2805 asn1_node p2, aux = NULL;
2806 asn1_node octetNode = NULL, objectNode = NULL;
2807 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2809 if ((definitions == NULL) || (*element == NULL))
2810 return ASN1_ELEMENT_NOT_FOUND;
2812 octetNode = asn1_find_node (*element, octetName);
2813 if (octetNode == NULL)
2814 return ASN1_ELEMENT_NOT_FOUND;
2815 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2816 return ASN1_ELEMENT_NOT_FOUND;
2817 if (octetNode->value == NULL)
2818 return ASN1_VALUE_NOT_FOUND;
2820 objectNode = asn1_find_node (*element, objectName);
2821 if (objectNode == NULL)
2822 return ASN1_ELEMENT_NOT_FOUND;
2824 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2825 return ASN1_ELEMENT_NOT_FOUND;
2827 if (objectNode->value == NULL)
2828 return ASN1_VALUE_NOT_FOUND;
2831 /* search the OBJECT_ID into definitions */
2832 p2 = definitions->down;
2833 while (p2)
2835 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2836 (p2->type & CONST_ASSIGN))
2838 strcpy (name, definitions->name);
2839 strcat (name, ".");
2840 strcat (name, p2->name);
2842 len = sizeof (value);
2843 result = asn1_read_value (definitions, name, value, &len);
2845 if ((result == ASN1_SUCCESS)
2846 && (!_asn1_strcmp (objectNode->value, value)))
2849 p2 = p2->right; /* pointer to the structure to
2850 use for expansion */
2851 while ((p2) && (p2->type & CONST_ASSIGN))
2852 p2 = p2->right;
2854 if (p2)
2856 strcpy (name, definitions->name);
2857 strcat (name, ".");
2858 strcat (name, p2->name);
2860 result = asn1_create_element (definitions, name, &aux);
2861 if (result == ASN1_SUCCESS)
2863 _asn1_cpy_name (aux, octetNode);
2864 len2 =
2865 asn1_get_length_der (octetNode->value,
2866 octetNode->value_len, &len3);
2867 if (len2 < 0)
2868 return ASN1_DER_ERROR;
2870 result =
2871 asn1_der_decoding (&aux, octetNode->value + len3,
2872 len2, errorDescription);
2873 if (result == ASN1_SUCCESS)
2876 _asn1_set_right (aux, octetNode->right);
2877 _asn1_set_right (octetNode, aux);
2879 result = asn1_delete_structure (&octetNode);
2880 if (result == ASN1_SUCCESS)
2882 aux = NULL;
2883 break;
2885 else
2886 { /* error with asn1_delete_structure */
2887 asn1_delete_structure (&aux);
2888 retCode = result;
2889 break;
2892 else
2893 { /* error with asn1_der_decoding */
2894 retCode = result;
2895 break;
2898 else
2899 { /* error with asn1_create_element */
2900 retCode = result;
2901 break;
2904 else
2905 { /* error with the pointer to the structure to exapand */
2906 retCode = ASN1_VALUE_NOT_VALID;
2907 break;
2912 p2 = p2->right;
2916 if (!p2)
2917 retCode = ASN1_VALUE_NOT_VALID;
2919 return retCode;