updated minitasn1 to 2.14.
[gnutls.git] / lib / minitasn1 / decoding.c
blobe6cdb9850b9df06bd47a0adb214d4d4f55e0ecc7
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 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_TYPE node, const unsigned char *der, int der_len,
373 int *ret_len)
375 ASN1_TYPE 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_TYPE node)
572 ASN1_TYPE 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 asn1_retCode
629 _asn1_extract_der_octet (ASN1_TYPE 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 asn1_retCode
674 _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE 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 tot_len += len2;
733 ret = _asn1_extract_der_octet (node, der, *len);
734 if (ret != ASN1_SUCCESS)
735 return ret;
739 else
740 { /* NOT STRUCTURED */
741 len2 = asn1_get_length_der (der, *len, &len3);
742 if (len2 < 0)
743 return ASN1_DER_ERROR;
744 if (node)
745 _asn1_set_value (node, der, len3 + len2);
746 counter = len3 + len2;
749 *len = counter;
750 return ASN1_SUCCESS;
754 static asn1_retCode
755 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
757 int len2, len3, counter, indefinite;
758 unsigned long tag;
759 unsigned char class;
761 counter = indefinite = 0;
763 while (1)
765 if ((*len) < counter)
766 return ASN1_DER_ERROR;
768 if ((der[counter] == 0) && (der[counter + 1] == 0))
770 counter += 2;
771 indefinite--;
772 if (indefinite <= 0)
773 break;
774 else
775 continue;
778 if (asn1_get_tag_der
779 (der + counter, *len - counter, &class, &len2,
780 &tag) != ASN1_SUCCESS)
781 return ASN1_DER_ERROR;
782 if (counter + len2 > *len)
783 return ASN1_DER_ERROR;
784 counter += len2;
785 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
786 if (len2 < -1)
787 return ASN1_DER_ERROR;
788 if (len2 == -1)
790 indefinite++;
791 counter += 1;
793 else
795 counter += len2 + len3;
799 *len = counter;
800 return ASN1_SUCCESS;
805 * asn1_der_decoding:
806 * @element: pointer to an ASN1 structure.
807 * @ider: vector that contains the DER encoding.
808 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
809 * @errorDescription: null-terminated string contains details when an
810 * error occurred.
812 * Fill the structure *@ELEMENT with values of a DER encoding
813 * string. The structure must just be created with function
814 * asn1_create_element(). If an error occurs during the decoding
815 * procedure, the *@ELEMENT is deleted and set equal to
816 * %ASN1_TYPE_EMPTY.
818 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
819 * if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
820 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
821 * name (*@ELEMENT deleted).
823 asn1_retCode
824 asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
825 char *errorDescription)
827 ASN1_TYPE node, p, p2, p3;
828 char temp[128];
829 int counter, len2, len3, len4, move, ris, tlen;
830 unsigned char class;
831 unsigned long tag;
832 int indefinite, result;
833 const unsigned char *der = ider;
835 node = *element;
837 if (node == ASN1_TYPE_EMPTY)
838 return ASN1_ELEMENT_NOT_FOUND;
840 if (node->type & CONST_OPTION)
842 result = ASN1_GENERIC_ERROR;
843 goto cleanup;
846 counter = 0;
847 move = DOWN;
848 p = node;
849 while (1)
851 ris = ASN1_SUCCESS;
852 if (move != UP)
854 if (p->type & CONST_SET)
856 p2 = _asn1_find_up (p);
857 len2 = _asn1_strtol (p2->value, NULL, 10);
858 if (len2 == -1)
860 if (!der[counter] && !der[counter + 1])
862 p = p2;
863 move = UP;
864 counter += 2;
865 continue;
868 else if (counter == len2)
870 p = p2;
871 move = UP;
872 continue;
874 else if (counter > len2)
876 result = ASN1_DER_ERROR;
877 goto cleanup;
879 p2 = p2->down;
880 while (p2)
882 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
884 if (type_field (p2->type) != TYPE_CHOICE)
885 ris =
886 _asn1_extract_tag_der (p2, der + counter,
887 len - counter, &len2);
888 else
890 p3 = p2->down;
891 while (p3)
893 ris =
894 _asn1_extract_tag_der (p3, der + counter,
895 len - counter, &len2);
896 if (ris == ASN1_SUCCESS)
897 break;
898 p3 = p3->right;
901 if (ris == ASN1_SUCCESS)
903 p2->type &= ~CONST_NOT_USED;
904 p = p2;
905 break;
908 p2 = p2->right;
910 if (p2 == NULL)
912 result = ASN1_DER_ERROR;
913 goto cleanup;
917 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
919 p2 = _asn1_find_up (p);
920 len2 = _asn1_strtol (p2->value, NULL, 10);
921 if (counter == len2)
923 if (p->right)
925 p2 = p->right;
926 move = RIGHT;
928 else
929 move = UP;
931 if (p->type & CONST_OPTION)
932 asn1_delete_structure (&p);
934 p = p2;
935 continue;
939 if (type_field (p->type) == TYPE_CHOICE)
941 while (p->down)
943 if (counter < len)
944 ris =
945 _asn1_extract_tag_der (p->down, der + counter,
946 len - counter, &len2);
947 else
948 ris = ASN1_DER_ERROR;
949 if (ris == ASN1_SUCCESS)
951 while (p->down->right)
953 p2 = p->down->right;
954 asn1_delete_structure (&p2);
956 break;
958 else if (ris == ASN1_ERROR_TYPE_ANY)
960 result = ASN1_ERROR_TYPE_ANY;
961 goto cleanup;
963 else
965 p2 = p->down;
966 asn1_delete_structure (&p2);
970 if (p->down == NULL)
972 if (!(p->type & CONST_OPTION))
974 result = ASN1_DER_ERROR;
975 goto cleanup;
978 else
979 p = p->down;
982 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
984 p2 = _asn1_find_up (p);
985 len2 = _asn1_strtol (p2->value, NULL, 10);
986 if ((len2 != -1) && (counter > len2))
987 ris = ASN1_TAG_ERROR;
990 if (ris == ASN1_SUCCESS)
991 ris =
992 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
993 if (ris != ASN1_SUCCESS)
995 if (p->type & CONST_OPTION)
997 p->type |= CONST_NOT_USED;
998 move = RIGHT;
1000 else if (p->type & CONST_DEFAULT)
1002 _asn1_set_value (p, NULL, 0);
1003 move = RIGHT;
1005 else
1007 if (errorDescription != NULL)
1008 _asn1_error_description_tag_error (p, errorDescription);
1010 result = ASN1_TAG_ERROR;
1011 goto cleanup;
1014 else
1015 counter += len2;
1018 if (ris == ASN1_SUCCESS)
1020 switch (type_field (p->type))
1022 case TYPE_NULL:
1023 if (der[counter])
1025 result = ASN1_DER_ERROR;
1026 goto cleanup;
1028 counter++;
1029 move = RIGHT;
1030 break;
1031 case TYPE_BOOLEAN:
1032 if (der[counter++] != 1)
1034 result = ASN1_DER_ERROR;
1035 goto cleanup;
1037 if (der[counter++] == 0)
1038 _asn1_set_value (p, "F", 1);
1039 else
1040 _asn1_set_value (p, "T", 1);
1041 move = RIGHT;
1042 break;
1043 case TYPE_INTEGER:
1044 case TYPE_ENUMERATED:
1045 len2 =
1046 asn1_get_length_der (der + counter, len - counter, &len3);
1047 if (len2 < 0)
1049 result = ASN1_DER_ERROR;
1050 goto cleanup;
1053 _asn1_set_value (p, der + counter, len3 + len2);
1054 counter += len3 + len2;
1055 move = RIGHT;
1056 break;
1057 case TYPE_OBJECT_ID:
1058 result =
1059 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1060 temp, sizeof (temp));
1061 if (result != ASN1_SUCCESS)
1062 goto cleanup;
1064 tlen = strlen (temp);
1065 if (tlen > 0)
1066 _asn1_set_value (p, temp, tlen + 1);
1067 counter += len2;
1068 move = RIGHT;
1069 break;
1070 case TYPE_TIME:
1071 result =
1072 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1073 sizeof (temp) - 1);
1074 if (result != ASN1_SUCCESS)
1075 goto cleanup;
1077 tlen = strlen (temp);
1078 if (tlen > 0)
1079 _asn1_set_value (p, temp, tlen + 1);
1080 counter += len2;
1081 move = RIGHT;
1082 break;
1083 case TYPE_OCTET_STRING:
1084 len3 = len - counter;
1085 result = _asn1_get_octet_string (der + counter, p, &len3);
1086 if (result != ASN1_SUCCESS)
1087 goto cleanup;
1089 counter += len3;
1090 move = RIGHT;
1091 break;
1092 case TYPE_GENERALSTRING:
1093 len2 =
1094 asn1_get_length_der (der + counter, len - counter, &len3);
1095 if (len2 < 0)
1097 result = ASN1_DER_ERROR;
1098 goto cleanup;
1101 _asn1_set_value (p, der + counter, len3 + len2);
1102 counter += len3 + len2;
1103 move = RIGHT;
1104 break;
1105 case TYPE_BIT_STRING:
1106 len2 =
1107 asn1_get_length_der (der + counter, len - counter, &len3);
1108 if (len2 < 0)
1110 result = ASN1_DER_ERROR;
1111 goto cleanup;
1114 _asn1_set_value (p, der + counter, len3 + len2);
1115 counter += len3 + len2;
1116 move = RIGHT;
1117 break;
1118 case TYPE_SEQUENCE:
1119 case TYPE_SET:
1120 if (move == UP)
1122 len2 = _asn1_strtol (p->value, NULL, 10);
1123 _asn1_set_value (p, NULL, 0);
1124 if (len2 == -1)
1125 { /* indefinite length method */
1126 if (len - counter + 1 > 0)
1128 if ((der[counter]) || der[counter + 1])
1130 result = ASN1_DER_ERROR;
1131 goto cleanup;
1134 else
1136 result = ASN1_DER_ERROR;
1137 goto cleanup;
1139 counter += 2;
1141 else
1142 { /* definite length method */
1143 if (len2 != counter)
1145 result = ASN1_DER_ERROR;
1146 goto cleanup;
1149 move = RIGHT;
1151 else
1152 { /* move==DOWN || move==RIGHT */
1153 len3 =
1154 asn1_get_length_der (der + counter, len - counter, &len2);
1155 if (len3 < -1)
1157 result = ASN1_DER_ERROR;
1158 goto cleanup;
1160 counter += len2;
1161 if (len3 > 0)
1163 _asn1_ltostr (counter + len3, temp);
1164 tlen = strlen (temp);
1165 if (tlen > 0)
1166 _asn1_set_value (p, temp, tlen + 1);
1167 move = DOWN;
1169 else if (len3 == 0)
1171 p2 = p->down;
1172 while (p2)
1174 if (type_field (p2->type) != TYPE_TAG)
1176 p3 = p2->right;
1177 asn1_delete_structure (&p2);
1178 p2 = p3;
1180 else
1181 p2 = p2->right;
1183 move = RIGHT;
1185 else
1186 { /* indefinite length method */
1187 _asn1_set_value (p, "-1", 3);
1188 move = DOWN;
1191 break;
1192 case TYPE_SEQUENCE_OF:
1193 case TYPE_SET_OF:
1194 if (move == UP)
1196 len2 = _asn1_strtol (p->value, NULL, 10);
1197 if (len2 == -1)
1198 { /* indefinite length method */
1199 if ((counter + 2) > len)
1201 result = ASN1_DER_ERROR;
1202 goto cleanup;
1205 if ((der[counter]) || der[counter + 1])
1207 _asn1_append_sequence_set (p);
1208 p = p->down;
1209 while (p->right)
1210 p = p->right;
1211 move = RIGHT;
1212 continue;
1214 _asn1_set_value (p, NULL, 0);
1215 counter += 2;
1217 else
1218 { /* definite length method */
1219 if (len2 > counter)
1221 _asn1_append_sequence_set (p);
1222 p = p->down;
1223 while (p->right)
1224 p = p->right;
1225 move = RIGHT;
1226 continue;
1228 _asn1_set_value (p, NULL, 0);
1229 if (len2 != counter)
1231 result = ASN1_DER_ERROR;
1232 goto cleanup;
1236 else
1237 { /* move==DOWN || move==RIGHT */
1238 len3 =
1239 asn1_get_length_der (der + counter, len - counter, &len2);
1240 if (len3 < -1)
1242 result = ASN1_DER_ERROR;
1243 goto cleanup;
1245 counter += len2;
1246 if (len3)
1248 if (len3 > 0)
1249 { /* definite length method */
1250 _asn1_ltostr (counter + len3, temp);
1251 tlen = strlen (temp);
1253 if (tlen > 0)
1254 _asn1_set_value (p, temp, tlen + 1);
1256 else
1257 { /* indefinite length method */
1258 _asn1_set_value (p, "-1", 3);
1260 p2 = p->down;
1261 while ((type_field (p2->type) == TYPE_TAG)
1262 || (type_field (p2->type) == TYPE_SIZE))
1263 p2 = p2->right;
1264 if (p2->right == NULL)
1265 _asn1_append_sequence_set (p);
1266 p = p2;
1269 move = RIGHT;
1270 break;
1271 case TYPE_ANY:
1272 if (asn1_get_tag_der
1273 (der + counter, len - counter, &class, &len2,
1274 &tag) != ASN1_SUCCESS)
1276 result = ASN1_DER_ERROR;
1277 goto cleanup;
1280 if (counter + len2 > len)
1282 result = ASN1_DER_ERROR;
1283 goto cleanup;
1285 len4 =
1286 asn1_get_length_der (der + counter + len2,
1287 len - counter - len2, &len3);
1288 if (len4 < -1)
1290 result = ASN1_DER_ERROR;
1291 goto cleanup;
1293 if (len4 != -1)
1295 len2 += len4;
1296 _asn1_set_value_octet (p, der + counter, len2 + len3);
1297 counter += len2 + len3;
1299 else
1300 { /* indefinite length */
1301 /* Check indefinite lenth method in an EXPLICIT TAG */
1302 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1303 indefinite = 1;
1304 else
1305 indefinite = 0;
1307 len2 = len - counter;
1308 result =
1309 _asn1_get_indefinite_length_string (der + counter, &len2);
1310 if (result != ASN1_SUCCESS)
1311 goto cleanup;
1313 _asn1_set_value_octet (p, der + counter, len2);
1314 counter += len2;
1316 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1317 an indefinite length method. */
1318 if (indefinite)
1320 if (!der[counter] && !der[counter + 1])
1322 counter += 2;
1324 else
1326 result = ASN1_DER_ERROR;
1327 goto cleanup;
1331 move = RIGHT;
1332 break;
1333 default:
1334 move = (move == UP) ? RIGHT : DOWN;
1335 break;
1339 if (p == node && move != DOWN)
1340 break;
1342 if (move == DOWN)
1344 if (p->down)
1345 p = p->down;
1346 else
1347 move = RIGHT;
1349 if ((move == RIGHT) && !(p->type & CONST_SET))
1351 if (p->right)
1352 p = p->right;
1353 else
1354 move = UP;
1356 if (move == UP)
1357 p = _asn1_find_up (p);
1360 _asn1_delete_not_used (*element);
1362 if (counter != len)
1364 result = ASN1_DER_ERROR;
1365 goto cleanup;
1368 return ASN1_SUCCESS;
1370 cleanup:
1371 asn1_delete_structure (element);
1372 return result;
1375 #define FOUND 1
1376 #define SAME_BRANCH 2
1377 #define OTHER_BRANCH 3
1378 #define EXIT 4
1381 * asn1_der_decoding_element:
1382 * @structure: pointer to an ASN1 structure
1383 * @elementName: name of the element to fill
1384 * @ider: vector that contains the DER encoding of the whole structure.
1385 * @len: number of bytes of *der: der[0]..der[len-1]
1386 * @errorDescription: null-terminated string contains details when an
1387 * error occurred.
1389 * Fill the element named @ELEMENTNAME with values of a DER encoding
1390 * string. The structure must just be created with function
1391 * asn1_create_element(). The DER vector must contain the encoding
1392 * string of the whole @STRUCTURE. If an error occurs during the
1393 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1394 * %ASN1_TYPE_EMPTY.
1396 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1397 * if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
1398 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1399 * match the structure @structure (*ELEMENT deleted).
1401 asn1_retCode
1402 asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
1403 const void *ider, int len, char *errorDescription)
1405 ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
1406 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1407 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1408 int counter, len2, len3, len4, move, ris, tlen;
1409 unsigned char class;
1410 unsigned long tag;
1411 int indefinite, result;
1412 const unsigned char *der = ider;
1414 node = *structure;
1416 if (node == ASN1_TYPE_EMPTY)
1417 return ASN1_ELEMENT_NOT_FOUND;
1419 if (elementName == NULL)
1421 result = ASN1_ELEMENT_NOT_FOUND;
1422 goto cleanup;
1425 if (node->type & CONST_OPTION)
1427 result = ASN1_GENERIC_ERROR;
1428 goto cleanup;
1431 if ((*structure)->name)
1432 { /* Has *structure got a name? */
1433 nameLen -= strlen ((*structure)->name);
1434 if (nameLen > 0)
1435 strcpy (currentName, (*structure)->name);
1436 else
1438 result = ASN1_MEM_ERROR;
1439 goto cleanup;
1441 if (!(strcmp (currentName, elementName)))
1443 state = FOUND;
1444 nodeFound = *structure;
1446 else if (!memcmp (currentName, elementName, strlen (currentName)))
1447 state = SAME_BRANCH;
1448 else
1449 state = OTHER_BRANCH;
1451 else
1452 { /* *structure doesn't have a name? */
1453 currentName[0] = 0;
1454 if (elementName[0] == 0)
1456 state = FOUND;
1457 nodeFound = *structure;
1459 else
1461 state = SAME_BRANCH;
1465 counter = 0;
1466 move = DOWN;
1467 p = node;
1468 while (1)
1471 ris = ASN1_SUCCESS;
1473 if (move != UP)
1475 if (p->type & CONST_SET)
1477 p2 = _asn1_find_up (p);
1478 len2 = _asn1_strtol (p2->value, NULL, 10);
1479 if (counter == len2)
1481 p = p2;
1482 move = UP;
1483 continue;
1485 else if (counter > len2)
1487 result = ASN1_DER_ERROR;
1488 goto cleanup;
1490 p2 = p2->down;
1491 while (p2)
1493 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1495 if (type_field (p2->type) != TYPE_CHOICE)
1496 ris =
1497 _asn1_extract_tag_der (p2, der + counter,
1498 len - counter, &len2);
1499 else
1501 p3 = p2->down;
1502 while (p3)
1504 ris =
1505 _asn1_extract_tag_der (p3, der + counter,
1506 len - counter, &len2);
1507 if (ris == ASN1_SUCCESS)
1508 break;
1509 p3 = p3->right;
1512 if (ris == ASN1_SUCCESS)
1514 p2->type &= ~CONST_NOT_USED;
1515 p = p2;
1516 break;
1519 p2 = p2->right;
1521 if (p2 == NULL)
1523 result = ASN1_DER_ERROR;
1524 goto cleanup;
1528 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1530 p2 = _asn1_find_up (p);
1531 len2 = _asn1_strtol (p2->value, NULL, 10);
1532 if (counter == len2)
1534 if (p->right)
1536 p2 = p->right;
1537 move = RIGHT;
1539 else
1540 move = UP;
1542 if (p->type & CONST_OPTION)
1543 asn1_delete_structure (&p);
1545 p = p2;
1546 continue;
1550 if (type_field (p->type) == TYPE_CHOICE)
1552 while (p->down)
1554 if (counter < len)
1555 ris =
1556 _asn1_extract_tag_der (p->down, der + counter,
1557 len - counter, &len2);
1558 else
1559 ris = ASN1_DER_ERROR;
1560 if (ris == ASN1_SUCCESS)
1562 while (p->down->right)
1564 p2 = p->down->right;
1565 asn1_delete_structure (&p2);
1567 break;
1569 else if (ris == ASN1_ERROR_TYPE_ANY)
1571 result = ASN1_ERROR_TYPE_ANY;
1572 goto cleanup;
1574 else
1576 p2 = p->down;
1577 asn1_delete_structure (&p2);
1581 if (p->down == NULL)
1583 if (!(p->type & CONST_OPTION))
1585 result = ASN1_DER_ERROR;
1586 goto cleanup;
1589 else
1590 p = p->down;
1593 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1595 p2 = _asn1_find_up (p);
1596 len2 = _asn1_strtol (p2->value, NULL, 10);
1597 if (counter > len2)
1598 ris = ASN1_TAG_ERROR;
1601 if (ris == ASN1_SUCCESS)
1602 ris =
1603 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1604 if (ris != ASN1_SUCCESS)
1606 if (p->type & CONST_OPTION)
1608 p->type |= CONST_NOT_USED;
1609 move = RIGHT;
1611 else if (p->type & CONST_DEFAULT)
1613 _asn1_set_value (p, NULL, 0);
1614 move = RIGHT;
1616 else
1618 if (errorDescription != NULL)
1619 _asn1_error_description_tag_error (p, errorDescription);
1621 result = ASN1_TAG_ERROR;
1622 goto cleanup;
1625 else
1626 counter += len2;
1629 if (ris == ASN1_SUCCESS)
1631 switch (type_field (p->type))
1633 case TYPE_NULL:
1634 if (der[counter])
1636 result = ASN1_DER_ERROR;
1637 goto cleanup;
1640 if (p == nodeFound)
1641 state = EXIT;
1643 counter++;
1644 move = RIGHT;
1645 break;
1646 case TYPE_BOOLEAN:
1647 if (der[counter++] != 1)
1649 result = ASN1_DER_ERROR;
1650 goto cleanup;
1653 if (state == FOUND)
1655 if (der[counter++] == 0)
1656 _asn1_set_value (p, "F", 1);
1657 else
1658 _asn1_set_value (p, "T", 1);
1660 if (p == nodeFound)
1661 state = EXIT;
1664 else
1665 counter++;
1667 move = RIGHT;
1668 break;
1669 case TYPE_INTEGER:
1670 case TYPE_ENUMERATED:
1671 len2 =
1672 asn1_get_length_der (der + counter, len - counter, &len3);
1673 if (len2 < 0)
1675 result = ASN1_DER_ERROR;
1676 goto cleanup;
1679 if (state == FOUND)
1681 if (len3 + len2 > len - counter)
1683 result = ASN1_DER_ERROR;
1684 goto cleanup;
1686 _asn1_set_value (p, der + counter, len3 + len2);
1688 if (p == nodeFound)
1689 state = EXIT;
1691 counter += len3 + len2;
1692 move = RIGHT;
1693 break;
1694 case TYPE_OBJECT_ID:
1695 if (state == FOUND)
1697 result =
1698 _asn1_get_objectid_der (der + counter, len - counter,
1699 &len2, temp, sizeof (temp));
1700 if (result != ASN1_SUCCESS)
1701 goto cleanup;
1703 tlen = strlen (temp);
1705 if (tlen > 0)
1706 _asn1_set_value (p, temp, tlen + 1);
1708 if (p == nodeFound)
1709 state = EXIT;
1711 else
1713 len2 =
1714 asn1_get_length_der (der + counter, len - counter, &len3);
1715 if (len2 < 0)
1717 result = ASN1_DER_ERROR;
1718 goto cleanup;
1720 len2 += len3;
1723 counter += len2;
1724 move = RIGHT;
1725 break;
1726 case TYPE_TIME:
1727 if (state == FOUND)
1729 result =
1730 _asn1_get_time_der (der + counter, len - counter, &len2,
1731 temp, sizeof (temp) - 1);
1732 if (result != ASN1_SUCCESS)
1733 goto cleanup;
1735 tlen = strlen (temp);
1736 if (tlen > 0)
1737 _asn1_set_value (p, temp, tlen + 1);
1739 if (p == nodeFound)
1740 state = EXIT;
1742 else
1744 len2 =
1745 asn1_get_length_der (der + counter, len - counter, &len3);
1746 if (len2 < 0)
1748 result = ASN1_DER_ERROR;
1749 goto cleanup;
1751 len2 += len3;
1754 counter += len2;
1755 move = RIGHT;
1756 break;
1757 case TYPE_OCTET_STRING:
1758 len3 = len - counter;
1759 if (state == FOUND)
1761 result = _asn1_get_octet_string (der + counter, p, &len3);
1762 if (p == nodeFound)
1763 state = EXIT;
1765 else
1766 result = _asn1_get_octet_string (der + counter, NULL, &len3);
1768 if (result != ASN1_SUCCESS)
1769 goto cleanup;
1771 counter += len3;
1772 move = RIGHT;
1773 break;
1774 case TYPE_GENERALSTRING:
1775 len2 =
1776 asn1_get_length_der (der + counter, len - counter, &len3);
1777 if (len2 < 0)
1779 result = ASN1_DER_ERROR;
1780 goto cleanup;
1783 if (state == FOUND)
1785 if (len3 + len2 > len - counter)
1787 result = ASN1_DER_ERROR;
1788 goto cleanup;
1790 _asn1_set_value (p, der + counter, len3 + len2);
1792 if (p == nodeFound)
1793 state = EXIT;
1795 counter += len3 + len2;
1796 move = RIGHT;
1797 break;
1798 case TYPE_BIT_STRING:
1799 len2 =
1800 asn1_get_length_der (der + counter, len - counter, &len3);
1801 if (len2 < 0)
1803 result = ASN1_DER_ERROR;
1804 goto cleanup;
1806 if (state == FOUND)
1808 if (len3 + len2 > len - counter)
1810 result = ASN1_DER_ERROR;
1811 goto cleanup;
1813 _asn1_set_value (p, der + counter, len3 + len2);
1815 if (p == nodeFound)
1816 state = EXIT;
1818 counter += len3 + len2;
1819 move = RIGHT;
1820 break;
1821 case TYPE_SEQUENCE:
1822 case TYPE_SET:
1823 if (move == UP)
1825 len2 = _asn1_strtol (p->value, NULL, 10);
1826 _asn1_set_value (p, NULL, 0);
1827 if (len2 == -1)
1828 { /* indefinite length method */
1829 if ((der[counter]) || der[counter + 1])
1831 result = ASN1_DER_ERROR;
1832 goto cleanup;
1834 counter += 2;
1836 else
1837 { /* definite length method */
1838 if (len2 != counter)
1840 result = ASN1_DER_ERROR;
1841 goto cleanup;
1844 if (p == nodeFound)
1845 state = EXIT;
1846 move = RIGHT;
1848 else
1849 { /* move==DOWN || move==RIGHT */
1850 if (state == OTHER_BRANCH)
1852 len3 =
1853 asn1_get_length_der (der + counter, len - counter,
1854 &len2);
1855 if (len3 < 0)
1857 result = ASN1_DER_ERROR;
1858 goto cleanup;
1860 counter += len2 + len3;
1861 move = RIGHT;
1863 else
1864 { /* state==SAME_BRANCH or state==FOUND */
1865 len3 =
1866 asn1_get_length_der (der + counter, len - counter,
1867 &len2);
1868 if (len3 < 0)
1870 result = ASN1_DER_ERROR;
1871 goto cleanup;
1873 counter += len2;
1874 if (len3 > 0)
1876 _asn1_ltostr (counter + len3, temp);
1877 tlen = strlen (temp);
1879 if (tlen > 0)
1880 _asn1_set_value (p, temp, tlen + 1);
1881 move = DOWN;
1883 else if (len3 == 0)
1885 p2 = p->down;
1886 while (p2)
1888 if (type_field (p2->type) != TYPE_TAG)
1890 p3 = p2->right;
1891 asn1_delete_structure (&p2);
1892 p2 = p3;
1894 else
1895 p2 = p2->right;
1897 move = RIGHT;
1899 else
1900 { /* indefinite length method */
1901 _asn1_set_value (p, "-1", 3);
1902 move = DOWN;
1906 break;
1907 case TYPE_SEQUENCE_OF:
1908 case TYPE_SET_OF:
1909 if (move == UP)
1911 len2 = _asn1_strtol (p->value, NULL, 10);
1912 if (len2 > counter)
1914 _asn1_append_sequence_set (p);
1915 p = p->down;
1916 while (p->right)
1917 p = p->right;
1918 move = RIGHT;
1919 continue;
1921 _asn1_set_value (p, NULL, 0);
1922 if (len2 != counter)
1924 result = ASN1_DER_ERROR;
1925 goto cleanup;
1928 if (p == nodeFound)
1929 state = EXIT;
1931 else
1932 { /* move==DOWN || move==RIGHT */
1933 if (state == OTHER_BRANCH)
1935 len3 =
1936 asn1_get_length_der (der + counter, len - counter,
1937 &len2);
1938 if (len3 < 0)
1940 result = ASN1_DER_ERROR;
1941 goto cleanup;
1943 counter += len2 + len3;
1944 move = RIGHT;
1946 else
1947 { /* state==FOUND or state==SAME_BRANCH */
1948 len3 =
1949 asn1_get_length_der (der + counter, len - counter,
1950 &len2);
1951 if (len3 < 0)
1953 result = ASN1_DER_ERROR;
1954 goto cleanup;
1956 counter += len2;
1957 if (len3)
1959 _asn1_ltostr (counter + len3, temp);
1960 tlen = strlen (temp);
1962 if (tlen > 0)
1963 _asn1_set_value (p, temp, tlen + 1);
1964 p2 = p->down;
1965 while ((type_field (p2->type) == TYPE_TAG)
1966 || (type_field (p2->type) == TYPE_SIZE))
1967 p2 = p2->right;
1968 if (p2->right == NULL)
1969 _asn1_append_sequence_set (p);
1970 p = p2;
1971 state = FOUND;
1976 break;
1977 case TYPE_ANY:
1978 if (asn1_get_tag_der
1979 (der + counter, len - counter, &class, &len2,
1980 &tag) != ASN1_SUCCESS)
1982 result = ASN1_DER_ERROR;
1983 goto cleanup;
1986 if (counter + len2 > len)
1988 result = ASN1_DER_ERROR;
1989 goto cleanup;
1992 len4 =
1993 asn1_get_length_der (der + counter + len2,
1994 len - counter - len2, &len3);
1995 if (len4 < -1)
1997 result = ASN1_DER_ERROR;
1998 goto cleanup;
2001 if (len4 != -1)
2003 len2 += len4;
2004 if (state == FOUND)
2006 _asn1_set_value_octet (p, der + counter, len2 + len3);
2008 if (p == nodeFound)
2009 state = EXIT;
2011 counter += len2 + len3;
2013 else
2014 { /* indefinite length */
2015 /* Check indefinite lenth method in an EXPLICIT TAG */
2016 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2017 indefinite = 1;
2018 else
2019 indefinite = 0;
2021 len2 = len - counter;
2022 result =
2023 _asn1_get_indefinite_length_string (der + counter, &len2);
2024 if (result != ASN1_SUCCESS)
2025 goto cleanup;
2027 if (state == FOUND)
2029 _asn1_set_value_octet (p, der + counter, len2);
2031 if (p == nodeFound)
2032 state = EXIT;
2035 counter += len2;
2037 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2038 an indefinite length method. */
2039 if (indefinite)
2041 if (!der[counter] && !der[counter + 1])
2043 counter += 2;
2045 else
2047 result = ASN1_DER_ERROR;
2048 goto cleanup;
2052 move = RIGHT;
2053 break;
2055 default:
2056 move = (move == UP) ? RIGHT : DOWN;
2057 break;
2061 if ((p == node && move != DOWN) || (state == EXIT))
2062 break;
2064 if (move == DOWN)
2066 if (p->down)
2068 p = p->down;
2070 if (state != FOUND)
2072 nameLen -= strlen (p->name) + 1;
2073 if (nameLen > 0)
2075 if (currentName[0])
2076 strcat (currentName, ".");
2077 strcat (currentName, p->name);
2079 else
2081 result = ASN1_MEM_ERROR;
2082 goto cleanup;
2084 if (!(strcmp (currentName, elementName)))
2086 state = FOUND;
2087 nodeFound = p;
2089 else
2090 if (!memcmp
2091 (currentName, elementName, strlen (currentName)))
2092 state = SAME_BRANCH;
2093 else
2094 state = OTHER_BRANCH;
2097 else
2098 move = RIGHT;
2101 if ((move == RIGHT) && !(p->type & CONST_SET))
2103 if (p->right)
2105 p = p->right;
2107 if (state != FOUND)
2109 dot_p = char_p = currentName;
2110 while ((char_p = strchr (char_p, '.')))
2112 dot_p = char_p++;
2113 dot_p++;
2116 nameLen += strlen (currentName) - (dot_p - currentName);
2117 *dot_p = 0;
2119 nameLen -= strlen (p->name);
2120 if (nameLen > 0)
2121 strcat (currentName, p->name);
2122 else
2124 result = ASN1_MEM_ERROR;
2125 goto cleanup;
2128 if (!(strcmp (currentName, elementName)))
2130 state = FOUND;
2131 nodeFound = p;
2133 else
2134 if (!memcmp
2135 (currentName, elementName, strlen (currentName)))
2136 state = SAME_BRANCH;
2137 else
2138 state = OTHER_BRANCH;
2141 else
2142 move = UP;
2145 if (move == UP)
2147 p = _asn1_find_up (p);
2149 if (state != FOUND)
2151 dot_p = char_p = currentName;
2152 while ((char_p = strchr (char_p, '.')))
2154 dot_p = char_p++;
2155 dot_p++;
2158 nameLen += strlen (currentName) - (dot_p - currentName);
2159 *dot_p = 0;
2161 if (!(strcmp (currentName, elementName)))
2163 state = FOUND;
2164 nodeFound = p;
2166 else
2167 if (!memcmp (currentName, elementName, strlen (currentName)))
2168 state = SAME_BRANCH;
2169 else
2170 state = OTHER_BRANCH;
2175 _asn1_delete_not_used (*structure);
2177 if (counter > len)
2179 result = ASN1_DER_ERROR;
2180 goto cleanup;
2183 return ASN1_SUCCESS;
2185 cleanup:
2186 asn1_delete_structure (structure);
2187 return result;
2191 * asn1_der_decoding_startEnd:
2192 * @element: pointer to an ASN1 element
2193 * @ider: vector that contains the DER encoding.
2194 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2195 * @name_element: an element of NAME structure.
2196 * @start: the position of the first byte of NAME_ELEMENT decoding
2197 * (@ider[*start])
2198 * @end: the position of the last byte of NAME_ELEMENT decoding
2199 * (@ider[*end])
2201 * Find the start and end point of an element in a DER encoding
2202 * string. I mean that if you have a der encoding and you have already
2203 * used the function asn1_der_decoding() to fill a structure, it may
2204 * happen that you want to find the piece of string concerning an
2205 * element of the structure.
2207 * One example is the sequence "tbsCertificate" inside an X509
2208 * certificate.
2210 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2211 * if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
2212 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2213 * doesn't match the structure ELEMENT.
2215 asn1_retCode
2216 asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
2217 const char *name_element, int *start, int *end)
2219 ASN1_TYPE node, node_to_find, p, p2, p3;
2220 int counter, len2, len3, len4, move, ris;
2221 unsigned char class;
2222 unsigned long tag;
2223 int indefinite;
2224 const unsigned char *der = ider;
2226 node = element;
2228 if (node == ASN1_TYPE_EMPTY)
2229 return ASN1_ELEMENT_NOT_FOUND;
2231 node_to_find = asn1_find_node (node, name_element);
2233 if (node_to_find == NULL)
2234 return ASN1_ELEMENT_NOT_FOUND;
2236 if (node_to_find == node)
2238 *start = 0;
2239 *end = len - 1;
2240 return ASN1_SUCCESS;
2243 if (node->type & CONST_OPTION)
2244 return ASN1_GENERIC_ERROR;
2246 counter = 0;
2247 move = DOWN;
2248 p = node;
2249 while (1)
2251 ris = ASN1_SUCCESS;
2253 if (move != UP)
2255 if (p->type & CONST_SET)
2257 p2 = _asn1_find_up (p);
2258 len2 = _asn1_strtol (p2->value, NULL, 10);
2259 if (len2 == -1)
2261 if (!der[counter] && !der[counter + 1])
2263 p = p2;
2264 move = UP;
2265 counter += 2;
2266 continue;
2269 else if (counter == len2)
2271 p = p2;
2272 move = UP;
2273 continue;
2275 else if (counter > len2)
2276 return ASN1_DER_ERROR;
2277 p2 = p2->down;
2278 while (p2)
2280 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2281 { /* CONTROLLARE */
2282 if (type_field (p2->type) != TYPE_CHOICE)
2283 ris =
2284 _asn1_extract_tag_der (p2, der + counter,
2285 len - counter, &len2);
2286 else
2288 p3 = p2->down;
2289 ris =
2290 _asn1_extract_tag_der (p3, der + counter,
2291 len - counter, &len2);
2293 if (ris == ASN1_SUCCESS)
2295 p2->type &= ~CONST_NOT_USED;
2296 p = p2;
2297 break;
2300 p2 = p2->right;
2302 if (p2 == NULL)
2303 return ASN1_DER_ERROR;
2306 if (p == node_to_find)
2307 *start = counter;
2309 if (type_field (p->type) == TYPE_CHOICE)
2311 p = p->down;
2312 ris =
2313 _asn1_extract_tag_der (p, der + counter, len - counter,
2314 &len2);
2315 if (p == node_to_find)
2316 *start = counter;
2319 if (ris == ASN1_SUCCESS)
2320 ris =
2321 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2322 if (ris != ASN1_SUCCESS)
2324 if (p->type & CONST_OPTION)
2326 p->type |= CONST_NOT_USED;
2327 move = RIGHT;
2329 else if (p->type & CONST_DEFAULT)
2331 move = RIGHT;
2333 else
2335 return ASN1_TAG_ERROR;
2338 else
2339 counter += len2;
2342 if (ris == ASN1_SUCCESS)
2344 switch (type_field (p->type))
2346 case TYPE_NULL:
2347 if (der[counter])
2348 return ASN1_DER_ERROR;
2349 counter++;
2350 move = RIGHT;
2351 break;
2352 case TYPE_BOOLEAN:
2353 if (der[counter++] != 1)
2354 return ASN1_DER_ERROR;
2355 counter++;
2356 move = RIGHT;
2357 break;
2358 case TYPE_INTEGER:
2359 case TYPE_ENUMERATED:
2360 len2 =
2361 asn1_get_length_der (der + counter, len - counter, &len3);
2362 if (len2 < 0)
2363 return ASN1_DER_ERROR;
2364 counter += len3 + len2;
2365 move = RIGHT;
2366 break;
2367 case TYPE_OBJECT_ID:
2368 len2 =
2369 asn1_get_length_der (der + counter, len - counter, &len3);
2370 if (len2 < 0)
2371 return ASN1_DER_ERROR;
2372 counter += len2 + len3;
2373 move = RIGHT;
2374 break;
2375 case TYPE_TIME:
2376 len2 =
2377 asn1_get_length_der (der + counter, len - counter, &len3);
2378 if (len2 < 0)
2379 return ASN1_DER_ERROR;
2380 counter += len2 + len3;
2381 move = RIGHT;
2382 break;
2383 case TYPE_OCTET_STRING:
2384 len3 = len - counter;
2385 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2386 if (ris != ASN1_SUCCESS)
2387 return ris;
2388 counter += len3;
2389 move = RIGHT;
2390 break;
2391 case TYPE_GENERALSTRING:
2392 len2 =
2393 asn1_get_length_der (der + counter, len - counter, &len3);
2394 if (len2 < 0)
2395 return ASN1_DER_ERROR;
2396 counter += len3 + len2;
2397 move = RIGHT;
2398 break;
2399 case TYPE_BIT_STRING:
2400 len2 =
2401 asn1_get_length_der (der + counter, len - counter, &len3);
2402 if (len2 < 0)
2403 return ASN1_DER_ERROR;
2404 counter += len3 + len2;
2405 move = RIGHT;
2406 break;
2407 case TYPE_SEQUENCE:
2408 case TYPE_SET:
2409 if (move != UP)
2411 len3 =
2412 asn1_get_length_der (der + counter, len - counter, &len2);
2413 if (len3 < -1)
2414 return ASN1_DER_ERROR;
2415 counter += len2;
2416 if (len3 == 0)
2417 move = RIGHT;
2418 else
2419 move = DOWN;
2421 else
2423 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2424 counter += 2;
2425 move = RIGHT;
2427 break;
2428 case TYPE_SEQUENCE_OF:
2429 case TYPE_SET_OF:
2430 if (move != UP)
2432 len3 =
2433 asn1_get_length_der (der + counter, len - counter, &len2);
2434 if (len3 < -1)
2435 return ASN1_DER_ERROR;
2436 counter += len2;
2437 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2438 counter += 2;
2439 else if (len3)
2441 p2 = p->down;
2442 while ((type_field (p2->type) == TYPE_TAG) ||
2443 (type_field (p2->type) == TYPE_SIZE))
2444 p2 = p2->right;
2445 p = p2;
2448 else
2450 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2451 counter += 2;
2453 move = RIGHT;
2454 break;
2455 case TYPE_ANY:
2456 if (asn1_get_tag_der
2457 (der + counter, len - counter, &class, &len2,
2458 &tag) != ASN1_SUCCESS)
2459 return ASN1_DER_ERROR;
2460 if (counter + len2 > len)
2461 return ASN1_DER_ERROR;
2463 len4 =
2464 asn1_get_length_der (der + counter + len2,
2465 len - counter - len2, &len3);
2466 if (len4 < -1)
2467 return ASN1_DER_ERROR;
2469 if (len4 != -1)
2471 counter += len2 + len4 + len3;
2473 else
2474 { /* indefinite length */
2475 /* Check indefinite lenth method in an EXPLICIT TAG */
2476 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2477 indefinite = 1;
2478 else
2479 indefinite = 0;
2481 len2 = len - counter;
2482 ris =
2483 _asn1_get_indefinite_length_string (der + counter, &len2);
2484 if (ris != ASN1_SUCCESS)
2485 return ris;
2486 counter += len2;
2488 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2489 an indefinite length method. */
2490 if (indefinite)
2492 if (!der[counter] && !der[counter + 1])
2493 counter += 2;
2494 else
2495 return ASN1_DER_ERROR;
2498 move = RIGHT;
2499 break;
2500 default:
2501 move = (move == UP) ? RIGHT : DOWN;
2502 break;
2506 if ((p == node_to_find) && (move == RIGHT))
2508 *end = counter - 1;
2509 return ASN1_SUCCESS;
2512 if (p == node && move != DOWN)
2513 break;
2515 if (move == DOWN)
2517 if (p->down)
2518 p = p->down;
2519 else
2520 move = RIGHT;
2522 if ((move == RIGHT) && !(p->type & CONST_SET))
2524 if (p->right)
2525 p = p->right;
2526 else
2527 move = UP;
2529 if (move == UP)
2530 p = _asn1_find_up (p);
2533 return ASN1_ELEMENT_NOT_FOUND;
2537 * asn1_expand_any_defined_by:
2538 * @definitions: ASN1 definitions
2539 * @element: pointer to an ASN1 structure
2541 * Expands every "ANY DEFINED BY" element of a structure created from
2542 * a DER decoding process (asn1_der_decoding function). The element
2543 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2544 * expand the element ANY is the first one following the definition of
2545 * the actual value of the OBJECT IDENTIFIER.
2547 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2548 * some "ANY DEFINED BY" element couldn't be expanded due to a
2549 * problem in OBJECT_ID -> TYPE association, or other error codes
2550 * depending on DER decoding.
2552 asn1_retCode
2553 asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
2555 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2556 value[ASN1_MAX_NAME_SIZE];
2557 asn1_retCode retCode = ASN1_SUCCESS, result;
2558 int len, len2, len3;
2559 ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
2560 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2562 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2563 return ASN1_ELEMENT_NOT_FOUND;
2565 strcpy (definitionsName, definitions->name);
2566 strcat (definitionsName, ".");
2568 p = *element;
2569 while (p)
2572 switch (type_field (p->type))
2574 case TYPE_ANY:
2575 if ((p->type & CONST_DEFINED_BY) && (p->value))
2577 /* search the "DEF_BY" element */
2578 p2 = p->down;
2579 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2580 p2 = p2->right;
2582 if (!p2)
2584 retCode = ASN1_ERROR_TYPE_ANY;
2585 break;
2588 p3 = _asn1_find_up (p);
2590 if (!p3)
2592 retCode = ASN1_ERROR_TYPE_ANY;
2593 break;
2596 p3 = p3->down;
2597 while (p3)
2599 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2600 break;
2601 p3 = p3->right;
2604 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2605 (p3->value == NULL))
2608 p3 = _asn1_find_up (p);
2609 p3 = _asn1_find_up (p3);
2611 if (!p3)
2613 retCode = ASN1_ERROR_TYPE_ANY;
2614 break;
2617 p3 = p3->down;
2619 while (p3)
2621 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2622 break;
2623 p3 = p3->right;
2626 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2627 (p3->value == NULL))
2629 retCode = ASN1_ERROR_TYPE_ANY;
2630 break;
2634 /* search the OBJECT_ID into definitions */
2635 p2 = definitions->down;
2636 while (p2)
2638 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2639 (p2->type & CONST_ASSIGN))
2641 strcpy (name, definitionsName);
2642 strcat (name, p2->name);
2644 len = ASN1_MAX_NAME_SIZE;
2645 result =
2646 asn1_read_value (definitions, name, value, &len);
2648 if ((result == ASN1_SUCCESS)
2649 && (!_asn1_strcmp (p3->value, value)))
2651 p2 = p2->right; /* pointer to the structure to
2652 use for expansion */
2653 while ((p2) && (p2->type & CONST_ASSIGN))
2654 p2 = p2->right;
2656 if (p2)
2658 strcpy (name, definitionsName);
2659 strcat (name, p2->name);
2661 result =
2662 asn1_create_element (definitions, name, &aux);
2663 if (result == ASN1_SUCCESS)
2665 _asn1_set_name (aux, p->name);
2666 len2 =
2667 asn1_get_length_der (p->value,
2668 p->value_len, &len3);
2669 if (len2 < 0)
2670 return ASN1_DER_ERROR;
2672 result =
2673 asn1_der_decoding (&aux, p->value + len3,
2674 len2,
2675 errorDescription);
2676 if (result == ASN1_SUCCESS)
2679 _asn1_set_right (aux, p->right);
2680 _asn1_set_right (p, aux);
2682 result = asn1_delete_structure (&p);
2683 if (result == ASN1_SUCCESS)
2685 p = aux;
2686 aux = ASN1_TYPE_EMPTY;
2687 break;
2689 else
2690 { /* error with asn1_delete_structure */
2691 asn1_delete_structure (&aux);
2692 retCode = result;
2693 break;
2696 else
2697 { /* error with asn1_der_decoding */
2698 retCode = result;
2699 break;
2702 else
2703 { /* error with asn1_create_element */
2704 retCode = result;
2705 break;
2708 else
2709 { /* error with the pointer to the structure to exapand */
2710 retCode = ASN1_ERROR_TYPE_ANY;
2711 break;
2715 p2 = p2->right;
2716 } /* end while */
2718 if (!p2)
2720 retCode = ASN1_ERROR_TYPE_ANY;
2721 break;
2725 break;
2726 default:
2727 break;
2731 if (p->down)
2733 p = p->down;
2735 else if (p == *element)
2737 p = NULL;
2738 break;
2740 else if (p->right)
2741 p = p->right;
2742 else
2744 while (1)
2746 p = _asn1_find_up (p);
2747 if (p == *element)
2749 p = NULL;
2750 break;
2752 if (p->right)
2754 p = p->right;
2755 break;
2761 return retCode;
2765 * asn1_expand_octet_string:
2766 * @definitions: ASN1 definitions
2767 * @element: pointer to an ASN1 structure
2768 * @octetName: name of the OCTECT STRING field to expand.
2769 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2770 * the type for expansion.
2772 * Expands an "OCTET STRING" element of a structure created from a DER
2773 * decoding process (the asn1_der_decoding() function). The type used
2774 * for expansion is the first one following the definition of the
2775 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2777 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2778 * if @objectName or @octetName are not correct,
2779 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2780 * use for expansion, or other errors depending on DER decoding.
2782 asn1_retCode
2783 asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
2784 const char *octetName, const char *objectName)
2786 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2787 asn1_retCode retCode = ASN1_SUCCESS, result;
2788 int len, len2, len3;
2789 ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
2790 ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
2791 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2793 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2794 return ASN1_ELEMENT_NOT_FOUND;
2796 octetNode = asn1_find_node (*element, octetName);
2797 if (octetNode == ASN1_TYPE_EMPTY)
2798 return ASN1_ELEMENT_NOT_FOUND;
2799 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2800 return ASN1_ELEMENT_NOT_FOUND;
2801 if (octetNode->value == NULL)
2802 return ASN1_VALUE_NOT_FOUND;
2804 objectNode = asn1_find_node (*element, objectName);
2805 if (objectNode == ASN1_TYPE_EMPTY)
2806 return ASN1_ELEMENT_NOT_FOUND;
2808 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2809 return ASN1_ELEMENT_NOT_FOUND;
2811 if (objectNode->value == NULL)
2812 return ASN1_VALUE_NOT_FOUND;
2815 /* search the OBJECT_ID into definitions */
2816 p2 = definitions->down;
2817 while (p2)
2819 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2820 (p2->type & CONST_ASSIGN))
2822 strcpy (name, definitions->name);
2823 strcat (name, ".");
2824 strcat (name, p2->name);
2826 len = sizeof (value);
2827 result = asn1_read_value (definitions, name, value, &len);
2829 if ((result == ASN1_SUCCESS)
2830 && (!_asn1_strcmp (objectNode->value, value)))
2833 p2 = p2->right; /* pointer to the structure to
2834 use for expansion */
2835 while ((p2) && (p2->type & CONST_ASSIGN))
2836 p2 = p2->right;
2838 if (p2)
2840 strcpy (name, definitions->name);
2841 strcat (name, ".");
2842 strcat (name, p2->name);
2844 result = asn1_create_element (definitions, name, &aux);
2845 if (result == ASN1_SUCCESS)
2847 _asn1_set_name (aux, octetNode->name);
2848 len2 =
2849 asn1_get_length_der (octetNode->value,
2850 octetNode->value_len, &len3);
2851 if (len2 < 0)
2852 return ASN1_DER_ERROR;
2854 result =
2855 asn1_der_decoding (&aux, octetNode->value + len3,
2856 len2, errorDescription);
2857 if (result == ASN1_SUCCESS)
2860 _asn1_set_right (aux, octetNode->right);
2861 _asn1_set_right (octetNode, aux);
2863 result = asn1_delete_structure (&octetNode);
2864 if (result == ASN1_SUCCESS)
2866 aux = ASN1_TYPE_EMPTY;
2867 break;
2869 else
2870 { /* error with asn1_delete_structure */
2871 asn1_delete_structure (&aux);
2872 retCode = result;
2873 break;
2876 else
2877 { /* error with asn1_der_decoding */
2878 retCode = result;
2879 break;
2882 else
2883 { /* error with asn1_create_element */
2884 retCode = result;
2885 break;
2888 else
2889 { /* error with the pointer to the structure to exapand */
2890 retCode = ASN1_VALUE_NOT_VALID;
2891 break;
2896 p2 = p2->right;
2900 if (!p2)
2901 retCode = ASN1_VALUE_NOT_VALID;
2903 return retCode;