updated libtasn1
[gnutls.git] / lib / minitasn1 / decoding.c
blob1cfad3556b38367f35aa3db7a2ebfa00bcda6083
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 asn1_retCode
36 _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
38 static void
39 _asn1_error_description_tag_error (ASN1_TYPE 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 signed long
62 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
64 unsigned int ans, sum, last;
65 unsigned 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 (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 punt, ris;
134 unsigned int last;
136 if (der == NULL || der_len < 2 || len == NULL)
137 return ASN1_DER_ERROR;
139 *cls = der[0] & 0xE0;
140 if ((der[0] & 0x1F) != 0x1F)
142 /* short form */
143 *len = 1;
144 ris = der[0] & 0x1F;
146 else
148 /* Long form */
149 punt = 1;
150 ris = 0;
151 while (punt <= der_len && der[punt] & 128)
153 last = ris;
155 ris = (ris * 128) + (der[punt++] & 0x7F);
156 if (ris < last)
157 /* wrapped around, and no bignums... */
158 return ASN1_DER_ERROR;
161 if (punt >= der_len)
162 return ASN1_DER_ERROR;
164 last = ris;
166 ris = (ris * 128) + (der[punt++] & 0x7F);
167 if (ris < last)
168 return ASN1_DER_ERROR;
170 *len = punt;
172 if (tag)
173 *tag = ris;
174 return ASN1_SUCCESS;
178 * asn1_get_length_ber:
179 * @ber: BER data to decode.
180 * @ber_len: Length of BER data to decode.
181 * @len: Output variable containing the length of the BER length field.
183 * Extract a length field from BER data. The difference to
184 * asn1_get_length_der() is that this function will return a length
185 * even if the value has indefinite encoding.
187 * Returns: Return the decoded length value, or negative value when
188 * the value was too big.
190 * Since: 2.0
192 signed long
193 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
195 int ret;
196 long err;
198 ret = asn1_get_length_der (ber, ber_len, len);
199 if (ret == -1)
200 { /* indefinite length method */
201 ret = ber_len;
202 err = _asn1_get_indefinite_length_string (ber + 1, &ret);
203 if (err != ASN1_SUCCESS)
204 return -3;
207 return ret;
211 * asn1_get_octet_der:
212 * @der: DER data to decode containing the OCTET SEQUENCE.
213 * @der_len: Length of DER data to decode.
214 * @ret_len: Output variable containing the length of the DER data.
215 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
216 * @str_size: Length of pre-allocated output buffer.
217 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
219 * Extract an OCTET SEQUENCE from DER data.
221 * Returns: Returns %ASN1_SUCCESS on success, or an error.
224 asn1_get_octet_der (const unsigned char *der, int der_len,
225 int *ret_len, unsigned char *str, int str_size,
226 int *str_len)
228 int len_len;
230 if (der_len <= 0)
231 return ASN1_GENERIC_ERROR;
233 /* if(str==NULL) return ASN1_SUCCESS; */
234 *str_len = asn1_get_length_der (der, der_len, &len_len);
236 if (*str_len < 0)
237 return ASN1_DER_ERROR;
239 *ret_len = *str_len + len_len;
240 if (str_size >= *str_len)
241 memcpy (str, der + len_len, *str_len);
242 else
244 return ASN1_MEM_ERROR;
247 return ASN1_SUCCESS;
250 /* Returns ASN1_SUCCESS on success or an error code on error.
252 static int
253 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
254 char *str, int str_size)
256 int len_len, str_len;
258 if (der_len <= 0 || str == NULL)
259 return ASN1_DER_ERROR;
260 str_len = asn1_get_length_der (der, der_len, &len_len);
261 if (str_len < 0 || str_size < str_len)
262 return ASN1_DER_ERROR;
263 memcpy (str, der + len_len, str_len);
264 str[str_len] = 0;
265 *ret_len = str_len + len_len;
267 return ASN1_SUCCESS;
270 static int
271 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
272 char *str, int str_size)
274 int len_len, len, k;
275 int leading;
276 char temp[20];
277 unsigned long val, val1, prev_val;
279 *ret_len = 0;
280 if (str && str_size > 0)
281 str[0] = 0; /* no oid */
283 if (str == NULL || der_len <= 0)
284 return ASN1_GENERIC_ERROR;
285 len = asn1_get_length_der (der, der_len, &len_len);
287 if (len < 0 || len > der_len || len_len > der_len)
288 return ASN1_DER_ERROR;
290 val1 = der[len_len] / 40;
291 val = der[len_len] - val1 * 40;
293 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
294 _asn1_str_cat (str, str_size, ".");
295 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
297 prev_val = 0;
298 val = 0;
299 leading = 1;
300 for (k = 1; k < len; k++)
302 /* X.690 mandates that the leading byte must never be 0x80
304 if (leading != 0 && der[len_len + k] == 0x80)
305 return ASN1_DER_ERROR;
306 leading = 0;
308 /* check for wrap around */
309 val = val << 7;
310 val |= der[len_len + k] & 0x7F;
312 if (val < prev_val)
313 return ASN1_DER_ERROR;
315 prev_val = val;
317 if (!(der[len_len + k] & 0x80))
319 _asn1_str_cat (str, str_size, ".");
320 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
321 val = 0;
322 prev_val = 0;
323 leading = 1;
326 *ret_len = len + len_len;
328 return ASN1_SUCCESS;
332 * asn1_get_bit_der:
333 * @der: DER data to decode containing the BIT SEQUENCE.
334 * @der_len: Length of DER data to decode.
335 * @ret_len: Output variable containing the length of the DER data.
336 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
337 * @str_size: Length of pre-allocated output buffer.
338 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
340 * Extract a BIT SEQUENCE from DER data.
342 * Returns: Return %ASN1_SUCCESS on success, or an error.
345 asn1_get_bit_der (const unsigned char *der, int der_len,
346 int *ret_len, unsigned char *str, int str_size,
347 int *bit_len)
349 int len_len, len_byte;
351 if (der_len <= 0)
352 return ASN1_GENERIC_ERROR;
353 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
354 if (len_byte < 0)
355 return ASN1_DER_ERROR;
357 *ret_len = len_byte + len_len + 1;
358 *bit_len = len_byte * 8 - der[len_len];
360 if (str_size >= len_byte)
361 memcpy (str, der + len_len + 1, len_byte);
362 else
364 return ASN1_MEM_ERROR;
367 return ASN1_SUCCESS;
370 static int
371 _asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
372 int *ret_len)
374 ASN1_TYPE p;
375 int counter, len2, len3, is_tag_implicit;
376 unsigned long tag, tag_implicit = 0;
377 unsigned char class, class2, class_implicit = 0;
379 if (der_len <= 0)
380 return ASN1_GENERIC_ERROR;
382 counter = is_tag_implicit = 0;
384 if (node->type & CONST_TAG)
386 p = node->down;
387 while (p)
389 if (type_field (p->type) == TYPE_TAG)
391 if (p->type & CONST_APPLICATION)
392 class2 = ASN1_CLASS_APPLICATION;
393 else if (p->type & CONST_UNIVERSAL)
394 class2 = ASN1_CLASS_UNIVERSAL;
395 else if (p->type & CONST_PRIVATE)
396 class2 = ASN1_CLASS_PRIVATE;
397 else
398 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
400 if (p->type & CONST_EXPLICIT)
402 if (asn1_get_tag_der
403 (der + counter, der_len - counter, &class, &len2,
404 &tag) != ASN1_SUCCESS)
405 return ASN1_DER_ERROR;
407 if (counter + len2 > der_len)
408 return ASN1_DER_ERROR;
409 counter += len2;
411 len3 =
412 asn1_get_length_ber (der + counter, der_len - counter,
413 &len2);
414 if (len3 < 0)
415 return ASN1_DER_ERROR;
417 counter += len2;
418 if (counter > der_len)
419 return ASN1_DER_ERROR;
421 if (!is_tag_implicit)
423 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
424 (tag != strtoul ((char *) p->value, NULL, 10)))
425 return ASN1_TAG_ERROR;
427 else
428 { /* ASN1_TAG_IMPLICIT */
429 if ((class != class_implicit) || (tag != tag_implicit))
430 return ASN1_TAG_ERROR;
432 is_tag_implicit = 0;
434 else
435 { /* ASN1_TAG_IMPLICIT */
436 if (!is_tag_implicit)
438 if ((type_field (node->type) == TYPE_SEQUENCE) ||
439 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
440 (type_field (node->type) == TYPE_SET) ||
441 (type_field (node->type) == TYPE_SET_OF))
442 class2 |= ASN1_CLASS_STRUCTURED;
443 class_implicit = class2;
444 tag_implicit = strtoul ((char *) p->value, NULL, 10);
445 is_tag_implicit = 1;
449 p = p->right;
453 if (is_tag_implicit)
455 if (asn1_get_tag_der
456 (der + counter, der_len - counter, &class, &len2,
457 &tag) != ASN1_SUCCESS)
458 return ASN1_DER_ERROR;
459 if (counter + len2 > der_len)
460 return ASN1_DER_ERROR;
462 if ((class != class_implicit) || (tag != tag_implicit))
464 if (type_field (node->type) == TYPE_OCTET_STRING)
466 class_implicit |= ASN1_CLASS_STRUCTURED;
467 if ((class != class_implicit) || (tag != tag_implicit))
468 return ASN1_TAG_ERROR;
470 else
471 return ASN1_TAG_ERROR;
474 else
476 if (type_field (node->type) == TYPE_TAG)
478 counter = 0;
479 *ret_len = counter;
480 return ASN1_SUCCESS;
483 if (asn1_get_tag_der
484 (der + counter, der_len - counter, &class, &len2,
485 &tag) != ASN1_SUCCESS)
486 return ASN1_DER_ERROR;
488 if (counter + len2 > der_len)
489 return ASN1_DER_ERROR;
491 switch (type_field (node->type))
493 case TYPE_NULL:
494 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
495 return ASN1_DER_ERROR;
496 break;
497 case TYPE_BOOLEAN:
498 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
499 return ASN1_DER_ERROR;
500 break;
501 case TYPE_INTEGER:
502 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
503 return ASN1_DER_ERROR;
504 break;
505 case TYPE_ENUMERATED:
506 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
507 return ASN1_DER_ERROR;
508 break;
509 case TYPE_OBJECT_ID:
510 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
511 return ASN1_DER_ERROR;
512 break;
513 case TYPE_TIME:
514 if (node->type & CONST_UTC)
516 if ((class != ASN1_CLASS_UNIVERSAL)
517 || (tag != ASN1_TAG_UTCTime))
518 return ASN1_DER_ERROR;
520 else
522 if ((class != ASN1_CLASS_UNIVERSAL)
523 || (tag != ASN1_TAG_GENERALIZEDTime))
524 return ASN1_DER_ERROR;
526 break;
527 case TYPE_OCTET_STRING:
528 if (((class != ASN1_CLASS_UNIVERSAL)
529 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
530 || (tag != ASN1_TAG_OCTET_STRING))
531 return ASN1_DER_ERROR;
532 break;
533 case TYPE_GENERALSTRING:
534 if ((class != ASN1_CLASS_UNIVERSAL)
535 || (tag != ASN1_TAG_GENERALSTRING))
536 return ASN1_DER_ERROR;
537 break;
538 case TYPE_BIT_STRING:
539 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
540 return ASN1_DER_ERROR;
541 break;
542 case TYPE_SEQUENCE:
543 case TYPE_SEQUENCE_OF:
544 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
545 || (tag != ASN1_TAG_SEQUENCE))
546 return ASN1_DER_ERROR;
547 break;
548 case TYPE_SET:
549 case TYPE_SET_OF:
550 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
551 || (tag != ASN1_TAG_SET))
552 return ASN1_DER_ERROR;
553 break;
554 case TYPE_ANY:
555 counter -= len2;
556 break;
557 default:
558 return ASN1_DER_ERROR;
559 break;
563 counter += len2;
564 *ret_len = counter;
565 return ASN1_SUCCESS;
568 static int
569 _asn1_delete_not_used (ASN1_TYPE node)
571 ASN1_TYPE p, p2;
573 if (node == NULL)
574 return ASN1_ELEMENT_NOT_FOUND;
576 p = node;
577 while (p)
579 if (p->type & CONST_NOT_USED)
581 p2 = NULL;
582 if (p != node)
584 p2 = _asn1_find_left (p);
585 if (!p2)
586 p2 = _asn1_find_up (p);
588 asn1_delete_structure (&p);
589 p = p2;
592 if (!p)
593 break; /* reach node */
595 if (p->down)
597 p = p->down;
599 else
601 if (p == node)
602 p = NULL;
603 else if (p->right)
604 p = p->right;
605 else
607 while (1)
609 p = _asn1_find_up (p);
610 if (p == node)
612 p = NULL;
613 break;
615 if (p->right)
617 p = p->right;
618 break;
624 return ASN1_SUCCESS;
627 static asn1_retCode
628 _asn1_extract_der_octet (ASN1_TYPE node, const unsigned char *der,
629 int der_len)
631 int len2, len3;
632 int counter2, counter_end;
634 len2 = asn1_get_length_der (der, der_len, &len3);
635 if (len2 < -1)
636 return ASN1_DER_ERROR;
638 counter2 = len3 + 1;
640 if (len2 == -1)
641 counter_end = der_len - 2;
642 else
643 counter_end = der_len;
645 while (counter2 < counter_end)
647 len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
649 if (len2 < -1)
650 return ASN1_DER_ERROR;
652 if (len2 > 0)
654 _asn1_append_value (node, der + counter2 + len3, len2);
656 else
657 { /* indefinite */
659 len2 =
660 _asn1_extract_der_octet (node, der + counter2 + len3,
661 der_len - counter2 - len3);
662 if (len2 < 0)
663 return len2;
666 counter2 += len2 + len3 + 1;
669 return ASN1_SUCCESS;
672 static asn1_retCode
673 _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
675 int len2, len3, counter, tot_len, indefinite;
677 counter = 0;
679 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
681 tot_len = 0;
682 indefinite = asn1_get_length_der (der, *len, &len3);
683 if (indefinite < -1)
684 return ASN1_DER_ERROR;
686 counter += len3;
687 if (indefinite >= 0)
688 indefinite += len3;
690 while (1)
692 if (counter > (*len))
693 return ASN1_DER_ERROR;
695 if (indefinite == -1)
697 if ((der[counter] == 0) && (der[counter + 1] == 0))
699 counter += 2;
700 break;
703 else if (counter >= indefinite)
704 break;
706 if (der[counter] != ASN1_TAG_OCTET_STRING)
707 return ASN1_DER_ERROR;
709 counter++;
711 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
712 if (len2 <= 0)
713 return ASN1_DER_ERROR;
715 counter += len3 + len2;
716 tot_len += len2;
719 /* copy */
720 if (node)
722 unsigned char temp[DER_LEN];
723 int ret;
725 len2 = sizeof (temp);
727 asn1_length_der (tot_len, temp, &len2);
728 _asn1_set_value (node, temp, len2);
730 tot_len += len2;
732 ret = _asn1_extract_der_octet (node, der, *len);
733 if (ret != ASN1_SUCCESS)
734 return ret;
738 else
739 { /* NOT STRUCTURED */
740 len2 = asn1_get_length_der (der, *len, &len3);
741 if (len2 < 0)
742 return ASN1_DER_ERROR;
743 if (node)
744 _asn1_set_value (node, der, len3 + len2);
745 counter = len3 + len2;
748 *len = counter;
749 return ASN1_SUCCESS;
753 static asn1_retCode
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 * %ASN1_TYPE_EMPTY.
817 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
818 * if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
819 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
820 * name (*@ELEMENT deleted).
822 asn1_retCode
823 asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
824 char *errorDescription)
826 ASN1_TYPE 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 (node == ASN1_TYPE_EMPTY)
837 return ASN1_ELEMENT_NOT_FOUND;
839 if (node->type & CONST_OPTION)
841 result = ASN1_GENERIC_ERROR;
842 goto cleanup;
845 counter = 0;
846 move = DOWN;
847 p = node;
848 while (1)
850 ris = ASN1_SUCCESS;
851 if (move != UP)
853 if (p->type & CONST_SET)
855 p2 = _asn1_find_up (p);
856 len2 = _asn1_strtol (p2->value, NULL, 10);
857 if (len2 == -1)
859 if (!der[counter] && !der[counter + 1])
861 p = p2;
862 move = UP;
863 counter += 2;
864 continue;
867 else if (counter == len2)
869 p = p2;
870 move = UP;
871 continue;
873 else if (counter > len2)
875 result = ASN1_DER_ERROR;
876 goto cleanup;
878 p2 = p2->down;
879 while (p2)
881 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
883 if (type_field (p2->type) != TYPE_CHOICE)
884 ris =
885 _asn1_extract_tag_der (p2, der + counter,
886 len - counter, &len2);
887 else
889 p3 = p2->down;
890 while (p3)
892 ris =
893 _asn1_extract_tag_der (p3, der + counter,
894 len - counter, &len2);
895 if (ris == ASN1_SUCCESS)
896 break;
897 p3 = p3->right;
900 if (ris == ASN1_SUCCESS)
902 p2->type &= ~CONST_NOT_USED;
903 p = p2;
904 break;
907 p2 = p2->right;
909 if (p2 == NULL)
911 result = ASN1_DER_ERROR;
912 goto cleanup;
916 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
918 p2 = _asn1_find_up (p);
919 len2 = _asn1_strtol (p2->value, NULL, 10);
920 if (counter == len2)
922 if (p->right)
924 p2 = p->right;
925 move = RIGHT;
927 else
928 move = UP;
930 if (p->type & CONST_OPTION)
931 asn1_delete_structure (&p);
933 p = p2;
934 continue;
938 if (type_field (p->type) == TYPE_CHOICE)
940 while (p->down)
942 if (counter < len)
943 ris =
944 _asn1_extract_tag_der (p->down, der + counter,
945 len - counter, &len2);
946 else
947 ris = ASN1_DER_ERROR;
948 if (ris == ASN1_SUCCESS)
950 while (p->down->right)
952 p2 = p->down->right;
953 asn1_delete_structure (&p2);
955 break;
957 else if (ris == ASN1_ERROR_TYPE_ANY)
959 result = ASN1_ERROR_TYPE_ANY;
960 goto cleanup;
962 else
964 p2 = p->down;
965 asn1_delete_structure (&p2);
969 if (p->down == NULL)
971 if (!(p->type & CONST_OPTION))
973 result = ASN1_DER_ERROR;
974 goto cleanup;
977 else
978 p = p->down;
981 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
983 p2 = _asn1_find_up (p);
984 len2 = _asn1_strtol (p2->value, NULL, 10);
985 if ((len2 != -1) && (counter > len2))
986 ris = ASN1_TAG_ERROR;
989 if (ris == ASN1_SUCCESS)
990 ris =
991 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
992 if (ris != ASN1_SUCCESS)
994 if (p->type & CONST_OPTION)
996 p->type |= CONST_NOT_USED;
997 move = RIGHT;
999 else if (p->type & CONST_DEFAULT)
1001 _asn1_set_value (p, NULL, 0);
1002 move = RIGHT;
1004 else
1006 if (errorDescription != NULL)
1007 _asn1_error_description_tag_error (p, errorDescription);
1009 result = ASN1_TAG_ERROR;
1010 goto cleanup;
1013 else
1014 counter += len2;
1017 if (ris == ASN1_SUCCESS)
1019 switch (type_field (p->type))
1021 case TYPE_NULL:
1022 if (der[counter])
1024 result = ASN1_DER_ERROR;
1025 goto cleanup;
1027 counter++;
1028 move = RIGHT;
1029 break;
1030 case TYPE_BOOLEAN:
1031 if (der[counter++] != 1)
1033 result = ASN1_DER_ERROR;
1034 goto cleanup;
1036 if (der[counter++] == 0)
1037 _asn1_set_value (p, "F", 1);
1038 else
1039 _asn1_set_value (p, "T", 1);
1040 move = RIGHT;
1041 break;
1042 case TYPE_INTEGER:
1043 case TYPE_ENUMERATED:
1044 len2 =
1045 asn1_get_length_der (der + counter, len - counter, &len3);
1046 if (len2 < 0)
1048 result = ASN1_DER_ERROR;
1049 goto cleanup;
1052 _asn1_set_value (p, der + counter, len3 + len2);
1053 counter += len3 + len2;
1054 move = RIGHT;
1055 break;
1056 case TYPE_OBJECT_ID:
1057 result =
1058 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1059 temp, sizeof (temp));
1060 if (result != ASN1_SUCCESS)
1061 goto cleanup;
1063 tlen = strlen (temp);
1064 if (tlen > 0)
1065 _asn1_set_value (p, temp, tlen + 1);
1066 counter += len2;
1067 move = RIGHT;
1068 break;
1069 case TYPE_TIME:
1070 result =
1071 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1072 sizeof (temp) - 1);
1073 if (result != ASN1_SUCCESS)
1074 goto cleanup;
1076 tlen = strlen (temp);
1077 if (tlen > 0)
1078 _asn1_set_value (p, temp, tlen + 1);
1079 counter += len2;
1080 move = RIGHT;
1081 break;
1082 case TYPE_OCTET_STRING:
1083 len3 = len - counter;
1084 result = _asn1_get_octet_string (der + counter, p, &len3);
1085 if (result != ASN1_SUCCESS)
1086 goto cleanup;
1088 counter += len3;
1089 move = RIGHT;
1090 break;
1091 case TYPE_GENERALSTRING:
1092 len2 =
1093 asn1_get_length_der (der + counter, len - counter, &len3);
1094 if (len2 < 0)
1096 result = ASN1_DER_ERROR;
1097 goto cleanup;
1100 _asn1_set_value (p, der + counter, len3 + len2);
1101 counter += len3 + len2;
1102 move = RIGHT;
1103 break;
1104 case TYPE_BIT_STRING:
1105 len2 =
1106 asn1_get_length_der (der + counter, len - counter, &len3);
1107 if (len2 < 0)
1109 result = ASN1_DER_ERROR;
1110 goto cleanup;
1113 _asn1_set_value (p, der + counter, len3 + len2);
1114 counter += len3 + len2;
1115 move = RIGHT;
1116 break;
1117 case TYPE_SEQUENCE:
1118 case TYPE_SET:
1119 if (move == UP)
1121 len2 = _asn1_strtol (p->value, NULL, 10);
1122 _asn1_set_value (p, NULL, 0);
1123 if (len2 == -1)
1124 { /* indefinite length method */
1125 if (len - counter + 1 > 0)
1127 if ((der[counter]) || der[counter + 1])
1129 result = ASN1_DER_ERROR;
1130 goto cleanup;
1133 else
1135 result = ASN1_DER_ERROR;
1136 goto cleanup;
1138 counter += 2;
1140 else
1141 { /* definite length method */
1142 if (len2 != counter)
1144 result = ASN1_DER_ERROR;
1145 goto cleanup;
1148 move = RIGHT;
1150 else
1151 { /* move==DOWN || move==RIGHT */
1152 len3 =
1153 asn1_get_length_der (der + counter, len - counter, &len2);
1154 if (len3 < -1)
1156 result = ASN1_DER_ERROR;
1157 goto cleanup;
1159 counter += len2;
1160 if (len3 > 0)
1162 _asn1_ltostr (counter + len3, temp);
1163 tlen = strlen (temp);
1164 if (tlen > 0)
1165 _asn1_set_value (p, temp, tlen + 1);
1166 move = DOWN;
1168 else if (len3 == 0)
1170 p2 = p->down;
1171 while (p2)
1173 if (type_field (p2->type) != TYPE_TAG)
1175 p3 = p2->right;
1176 asn1_delete_structure (&p2);
1177 p2 = p3;
1179 else
1180 p2 = p2->right;
1182 move = RIGHT;
1184 else
1185 { /* indefinite length method */
1186 _asn1_set_value (p, "-1", 3);
1187 move = DOWN;
1190 break;
1191 case TYPE_SEQUENCE_OF:
1192 case TYPE_SET_OF:
1193 if (move == UP)
1195 len2 = _asn1_strtol (p->value, NULL, 10);
1196 if (len2 == -1)
1197 { /* indefinite length method */
1198 if ((counter + 2) > len)
1200 result = ASN1_DER_ERROR;
1201 goto cleanup;
1204 if ((der[counter]) || der[counter + 1])
1206 _asn1_append_sequence_set (p);
1207 p = p->down;
1208 while (p->right)
1209 p = p->right;
1210 move = RIGHT;
1211 continue;
1213 _asn1_set_value (p, NULL, 0);
1214 counter += 2;
1216 else
1217 { /* definite length method */
1218 if (len2 > counter)
1220 _asn1_append_sequence_set (p);
1221 p = p->down;
1222 while (p->right)
1223 p = p->right;
1224 move = RIGHT;
1225 continue;
1227 _asn1_set_value (p, NULL, 0);
1228 if (len2 != counter)
1230 result = ASN1_DER_ERROR;
1231 goto cleanup;
1235 else
1236 { /* move==DOWN || move==RIGHT */
1237 len3 =
1238 asn1_get_length_der (der + counter, len - counter, &len2);
1239 if (len3 < -1)
1241 result = ASN1_DER_ERROR;
1242 goto cleanup;
1244 counter += len2;
1245 if (len3)
1247 if (len3 > 0)
1248 { /* definite length method */
1249 _asn1_ltostr (counter + len3, temp);
1250 tlen = strlen (temp);
1252 if (tlen > 0)
1253 _asn1_set_value (p, temp, tlen + 1);
1255 else
1256 { /* indefinite length method */
1257 _asn1_set_value (p, "-1", 3);
1259 p2 = p->down;
1260 while ((type_field (p2->type) == TYPE_TAG)
1261 || (type_field (p2->type) == TYPE_SIZE))
1262 p2 = p2->right;
1263 if (p2->right == NULL)
1264 _asn1_append_sequence_set (p);
1265 p = p2;
1268 move = RIGHT;
1269 break;
1270 case TYPE_ANY:
1271 if (asn1_get_tag_der
1272 (der + counter, len - counter, &class, &len2,
1273 &tag) != ASN1_SUCCESS)
1275 result = ASN1_DER_ERROR;
1276 goto cleanup;
1279 if (counter + len2 > len)
1281 result = ASN1_DER_ERROR;
1282 goto cleanup;
1284 len4 =
1285 asn1_get_length_der (der + counter + len2,
1286 len - counter - len2, &len3);
1287 if (len4 < -1)
1289 result = ASN1_DER_ERROR;
1290 goto cleanup;
1292 if (len4 != -1)
1294 len2 += len4;
1295 _asn1_set_value_octet (p, der + counter, len2 + len3);
1296 counter += len2 + len3;
1298 else
1299 { /* indefinite length */
1300 /* Check indefinite lenth method in an EXPLICIT TAG */
1301 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1302 indefinite = 1;
1303 else
1304 indefinite = 0;
1306 len2 = len - counter;
1307 result =
1308 _asn1_get_indefinite_length_string (der + counter, &len2);
1309 if (result != ASN1_SUCCESS)
1310 goto cleanup;
1312 _asn1_set_value_octet (p, der + counter, len2);
1313 counter += len2;
1315 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1316 an indefinite length method. */
1317 if (indefinite)
1319 if (!der[counter] && !der[counter + 1])
1321 counter += 2;
1323 else
1325 result = ASN1_DER_ERROR;
1326 goto cleanup;
1330 move = RIGHT;
1331 break;
1332 default:
1333 move = (move == UP) ? RIGHT : DOWN;
1334 break;
1338 if (p == node && move != DOWN)
1339 break;
1341 if (move == DOWN)
1343 if (p->down)
1344 p = p->down;
1345 else
1346 move = RIGHT;
1348 if ((move == RIGHT) && !(p->type & CONST_SET))
1350 if (p->right)
1351 p = p->right;
1352 else
1353 move = UP;
1355 if (move == UP)
1356 p = _asn1_find_up (p);
1359 _asn1_delete_not_used (*element);
1361 if (counter != len)
1363 result = ASN1_DER_ERROR;
1364 goto cleanup;
1367 return ASN1_SUCCESS;
1369 cleanup:
1370 asn1_delete_structure (element);
1371 return result;
1374 #define FOUND 1
1375 #define SAME_BRANCH 2
1376 #define OTHER_BRANCH 3
1377 #define EXIT 4
1380 * asn1_der_decoding_element:
1381 * @structure: pointer to an ASN1 structure
1382 * @elementName: name of the element to fill
1383 * @ider: vector that contains the DER encoding of the whole structure.
1384 * @len: number of bytes of *der: der[0]..der[len-1]
1385 * @errorDescription: null-terminated string contains details when an
1386 * error occurred.
1388 * Fill the element named @ELEMENTNAME with values of a DER encoding
1389 * string. The structure must just be created with function
1390 * asn1_create_element(). The DER vector must contain the encoding
1391 * string of the whole @STRUCTURE. If an error occurs during the
1392 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1393 * %ASN1_TYPE_EMPTY.
1395 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1396 * if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
1397 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1398 * match the structure @structure (*ELEMENT deleted).
1400 asn1_retCode
1401 asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
1402 const void *ider, int len, char *errorDescription)
1404 ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
1405 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1406 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1407 int counter, len2, len3, len4, move, ris, tlen;
1408 unsigned char class;
1409 unsigned long tag;
1410 int indefinite, result;
1411 const unsigned char *der = ider;
1413 node = *structure;
1415 if (node == ASN1_TYPE_EMPTY)
1416 return ASN1_ELEMENT_NOT_FOUND;
1418 if (elementName == NULL)
1420 result = ASN1_ELEMENT_NOT_FOUND;
1421 goto cleanup;
1424 if (node->type & CONST_OPTION)
1426 result = ASN1_GENERIC_ERROR;
1427 goto cleanup;
1430 if ((*structure)->name)
1431 { /* Has *structure got a name? */
1432 nameLen -= strlen ((*structure)->name);
1433 if (nameLen > 0)
1434 strcpy (currentName, (*structure)->name);
1435 else
1437 result = ASN1_MEM_ERROR;
1438 goto cleanup;
1440 if (!(strcmp (currentName, elementName)))
1442 state = FOUND;
1443 nodeFound = *structure;
1445 else if (!memcmp (currentName, elementName, strlen (currentName)))
1446 state = SAME_BRANCH;
1447 else
1448 state = OTHER_BRANCH;
1450 else
1451 { /* *structure doesn't have a name? */
1452 currentName[0] = 0;
1453 if (elementName[0] == 0)
1455 state = FOUND;
1456 nodeFound = *structure;
1458 else
1460 state = SAME_BRANCH;
1464 counter = 0;
1465 move = DOWN;
1466 p = node;
1467 while (1)
1470 ris = ASN1_SUCCESS;
1472 if (move != UP)
1474 if (p->type & CONST_SET)
1476 p2 = _asn1_find_up (p);
1477 len2 = _asn1_strtol (p2->value, NULL, 10);
1478 if (counter == len2)
1480 p = p2;
1481 move = UP;
1482 continue;
1484 else if (counter > len2)
1486 result = ASN1_DER_ERROR;
1487 goto cleanup;
1489 p2 = p2->down;
1490 while (p2)
1492 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1494 if (type_field (p2->type) != TYPE_CHOICE)
1495 ris =
1496 _asn1_extract_tag_der (p2, der + counter,
1497 len - counter, &len2);
1498 else
1500 p3 = p2->down;
1501 while (p3)
1503 ris =
1504 _asn1_extract_tag_der (p3, der + counter,
1505 len - counter, &len2);
1506 if (ris == ASN1_SUCCESS)
1507 break;
1508 p3 = p3->right;
1511 if (ris == ASN1_SUCCESS)
1513 p2->type &= ~CONST_NOT_USED;
1514 p = p2;
1515 break;
1518 p2 = p2->right;
1520 if (p2 == NULL)
1522 result = ASN1_DER_ERROR;
1523 goto cleanup;
1527 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1529 p2 = _asn1_find_up (p);
1530 len2 = _asn1_strtol (p2->value, NULL, 10);
1531 if (counter == len2)
1533 if (p->right)
1535 p2 = p->right;
1536 move = RIGHT;
1538 else
1539 move = UP;
1541 if (p->type & CONST_OPTION)
1542 asn1_delete_structure (&p);
1544 p = p2;
1545 continue;
1549 if (type_field (p->type) == TYPE_CHOICE)
1551 while (p->down)
1553 if (counter < len)
1554 ris =
1555 _asn1_extract_tag_der (p->down, der + counter,
1556 len - counter, &len2);
1557 else
1558 ris = ASN1_DER_ERROR;
1559 if (ris == ASN1_SUCCESS)
1561 while (p->down->right)
1563 p2 = p->down->right;
1564 asn1_delete_structure (&p2);
1566 break;
1568 else if (ris == ASN1_ERROR_TYPE_ANY)
1570 result = ASN1_ERROR_TYPE_ANY;
1571 goto cleanup;
1573 else
1575 p2 = p->down;
1576 asn1_delete_structure (&p2);
1580 if (p->down == NULL)
1582 if (!(p->type & CONST_OPTION))
1584 result = ASN1_DER_ERROR;
1585 goto cleanup;
1588 else
1589 p = p->down;
1592 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1594 p2 = _asn1_find_up (p);
1595 len2 = _asn1_strtol (p2->value, NULL, 10);
1596 if (counter > len2)
1597 ris = ASN1_TAG_ERROR;
1600 if (ris == ASN1_SUCCESS)
1601 ris =
1602 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1603 if (ris != ASN1_SUCCESS)
1605 if (p->type & CONST_OPTION)
1607 p->type |= CONST_NOT_USED;
1608 move = RIGHT;
1610 else if (p->type & CONST_DEFAULT)
1612 _asn1_set_value (p, NULL, 0);
1613 move = RIGHT;
1615 else
1617 if (errorDescription != NULL)
1618 _asn1_error_description_tag_error (p, errorDescription);
1620 result = ASN1_TAG_ERROR;
1621 goto cleanup;
1624 else
1625 counter += len2;
1628 if (ris == ASN1_SUCCESS)
1630 switch (type_field (p->type))
1632 case TYPE_NULL:
1633 if (der[counter])
1635 result = ASN1_DER_ERROR;
1636 goto cleanup;
1639 if (p == nodeFound)
1640 state = EXIT;
1642 counter++;
1643 move = RIGHT;
1644 break;
1645 case TYPE_BOOLEAN:
1646 if (der[counter++] != 1)
1648 result = ASN1_DER_ERROR;
1649 goto cleanup;
1652 if (state == FOUND)
1654 if (der[counter++] == 0)
1655 _asn1_set_value (p, "F", 1);
1656 else
1657 _asn1_set_value (p, "T", 1);
1659 if (p == nodeFound)
1660 state = EXIT;
1663 else
1664 counter++;
1666 move = RIGHT;
1667 break;
1668 case TYPE_INTEGER:
1669 case TYPE_ENUMERATED:
1670 len2 =
1671 asn1_get_length_der (der + counter, len - counter, &len3);
1672 if (len2 < 0)
1674 result = ASN1_DER_ERROR;
1675 goto cleanup;
1678 if (state == FOUND)
1680 if (len3 + len2 > len - counter)
1682 result = ASN1_DER_ERROR;
1683 goto cleanup;
1685 _asn1_set_value (p, der + counter, len3 + len2);
1687 if (p == nodeFound)
1688 state = EXIT;
1690 counter += len3 + len2;
1691 move = RIGHT;
1692 break;
1693 case TYPE_OBJECT_ID:
1694 if (state == FOUND)
1696 result =
1697 _asn1_get_objectid_der (der + counter, len - counter,
1698 &len2, temp, sizeof (temp));
1699 if (result != ASN1_SUCCESS)
1700 goto cleanup;
1702 tlen = strlen (temp);
1704 if (tlen > 0)
1705 _asn1_set_value (p, temp, tlen + 1);
1707 if (p == nodeFound)
1708 state = EXIT;
1710 else
1712 len2 =
1713 asn1_get_length_der (der + counter, len - counter, &len3);
1714 if (len2 < 0)
1716 result = ASN1_DER_ERROR;
1717 goto cleanup;
1719 len2 += len3;
1722 counter += len2;
1723 move = RIGHT;
1724 break;
1725 case TYPE_TIME:
1726 if (state == FOUND)
1728 result =
1729 _asn1_get_time_der (der + counter, len - counter, &len2,
1730 temp, sizeof (temp) - 1);
1731 if (result != ASN1_SUCCESS)
1732 goto cleanup;
1734 tlen = strlen (temp);
1735 if (tlen > 0)
1736 _asn1_set_value (p, temp, tlen + 1);
1738 if (p == nodeFound)
1739 state = EXIT;
1741 else
1743 len2 =
1744 asn1_get_length_der (der + counter, len - counter, &len3);
1745 if (len2 < 0)
1747 result = ASN1_DER_ERROR;
1748 goto cleanup;
1750 len2 += len3;
1753 counter += len2;
1754 move = RIGHT;
1755 break;
1756 case TYPE_OCTET_STRING:
1757 len3 = len - counter;
1758 if (state == FOUND)
1760 result = _asn1_get_octet_string (der + counter, p, &len3);
1761 if (p == nodeFound)
1762 state = EXIT;
1764 else
1765 result = _asn1_get_octet_string (der + counter, NULL, &len3);
1767 if (result != ASN1_SUCCESS)
1768 goto cleanup;
1770 counter += len3;
1771 move = RIGHT;
1772 break;
1773 case TYPE_GENERALSTRING:
1774 len2 =
1775 asn1_get_length_der (der + counter, len - counter, &len3);
1776 if (len2 < 0)
1778 result = ASN1_DER_ERROR;
1779 goto cleanup;
1782 if (state == FOUND)
1784 if (len3 + len2 > len - counter)
1786 result = ASN1_DER_ERROR;
1787 goto cleanup;
1789 _asn1_set_value (p, der + counter, len3 + len2);
1791 if (p == nodeFound)
1792 state = EXIT;
1794 counter += len3 + len2;
1795 move = RIGHT;
1796 break;
1797 case TYPE_BIT_STRING:
1798 len2 =
1799 asn1_get_length_der (der + counter, len - counter, &len3);
1800 if (len2 < 0)
1802 result = ASN1_DER_ERROR;
1803 goto cleanup;
1805 if (state == FOUND)
1807 if (len3 + len2 > len - counter)
1809 result = ASN1_DER_ERROR;
1810 goto cleanup;
1812 _asn1_set_value (p, der + counter, len3 + len2);
1814 if (p == nodeFound)
1815 state = EXIT;
1817 counter += len3 + len2;
1818 move = RIGHT;
1819 break;
1820 case TYPE_SEQUENCE:
1821 case TYPE_SET:
1822 if (move == UP)
1824 len2 = _asn1_strtol (p->value, NULL, 10);
1825 _asn1_set_value (p, NULL, 0);
1826 if (len2 == -1)
1827 { /* indefinite length method */
1828 if ((der[counter]) || der[counter + 1])
1830 result = ASN1_DER_ERROR;
1831 goto cleanup;
1833 counter += 2;
1835 else
1836 { /* definite length method */
1837 if (len2 != counter)
1839 result = ASN1_DER_ERROR;
1840 goto cleanup;
1843 if (p == nodeFound)
1844 state = EXIT;
1845 move = RIGHT;
1847 else
1848 { /* move==DOWN || move==RIGHT */
1849 if (state == OTHER_BRANCH)
1851 len3 =
1852 asn1_get_length_der (der + counter, len - counter,
1853 &len2);
1854 if (len3 < 0)
1856 result = ASN1_DER_ERROR;
1857 goto cleanup;
1859 counter += len2 + len3;
1860 move = RIGHT;
1862 else
1863 { /* state==SAME_BRANCH or state==FOUND */
1864 len3 =
1865 asn1_get_length_der (der + counter, len - counter,
1866 &len2);
1867 if (len3 < 0)
1869 result = ASN1_DER_ERROR;
1870 goto cleanup;
1872 counter += len2;
1873 if (len3 > 0)
1875 _asn1_ltostr (counter + len3, temp);
1876 tlen = strlen (temp);
1878 if (tlen > 0)
1879 _asn1_set_value (p, temp, tlen + 1);
1880 move = DOWN;
1882 else if (len3 == 0)
1884 p2 = p->down;
1885 while (p2)
1887 if (type_field (p2->type) != TYPE_TAG)
1889 p3 = p2->right;
1890 asn1_delete_structure (&p2);
1891 p2 = p3;
1893 else
1894 p2 = p2->right;
1896 move = RIGHT;
1898 else
1899 { /* indefinite length method */
1900 _asn1_set_value (p, "-1", 3);
1901 move = DOWN;
1905 break;
1906 case TYPE_SEQUENCE_OF:
1907 case TYPE_SET_OF:
1908 if (move == UP)
1910 len2 = _asn1_strtol (p->value, NULL, 10);
1911 if (len2 > counter)
1913 _asn1_append_sequence_set (p);
1914 p = p->down;
1915 while (p->right)
1916 p = p->right;
1917 move = RIGHT;
1918 continue;
1920 _asn1_set_value (p, NULL, 0);
1921 if (len2 != counter)
1923 result = ASN1_DER_ERROR;
1924 goto cleanup;
1927 if (p == nodeFound)
1928 state = EXIT;
1930 else
1931 { /* move==DOWN || move==RIGHT */
1932 if (state == OTHER_BRANCH)
1934 len3 =
1935 asn1_get_length_der (der + counter, len - counter,
1936 &len2);
1937 if (len3 < 0)
1939 result = ASN1_DER_ERROR;
1940 goto cleanup;
1942 counter += len2 + len3;
1943 move = RIGHT;
1945 else
1946 { /* state==FOUND or state==SAME_BRANCH */
1947 len3 =
1948 asn1_get_length_der (der + counter, len - counter,
1949 &len2);
1950 if (len3 < 0)
1952 result = ASN1_DER_ERROR;
1953 goto cleanup;
1955 counter += len2;
1956 if (len3)
1958 _asn1_ltostr (counter + len3, temp);
1959 tlen = strlen (temp);
1961 if (tlen > 0)
1962 _asn1_set_value (p, temp, tlen + 1);
1963 p2 = p->down;
1964 while ((type_field (p2->type) == TYPE_TAG)
1965 || (type_field (p2->type) == TYPE_SIZE))
1966 p2 = p2->right;
1967 if (p2->right == NULL)
1968 _asn1_append_sequence_set (p);
1969 p = p2;
1970 state = FOUND;
1975 break;
1976 case TYPE_ANY:
1977 if (asn1_get_tag_der
1978 (der + counter, len - counter, &class, &len2,
1979 &tag) != ASN1_SUCCESS)
1981 result = ASN1_DER_ERROR;
1982 goto cleanup;
1985 if (counter + len2 > len)
1987 result = ASN1_DER_ERROR;
1988 goto cleanup;
1991 len4 =
1992 asn1_get_length_der (der + counter + len2,
1993 len - counter - len2, &len3);
1994 if (len4 < -1)
1996 result = ASN1_DER_ERROR;
1997 goto cleanup;
2000 if (len4 != -1)
2002 len2 += len4;
2003 if (state == FOUND)
2005 _asn1_set_value_octet (p, der + counter, len2 + len3);
2007 if (p == nodeFound)
2008 state = EXIT;
2010 counter += len2 + len3;
2012 else
2013 { /* indefinite length */
2014 /* Check indefinite lenth method in an EXPLICIT TAG */
2015 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2016 indefinite = 1;
2017 else
2018 indefinite = 0;
2020 len2 = len - counter;
2021 result =
2022 _asn1_get_indefinite_length_string (der + counter, &len2);
2023 if (result != ASN1_SUCCESS)
2024 goto cleanup;
2026 if (state == FOUND)
2028 _asn1_set_value_octet (p, der + counter, len2);
2030 if (p == nodeFound)
2031 state = EXIT;
2034 counter += len2;
2036 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2037 an indefinite length method. */
2038 if (indefinite)
2040 if (!der[counter] && !der[counter + 1])
2042 counter += 2;
2044 else
2046 result = ASN1_DER_ERROR;
2047 goto cleanup;
2051 move = RIGHT;
2052 break;
2054 default:
2055 move = (move == UP) ? RIGHT : DOWN;
2056 break;
2060 if ((p == node && move != DOWN) || (state == EXIT))
2061 break;
2063 if (move == DOWN)
2065 if (p->down)
2067 p = p->down;
2069 if (state != FOUND)
2071 nameLen -= strlen (p->name) + 1;
2072 if (nameLen > 0)
2074 if (currentName[0])
2075 strcat (currentName, ".");
2076 strcat (currentName, p->name);
2078 else
2080 result = ASN1_MEM_ERROR;
2081 goto cleanup;
2083 if (!(strcmp (currentName, elementName)))
2085 state = FOUND;
2086 nodeFound = p;
2088 else
2089 if (!memcmp
2090 (currentName, elementName, strlen (currentName)))
2091 state = SAME_BRANCH;
2092 else
2093 state = OTHER_BRANCH;
2096 else
2097 move = RIGHT;
2100 if ((move == RIGHT) && !(p->type & CONST_SET))
2102 if (p->right)
2104 p = p->right;
2106 if (state != FOUND)
2108 dot_p = char_p = currentName;
2109 while ((char_p = strchr (char_p, '.')))
2111 dot_p = char_p++;
2112 dot_p++;
2115 nameLen += strlen (currentName) - (dot_p - currentName);
2116 *dot_p = 0;
2118 nameLen -= strlen (p->name);
2119 if (nameLen > 0)
2120 strcat (currentName, p->name);
2121 else
2123 result = ASN1_MEM_ERROR;
2124 goto cleanup;
2127 if (!(strcmp (currentName, elementName)))
2129 state = FOUND;
2130 nodeFound = p;
2132 else
2133 if (!memcmp
2134 (currentName, elementName, strlen (currentName)))
2135 state = SAME_BRANCH;
2136 else
2137 state = OTHER_BRANCH;
2140 else
2141 move = UP;
2144 if (move == UP)
2146 p = _asn1_find_up (p);
2148 if (state != FOUND)
2150 dot_p = char_p = currentName;
2151 while ((char_p = strchr (char_p, '.')))
2153 dot_p = char_p++;
2154 dot_p++;
2157 nameLen += strlen (currentName) - (dot_p - currentName);
2158 *dot_p = 0;
2160 if (!(strcmp (currentName, elementName)))
2162 state = FOUND;
2163 nodeFound = p;
2165 else
2166 if (!memcmp (currentName, elementName, strlen (currentName)))
2167 state = SAME_BRANCH;
2168 else
2169 state = OTHER_BRANCH;
2174 _asn1_delete_not_used (*structure);
2176 if (counter > len)
2178 result = ASN1_DER_ERROR;
2179 goto cleanup;
2182 return ASN1_SUCCESS;
2184 cleanup:
2185 asn1_delete_structure (structure);
2186 return result;
2190 * asn1_der_decoding_startEnd:
2191 * @element: pointer to an ASN1 element
2192 * @ider: vector that contains the DER encoding.
2193 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2194 * @name_element: an element of NAME structure.
2195 * @start: the position of the first byte of NAME_ELEMENT decoding
2196 * (@ider[*start])
2197 * @end: the position of the last byte of NAME_ELEMENT decoding
2198 * (@ider[*end])
2200 * Find the start and end point of an element in a DER encoding
2201 * string. I mean that if you have a der encoding and you have already
2202 * used the function asn1_der_decoding() to fill a structure, it may
2203 * happen that you want to find the piece of string concerning an
2204 * element of the structure.
2206 * One example is the sequence "tbsCertificate" inside an X509
2207 * certificate.
2209 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2210 * if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
2211 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2212 * doesn't match the structure ELEMENT.
2214 asn1_retCode
2215 asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
2216 const char *name_element, int *start, int *end)
2218 ASN1_TYPE node, node_to_find, p, p2, p3;
2219 int counter, len2, len3, len4, move, ris;
2220 unsigned char class;
2221 unsigned long tag;
2222 int indefinite;
2223 const unsigned char *der = ider;
2225 node = element;
2227 if (node == ASN1_TYPE_EMPTY)
2228 return ASN1_ELEMENT_NOT_FOUND;
2230 node_to_find = asn1_find_node (node, name_element);
2232 if (node_to_find == NULL)
2233 return ASN1_ELEMENT_NOT_FOUND;
2235 if (node_to_find == node)
2237 *start = 0;
2238 *end = len - 1;
2239 return ASN1_SUCCESS;
2242 if (node->type & CONST_OPTION)
2243 return ASN1_GENERIC_ERROR;
2245 counter = 0;
2246 move = DOWN;
2247 p = node;
2248 while (1)
2250 ris = ASN1_SUCCESS;
2252 if (move != UP)
2254 if (p->type & CONST_SET)
2256 p2 = _asn1_find_up (p);
2257 len2 = _asn1_strtol (p2->value, NULL, 10);
2258 if (len2 == -1)
2260 if (!der[counter] && !der[counter + 1])
2262 p = p2;
2263 move = UP;
2264 counter += 2;
2265 continue;
2268 else if (counter == len2)
2270 p = p2;
2271 move = UP;
2272 continue;
2274 else if (counter > len2)
2275 return ASN1_DER_ERROR;
2276 p2 = p2->down;
2277 while (p2)
2279 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2280 { /* CONTROLLARE */
2281 if (type_field (p2->type) != TYPE_CHOICE)
2282 ris =
2283 _asn1_extract_tag_der (p2, der + counter,
2284 len - counter, &len2);
2285 else
2287 p3 = p2->down;
2288 ris =
2289 _asn1_extract_tag_der (p3, der + counter,
2290 len - counter, &len2);
2292 if (ris == ASN1_SUCCESS)
2294 p2->type &= ~CONST_NOT_USED;
2295 p = p2;
2296 break;
2299 p2 = p2->right;
2301 if (p2 == NULL)
2302 return ASN1_DER_ERROR;
2305 if (p == node_to_find)
2306 *start = counter;
2308 if (type_field (p->type) == TYPE_CHOICE)
2310 p = p->down;
2311 ris =
2312 _asn1_extract_tag_der (p, der + counter, len - counter,
2313 &len2);
2314 if (p == node_to_find)
2315 *start = counter;
2318 if (ris == ASN1_SUCCESS)
2319 ris =
2320 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2321 if (ris != ASN1_SUCCESS)
2323 if (p->type & CONST_OPTION)
2325 p->type |= CONST_NOT_USED;
2326 move = RIGHT;
2328 else if (p->type & CONST_DEFAULT)
2330 move = RIGHT;
2332 else
2334 return ASN1_TAG_ERROR;
2337 else
2338 counter += len2;
2341 if (ris == ASN1_SUCCESS)
2343 switch (type_field (p->type))
2345 case TYPE_NULL:
2346 if (der[counter])
2347 return ASN1_DER_ERROR;
2348 counter++;
2349 move = RIGHT;
2350 break;
2351 case TYPE_BOOLEAN:
2352 if (der[counter++] != 1)
2353 return ASN1_DER_ERROR;
2354 counter++;
2355 move = RIGHT;
2356 break;
2357 case TYPE_INTEGER:
2358 case TYPE_ENUMERATED:
2359 len2 =
2360 asn1_get_length_der (der + counter, len - counter, &len3);
2361 if (len2 < 0)
2362 return ASN1_DER_ERROR;
2363 counter += len3 + len2;
2364 move = RIGHT;
2365 break;
2366 case TYPE_OBJECT_ID:
2367 len2 =
2368 asn1_get_length_der (der + counter, len - counter, &len3);
2369 if (len2 < 0)
2370 return ASN1_DER_ERROR;
2371 counter += len2 + len3;
2372 move = RIGHT;
2373 break;
2374 case TYPE_TIME:
2375 len2 =
2376 asn1_get_length_der (der + counter, len - counter, &len3);
2377 if (len2 < 0)
2378 return ASN1_DER_ERROR;
2379 counter += len2 + len3;
2380 move = RIGHT;
2381 break;
2382 case TYPE_OCTET_STRING:
2383 len3 = len - counter;
2384 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2385 if (ris != ASN1_SUCCESS)
2386 return ris;
2387 counter += len3;
2388 move = RIGHT;
2389 break;
2390 case TYPE_GENERALSTRING:
2391 len2 =
2392 asn1_get_length_der (der + counter, len - counter, &len3);
2393 if (len2 < 0)
2394 return ASN1_DER_ERROR;
2395 counter += len3 + len2;
2396 move = RIGHT;
2397 break;
2398 case TYPE_BIT_STRING:
2399 len2 =
2400 asn1_get_length_der (der + counter, len - counter, &len3);
2401 if (len2 < 0)
2402 return ASN1_DER_ERROR;
2403 counter += len3 + len2;
2404 move = RIGHT;
2405 break;
2406 case TYPE_SEQUENCE:
2407 case TYPE_SET:
2408 if (move != UP)
2410 len3 =
2411 asn1_get_length_der (der + counter, len - counter, &len2);
2412 if (len3 < -1)
2413 return ASN1_DER_ERROR;
2414 counter += len2;
2415 if (len3 == 0)
2416 move = RIGHT;
2417 else
2418 move = DOWN;
2420 else
2422 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2423 counter += 2;
2424 move = RIGHT;
2426 break;
2427 case TYPE_SEQUENCE_OF:
2428 case TYPE_SET_OF:
2429 if (move != UP)
2431 len3 =
2432 asn1_get_length_der (der + counter, len - counter, &len2);
2433 if (len3 < -1)
2434 return ASN1_DER_ERROR;
2435 counter += len2;
2436 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2437 counter += 2;
2438 else if (len3)
2440 p2 = p->down;
2441 while ((type_field (p2->type) == TYPE_TAG) ||
2442 (type_field (p2->type) == TYPE_SIZE))
2443 p2 = p2->right;
2444 p = p2;
2447 else
2449 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2450 counter += 2;
2452 move = RIGHT;
2453 break;
2454 case TYPE_ANY:
2455 if (asn1_get_tag_der
2456 (der + counter, len - counter, &class, &len2,
2457 &tag) != ASN1_SUCCESS)
2458 return ASN1_DER_ERROR;
2459 if (counter + len2 > len)
2460 return ASN1_DER_ERROR;
2462 len4 =
2463 asn1_get_length_der (der + counter + len2,
2464 len - counter - len2, &len3);
2465 if (len4 < -1)
2466 return ASN1_DER_ERROR;
2468 if (len4 != -1)
2470 counter += len2 + len4 + len3;
2472 else
2473 { /* indefinite length */
2474 /* Check indefinite lenth method in an EXPLICIT TAG */
2475 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2476 indefinite = 1;
2477 else
2478 indefinite = 0;
2480 len2 = len - counter;
2481 ris =
2482 _asn1_get_indefinite_length_string (der + counter, &len2);
2483 if (ris != ASN1_SUCCESS)
2484 return ris;
2485 counter += len2;
2487 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2488 an indefinite length method. */
2489 if (indefinite)
2491 if (!der[counter] && !der[counter + 1])
2492 counter += 2;
2493 else
2494 return ASN1_DER_ERROR;
2497 move = RIGHT;
2498 break;
2499 default:
2500 move = (move == UP) ? RIGHT : DOWN;
2501 break;
2505 if ((p == node_to_find) && (move == RIGHT))
2507 *end = counter - 1;
2508 return ASN1_SUCCESS;
2511 if (p == node && move != DOWN)
2512 break;
2514 if (move == DOWN)
2516 if (p->down)
2517 p = p->down;
2518 else
2519 move = RIGHT;
2521 if ((move == RIGHT) && !(p->type & CONST_SET))
2523 if (p->right)
2524 p = p->right;
2525 else
2526 move = UP;
2528 if (move == UP)
2529 p = _asn1_find_up (p);
2532 return ASN1_ELEMENT_NOT_FOUND;
2536 * asn1_expand_any_defined_by:
2537 * @definitions: ASN1 definitions
2538 * @element: pointer to an ASN1 structure
2540 * Expands every "ANY DEFINED BY" element of a structure created from
2541 * a DER decoding process (asn1_der_decoding function). The element
2542 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2543 * expand the element ANY is the first one following the definition of
2544 * the actual value of the OBJECT IDENTIFIER.
2546 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2547 * some "ANY DEFINED BY" element couldn't be expanded due to a
2548 * problem in OBJECT_ID -> TYPE association, or other error codes
2549 * depending on DER decoding.
2551 asn1_retCode
2552 asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
2554 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2555 value[ASN1_MAX_NAME_SIZE];
2556 asn1_retCode retCode = ASN1_SUCCESS, result;
2557 int len, len2, len3;
2558 ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
2559 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2561 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2562 return ASN1_ELEMENT_NOT_FOUND;
2564 strcpy (definitionsName, definitions->name);
2565 strcat (definitionsName, ".");
2567 p = *element;
2568 while (p)
2571 switch (type_field (p->type))
2573 case TYPE_ANY:
2574 if ((p->type & CONST_DEFINED_BY) && (p->value))
2576 /* search the "DEF_BY" element */
2577 p2 = p->down;
2578 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2579 p2 = p2->right;
2581 if (!p2)
2583 retCode = ASN1_ERROR_TYPE_ANY;
2584 break;
2587 p3 = _asn1_find_up (p);
2589 if (!p3)
2591 retCode = ASN1_ERROR_TYPE_ANY;
2592 break;
2595 p3 = p3->down;
2596 while (p3)
2598 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2599 break;
2600 p3 = p3->right;
2603 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2604 (p3->value == NULL))
2607 p3 = _asn1_find_up (p);
2608 p3 = _asn1_find_up (p3);
2610 if (!p3)
2612 retCode = ASN1_ERROR_TYPE_ANY;
2613 break;
2616 p3 = p3->down;
2618 while (p3)
2620 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2621 break;
2622 p3 = p3->right;
2625 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2626 (p3->value == NULL))
2628 retCode = ASN1_ERROR_TYPE_ANY;
2629 break;
2633 /* search the OBJECT_ID into definitions */
2634 p2 = definitions->down;
2635 while (p2)
2637 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2638 (p2->type & CONST_ASSIGN))
2640 strcpy (name, definitionsName);
2641 strcat (name, p2->name);
2643 len = ASN1_MAX_NAME_SIZE;
2644 result =
2645 asn1_read_value (definitions, name, value, &len);
2647 if ((result == ASN1_SUCCESS)
2648 && (!_asn1_strcmp (p3->value, value)))
2650 p2 = p2->right; /* pointer to the structure to
2651 use for expansion */
2652 while ((p2) && (p2->type & CONST_ASSIGN))
2653 p2 = p2->right;
2655 if (p2)
2657 strcpy (name, definitionsName);
2658 strcat (name, p2->name);
2660 result =
2661 asn1_create_element (definitions, name, &aux);
2662 if (result == ASN1_SUCCESS)
2664 _asn1_set_name (aux, p->name);
2665 len2 =
2666 asn1_get_length_der (p->value,
2667 p->value_len, &len3);
2668 if (len2 < 0)
2669 return ASN1_DER_ERROR;
2671 result =
2672 asn1_der_decoding (&aux, p->value + len3,
2673 len2,
2674 errorDescription);
2675 if (result == ASN1_SUCCESS)
2678 _asn1_set_right (aux, p->right);
2679 _asn1_set_right (p, aux);
2681 result = asn1_delete_structure (&p);
2682 if (result == ASN1_SUCCESS)
2684 p = aux;
2685 aux = ASN1_TYPE_EMPTY;
2686 break;
2688 else
2689 { /* error with asn1_delete_structure */
2690 asn1_delete_structure (&aux);
2691 retCode = result;
2692 break;
2695 else
2696 { /* error with asn1_der_decoding */
2697 retCode = result;
2698 break;
2701 else
2702 { /* error with asn1_create_element */
2703 retCode = result;
2704 break;
2707 else
2708 { /* error with the pointer to the structure to exapand */
2709 retCode = ASN1_ERROR_TYPE_ANY;
2710 break;
2714 p2 = p2->right;
2715 } /* end while */
2717 if (!p2)
2719 retCode = ASN1_ERROR_TYPE_ANY;
2720 break;
2724 break;
2725 default:
2726 break;
2730 if (p->down)
2732 p = p->down;
2734 else if (p == *element)
2736 p = NULL;
2737 break;
2739 else if (p->right)
2740 p = p->right;
2741 else
2743 while (1)
2745 p = _asn1_find_up (p);
2746 if (p == *element)
2748 p = NULL;
2749 break;
2751 if (p->right)
2753 p = p->right;
2754 break;
2760 return retCode;
2764 * asn1_expand_octet_string:
2765 * @definitions: ASN1 definitions
2766 * @element: pointer to an ASN1 structure
2767 * @octetName: name of the OCTECT STRING field to expand.
2768 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2769 * the type for expansion.
2771 * Expands an "OCTET STRING" element of a structure created from a DER
2772 * decoding process (the asn1_der_decoding() function). The type used
2773 * for expansion is the first one following the definition of the
2774 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2776 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2777 * if @objectName or @octetName are not correct,
2778 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2779 * use for expansion, or other errors depending on DER decoding.
2781 asn1_retCode
2782 asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
2783 const char *octetName, const char *objectName)
2785 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2786 asn1_retCode retCode = ASN1_SUCCESS, result;
2787 int len, len2, len3;
2788 ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
2789 ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
2790 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2792 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2793 return ASN1_ELEMENT_NOT_FOUND;
2795 octetNode = asn1_find_node (*element, octetName);
2796 if (octetNode == ASN1_TYPE_EMPTY)
2797 return ASN1_ELEMENT_NOT_FOUND;
2798 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2799 return ASN1_ELEMENT_NOT_FOUND;
2800 if (octetNode->value == NULL)
2801 return ASN1_VALUE_NOT_FOUND;
2803 objectNode = asn1_find_node (*element, objectName);
2804 if (objectNode == ASN1_TYPE_EMPTY)
2805 return ASN1_ELEMENT_NOT_FOUND;
2807 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2808 return ASN1_ELEMENT_NOT_FOUND;
2810 if (objectNode->value == NULL)
2811 return ASN1_VALUE_NOT_FOUND;
2814 /* search the OBJECT_ID into definitions */
2815 p2 = definitions->down;
2816 while (p2)
2818 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2819 (p2->type & CONST_ASSIGN))
2821 strcpy (name, definitions->name);
2822 strcat (name, ".");
2823 strcat (name, p2->name);
2825 len = sizeof (value);
2826 result = asn1_read_value (definitions, name, value, &len);
2828 if ((result == ASN1_SUCCESS)
2829 && (!_asn1_strcmp (objectNode->value, value)))
2832 p2 = p2->right; /* pointer to the structure to
2833 use for expansion */
2834 while ((p2) && (p2->type & CONST_ASSIGN))
2835 p2 = p2->right;
2837 if (p2)
2839 strcpy (name, definitions->name);
2840 strcat (name, ".");
2841 strcat (name, p2->name);
2843 result = asn1_create_element (definitions, name, &aux);
2844 if (result == ASN1_SUCCESS)
2846 _asn1_set_name (aux, octetNode->name);
2847 len2 =
2848 asn1_get_length_der (octetNode->value,
2849 octetNode->value_len, &len3);
2850 if (len2 < 0)
2851 return ASN1_DER_ERROR;
2853 result =
2854 asn1_der_decoding (&aux, octetNode->value + len3,
2855 len2, errorDescription);
2856 if (result == ASN1_SUCCESS)
2859 _asn1_set_right (aux, octetNode->right);
2860 _asn1_set_right (octetNode, aux);
2862 result = asn1_delete_structure (&octetNode);
2863 if (result == ASN1_SUCCESS)
2865 aux = ASN1_TYPE_EMPTY;
2866 break;
2868 else
2869 { /* error with asn1_delete_structure */
2870 asn1_delete_structure (&aux);
2871 retCode = result;
2872 break;
2875 else
2876 { /* error with asn1_der_decoding */
2877 retCode = result;
2878 break;
2881 else
2882 { /* error with asn1_create_element */
2883 retCode = result;
2884 break;
2887 else
2888 { /* error with the pointer to the structure to exapand */
2889 retCode = ASN1_VALUE_NOT_VALID;
2890 break;
2895 p2 = p2->right;
2899 if (!p2)
2900 retCode = ASN1_VALUE_NOT_VALID;
2902 return retCode;