Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / lib / minitasn1 / decoding.c
blob8c8b01fd322cd2b83cd5be4515edf3b1702e3ed9
1 /*
2 * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
3 * Foundation, Inc.
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: decoding.c */
26 /* Description: Functions to manage DER decoding */
27 /*****************************************************/
29 #include <int.h>
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "structure.h"
33 #include "element.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.
59 **/
60 signed long
61 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
63 unsigned long ans;
64 int k, punt;
66 *len = 0;
67 if (der_len <= 0)
68 return 0;
70 if (!(der[0] & 128))
72 /* short form */
73 *len = 1;
74 return der[0];
76 else
78 /* Long form */
79 k = der[0] & 0x7F;
80 punt = 1;
81 if (k)
82 { /* definite length method */
83 ans = 0;
84 while (punt <= k && punt < der_len)
86 unsigned long last = ans;
88 ans = ans * 256 + der[punt++];
89 if (ans < last)
90 /* we wrapped around, no bignum support... */
91 return -2;
94 else
95 { /* indefinite length method */
96 ans = -1;
99 *len = punt;
100 return ans;
105 * asn1_get_tag_der:
106 * @der: DER data to decode.
107 * @der_len: Length of DER data to decode.
108 * @cls: Output variable containing decoded class.
109 * @len: Output variable containing the length of the DER TAG data.
110 * @tag: Output variable containing the decoded tag.
112 * Decode the class and TAG from DER code.
114 * Returns: Returns %ASN1_SUCCESS on success, or an error.
117 asn1_get_tag_der (const unsigned char *der, int der_len,
118 unsigned char *cls, int *len, unsigned long *tag)
120 int punt, ris;
122 if (der == NULL || der_len < 2 || len == NULL)
123 return ASN1_DER_ERROR;
125 *cls = der[0] & 0xE0;
126 if ((der[0] & 0x1F) != 0x1F)
128 /* short form */
129 *len = 1;
130 ris = der[0] & 0x1F;
132 else
134 /* Long form */
135 punt = 1;
136 ris = 0;
137 while (punt <= der_len && der[punt] & 128)
139 int last = ris;
140 ris = ris * 128 + (der[punt++] & 0x7F);
141 if (ris < last)
142 /* wrapper around, and no bignums... */
143 return ASN1_DER_ERROR;
145 if (punt >= der_len)
146 return ASN1_DER_ERROR;
148 int last = ris;
149 ris = ris * 128 + (der[punt++] & 0x7F);
150 if (ris < last)
151 /* wrapper around, and no bignums... */
152 return ASN1_DER_ERROR;
154 *len = punt;
156 if (tag)
157 *tag = ris;
158 return ASN1_SUCCESS;
162 * asn1_get_length_ber:
163 * @ber: BER data to decode.
164 * @ber_len: Length of BER data to decode.
165 * @len: Output variable containing the length of the BER length field.
167 * Extract a length field from BER data. The difference to
168 * asn1_get_length_der() is that this function will return a length
169 * even if the value has indefinite encoding.
171 * Returns: Return the decoded length value, or negative value when
172 * the value was too big.
174 * Since: 2.0
176 signed long
177 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
179 int ret;
180 long err;
182 ret = asn1_get_length_der (ber, ber_len, len);
183 if (ret == -1)
184 { /* indefinite length method */
185 ret = ber_len;
186 err = _asn1_get_indefinite_length_string (ber + 1, &ret);
187 if (err != ASN1_SUCCESS)
188 return -3;
191 return ret;
195 * asn1_get_octet_der:
196 * @der: DER data to decode containing the OCTET SEQUENCE.
197 * @der_len: Length of DER data to decode.
198 * @ret_len: Output variable containing the length of the DER data.
199 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
200 * @str_size: Length of pre-allocated output buffer.
201 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
203 * Extract an OCTET SEQUENCE from DER data.
205 * Returns: Returns %ASN1_SUCCESS on success, or an error.
208 asn1_get_octet_der (const unsigned char *der, int der_len,
209 int *ret_len, unsigned char *str, int str_size,
210 int *str_len)
212 int len_len;
214 if (der_len <= 0)
215 return ASN1_GENERIC_ERROR;
217 /* if(str==NULL) return ASN1_SUCCESS; */
218 *str_len = asn1_get_length_der (der, der_len, &len_len);
220 if (*str_len < 0)
221 return ASN1_DER_ERROR;
223 *ret_len = *str_len + len_len;
224 if (str_size >= *str_len)
225 memcpy (str, der + len_len, *str_len);
226 else
228 return ASN1_MEM_ERROR;
231 return ASN1_SUCCESS;
234 /* Returns ASN1_SUCCESS on success or an error code on error.
236 static int
237 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
238 char *str, int str_size)
240 int len_len, str_len;
242 if (der_len <= 0 || str == NULL)
243 return ASN1_DER_ERROR;
244 str_len = asn1_get_length_der (der, der_len, &len_len);
245 if (str_len < 0 || str_size < str_len)
246 return ASN1_DER_ERROR;
247 memcpy (str, der + len_len, str_len);
248 str[str_len] = 0;
249 *ret_len = str_len + len_len;
251 return ASN1_SUCCESS;
254 static int
255 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
256 char *str, int str_size)
258 int len_len, len, k;
259 int leading;
260 char temp[20];
261 unsigned long val, val1, prev_val;
263 *ret_len = 0;
264 if (str && str_size > 0)
265 str[0] = 0; /* no oid */
267 if (str == NULL || der_len <= 0)
268 return ASN1_GENERIC_ERROR;
269 len = asn1_get_length_der (der, der_len, &len_len);
271 if (len < 0 || len > der_len || len_len > der_len)
272 return ASN1_DER_ERROR;
274 val1 = der[len_len] / 40;
275 val = der[len_len] - val1 * 40;
277 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
278 _asn1_str_cat (str, str_size, ".");
279 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
281 prev_val = 0;
282 val = 0;
283 leading = 1;
284 for (k = 1; k < len; k++)
286 /* X.690 mandates that the leading byte must never be 0x80
288 if (leading != 0 && der[len_len + k] == 0x80)
289 return ASN1_DER_ERROR;
290 leading = 0;
292 /* check for wrap around */
293 val = val << 7;
294 val |= der[len_len + k] & 0x7F;
296 if (val < prev_val)
297 return ASN1_DER_ERROR;
299 prev_val = val;
301 if (!(der[len_len + k] & 0x80))
303 _asn1_str_cat (str, str_size, ".");
304 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
305 val = 0;
306 prev_val = 0;
307 leading = 1;
310 *ret_len = len + len_len;
312 return ASN1_SUCCESS;
316 * asn1_get_bit_der:
317 * @der: DER data to decode containing the BIT SEQUENCE.
318 * @der_len: Length of DER data to decode.
319 * @ret_len: Output variable containing the length of the DER data.
320 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
321 * @str_size: Length of pre-allocated output buffer.
322 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
324 * Extract a BIT SEQUENCE from DER data.
326 * Returns: Return %ASN1_SUCCESS on success, or an error.
329 asn1_get_bit_der (const unsigned char *der, int der_len,
330 int *ret_len, unsigned char *str, int str_size,
331 int *bit_len)
333 int len_len, len_byte;
335 if (der_len <= 0)
336 return ASN1_GENERIC_ERROR;
337 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
338 if (len_byte < 0)
339 return ASN1_DER_ERROR;
341 *ret_len = len_byte + len_len + 1;
342 *bit_len = len_byte * 8 - der[len_len];
344 if (str_size >= len_byte)
345 memcpy (str, der + len_len + 1, len_byte);
346 else
348 return ASN1_MEM_ERROR;
351 return ASN1_SUCCESS;
354 static int
355 _asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
356 int *ret_len)
358 ASN1_TYPE p;
359 int counter, len2, len3, is_tag_implicit;
360 unsigned long tag, tag_implicit = 0;
361 unsigned char class, class2, class_implicit = 0;
363 if (der_len <= 0)
364 return ASN1_GENERIC_ERROR;
366 counter = is_tag_implicit = 0;
368 if (node->type & CONST_TAG)
370 p = node->down;
371 while (p)
373 if (type_field (p->type) == TYPE_TAG)
375 if (p->type & CONST_APPLICATION)
376 class2 = ASN1_CLASS_APPLICATION;
377 else if (p->type & CONST_UNIVERSAL)
378 class2 = ASN1_CLASS_UNIVERSAL;
379 else if (p->type & CONST_PRIVATE)
380 class2 = ASN1_CLASS_PRIVATE;
381 else
382 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
384 if (p->type & CONST_EXPLICIT)
386 if (asn1_get_tag_der
387 (der + counter, der_len - counter, &class, &len2,
388 &tag) != ASN1_SUCCESS)
389 return ASN1_DER_ERROR;
391 if (counter + len2 > der_len)
392 return ASN1_DER_ERROR;
393 counter += len2;
395 len3 =
396 asn1_get_length_ber (der + counter, der_len - counter,
397 &len2);
398 if (len3 < 0)
399 return ASN1_DER_ERROR;
401 counter += len2;
402 if (counter > der_len)
403 return ASN1_DER_ERROR;
405 if (!is_tag_implicit)
407 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
408 (tag != strtoul ((char *) p->value, NULL, 10)))
409 return ASN1_TAG_ERROR;
411 else
412 { /* ASN1_TAG_IMPLICIT */
413 if ((class != class_implicit) || (tag != tag_implicit))
414 return ASN1_TAG_ERROR;
416 is_tag_implicit = 0;
418 else
419 { /* ASN1_TAG_IMPLICIT */
420 if (!is_tag_implicit)
422 if ((type_field (node->type) == TYPE_SEQUENCE) ||
423 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
424 (type_field (node->type) == TYPE_SET) ||
425 (type_field (node->type) == TYPE_SET_OF))
426 class2 |= ASN1_CLASS_STRUCTURED;
427 class_implicit = class2;
428 tag_implicit = strtoul ((char *) p->value, NULL, 10);
429 is_tag_implicit = 1;
433 p = p->right;
437 if (is_tag_implicit)
439 if (asn1_get_tag_der
440 (der + counter, der_len - counter, &class, &len2,
441 &tag) != ASN1_SUCCESS)
442 return ASN1_DER_ERROR;
443 if (counter + len2 > der_len)
444 return ASN1_DER_ERROR;
446 if ((class != class_implicit) || (tag != tag_implicit))
448 if (type_field (node->type) == TYPE_OCTET_STRING)
450 class_implicit |= ASN1_CLASS_STRUCTURED;
451 if ((class != class_implicit) || (tag != tag_implicit))
452 return ASN1_TAG_ERROR;
454 else
455 return ASN1_TAG_ERROR;
458 else
460 if (type_field (node->type) == TYPE_TAG)
462 counter = 0;
463 *ret_len = counter;
464 return ASN1_SUCCESS;
467 if (asn1_get_tag_der
468 (der + counter, der_len - counter, &class, &len2,
469 &tag) != ASN1_SUCCESS)
470 return ASN1_DER_ERROR;
472 if (counter + len2 > der_len)
473 return ASN1_DER_ERROR;
475 switch (type_field (node->type))
477 case TYPE_NULL:
478 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
479 return ASN1_DER_ERROR;
480 break;
481 case TYPE_BOOLEAN:
482 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
483 return ASN1_DER_ERROR;
484 break;
485 case TYPE_INTEGER:
486 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
487 return ASN1_DER_ERROR;
488 break;
489 case TYPE_ENUMERATED:
490 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
491 return ASN1_DER_ERROR;
492 break;
493 case TYPE_OBJECT_ID:
494 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
495 return ASN1_DER_ERROR;
496 break;
497 case TYPE_TIME:
498 if (node->type & CONST_UTC)
500 if ((class != ASN1_CLASS_UNIVERSAL)
501 || (tag != ASN1_TAG_UTCTime))
502 return ASN1_DER_ERROR;
504 else
506 if ((class != ASN1_CLASS_UNIVERSAL)
507 || (tag != ASN1_TAG_GENERALIZEDTime))
508 return ASN1_DER_ERROR;
510 break;
511 case TYPE_OCTET_STRING:
512 if (((class != ASN1_CLASS_UNIVERSAL)
513 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
514 || (tag != ASN1_TAG_OCTET_STRING))
515 return ASN1_DER_ERROR;
516 break;
517 case TYPE_GENERALSTRING:
518 if ((class != ASN1_CLASS_UNIVERSAL)
519 || (tag != ASN1_TAG_GENERALSTRING))
520 return ASN1_DER_ERROR;
521 break;
522 case TYPE_BIT_STRING:
523 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
524 return ASN1_DER_ERROR;
525 break;
526 case TYPE_SEQUENCE:
527 case TYPE_SEQUENCE_OF:
528 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
529 || (tag != ASN1_TAG_SEQUENCE))
530 return ASN1_DER_ERROR;
531 break;
532 case TYPE_SET:
533 case TYPE_SET_OF:
534 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
535 || (tag != ASN1_TAG_SET))
536 return ASN1_DER_ERROR;
537 break;
538 case TYPE_ANY:
539 counter -= len2;
540 break;
541 default:
542 return ASN1_DER_ERROR;
543 break;
547 counter += len2;
548 *ret_len = counter;
549 return ASN1_SUCCESS;
552 static int
553 _asn1_delete_not_used (ASN1_TYPE node)
555 ASN1_TYPE p, p2;
557 if (node == NULL)
558 return ASN1_ELEMENT_NOT_FOUND;
560 p = node;
561 while (p)
563 if (p->type & CONST_NOT_USED)
565 p2 = NULL;
566 if (p != node)
568 p2 = _asn1_find_left (p);
569 if (!p2)
570 p2 = _asn1_find_up (p);
572 asn1_delete_structure (&p);
573 p = p2;
576 if (!p)
577 break; /* reach node */
579 if (p->down)
581 p = p->down;
583 else
585 if (p == node)
586 p = NULL;
587 else if (p->right)
588 p = p->right;
589 else
591 while (1)
593 p = _asn1_find_up (p);
594 if (p == node)
596 p = NULL;
597 break;
599 if (p->right)
601 p = p->right;
602 break;
608 return ASN1_SUCCESS;
611 static asn1_retCode
612 _asn1_extract_der_octet (ASN1_TYPE node, const unsigned char *der,
613 int der_len)
615 int len2, len3;
616 int counter2, counter_end;
618 len2 = asn1_get_length_der (der, der_len, &len3);
619 if (len2 < -1)
620 return ASN1_DER_ERROR;
622 counter2 = len3 + 1;
624 if (len2 == -1)
625 counter_end = der_len - 2;
626 else
627 counter_end = der_len;
629 while (counter2 < counter_end)
631 len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
633 if (len2 < -1)
634 return ASN1_DER_ERROR;
636 if (len2 > 0)
638 _asn1_append_value (node, der + counter2 + len3, len2);
640 else
641 { /* indefinite */
643 len2 =
644 _asn1_extract_der_octet (node, der + counter2 + len3,
645 der_len - counter2 - len3);
646 if (len2 < 0)
647 return len2;
650 counter2 += len2 + len3 + 1;
653 return ASN1_SUCCESS;
656 static asn1_retCode
657 _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
659 int len2, len3, counter, tot_len, indefinite;
661 counter = 0;
663 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
665 tot_len = 0;
666 indefinite = asn1_get_length_der (der, *len, &len3);
667 if (indefinite < -1)
668 return ASN1_DER_ERROR;
670 counter += len3;
671 if (indefinite >= 0)
672 indefinite += len3;
674 while (1)
676 if (counter > (*len))
677 return ASN1_DER_ERROR;
679 if (indefinite == -1)
681 if ((der[counter] == 0) && (der[counter + 1] == 0))
683 counter += 2;
684 break;
687 else if (counter >= indefinite)
688 break;
690 if (der[counter] != ASN1_TAG_OCTET_STRING)
691 return ASN1_DER_ERROR;
693 counter++;
695 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
696 if (len2 <= 0)
697 return ASN1_DER_ERROR;
699 counter += len3 + len2;
700 tot_len += len2;
703 /* copy */
704 if (node)
706 unsigned char temp[DER_LEN];
707 int ret;
709 len2 = sizeof (temp);
711 asn1_length_der (tot_len, temp, &len2);
712 _asn1_set_value (node, temp, len2);
714 tot_len += len2;
716 ret = _asn1_extract_der_octet (node, der, *len);
717 if (ret != ASN1_SUCCESS)
718 return ret;
722 else
723 { /* NOT STRUCTURED */
724 len2 = asn1_get_length_der (der, *len, &len3);
725 if (len2 < 0)
726 return ASN1_DER_ERROR;
727 if (len3 + len2 > *len)
728 return ASN1_DER_ERROR;
729 if (node)
730 _asn1_set_value (node, der, len3 + len2);
731 counter = len3 + len2;
734 *len = counter;
735 return ASN1_SUCCESS;
739 static asn1_retCode
740 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
742 int len2, len3, counter, indefinite;
743 unsigned long tag;
744 unsigned char class;
746 counter = indefinite = 0;
748 while (1)
750 if ((*len) < counter)
751 return ASN1_DER_ERROR;
753 if ((der[counter] == 0) && (der[counter + 1] == 0))
755 counter += 2;
756 indefinite--;
757 if (indefinite <= 0)
758 break;
759 else
760 continue;
763 if (asn1_get_tag_der
764 (der + counter, *len - counter, &class, &len2,
765 &tag) != ASN1_SUCCESS)
766 return ASN1_DER_ERROR;
767 if (counter + len2 > *len)
768 return ASN1_DER_ERROR;
769 counter += len2;
770 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
771 if (len2 < -1)
772 return ASN1_DER_ERROR;
773 if (len2 == -1)
775 indefinite++;
776 counter += 1;
778 else
780 counter += len2 + len3;
784 *len = counter;
785 return ASN1_SUCCESS;
790 * asn1_der_decoding:
791 * @element: pointer to an ASN1 structure.
792 * @ider: vector that contains the DER encoding.
793 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
794 * @errorDescription: null-terminated string contains details when an
795 * error occurred.
797 * Fill the structure *@ELEMENT with values of a DER encoding
798 * string. The structure must just be created with function
799 * asn1_create_element(). If an error occurs during the decoding
800 * procedure, the *@ELEMENT is deleted and set equal to
801 * %ASN1_TYPE_EMPTY.
803 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
804 * if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
805 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
806 * name (*@ELEMENT deleted).
808 asn1_retCode
809 asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
810 char *errorDescription)
812 ASN1_TYPE node, p, p2, p3;
813 char temp[128];
814 int counter, len2, len3, len4, move, ris, tlen;
815 unsigned char class;
816 unsigned long tag;
817 int indefinite, result;
818 const unsigned char *der = ider;
820 node = *element;
822 if (node == ASN1_TYPE_EMPTY)
823 return ASN1_ELEMENT_NOT_FOUND;
825 if (node->type & CONST_OPTION)
827 asn1_delete_structure (element);
828 return ASN1_GENERIC_ERROR;
831 counter = 0;
832 move = DOWN;
833 p = node;
834 while (1)
836 ris = ASN1_SUCCESS;
837 if (move != UP)
839 if (p->type & CONST_SET)
841 p2 = _asn1_find_up (p);
842 len2 = strtol (p2->value, NULL, 10);
843 if (len2 == -1)
845 if (!der[counter] && !der[counter + 1])
847 p = p2;
848 move = UP;
849 counter += 2;
850 continue;
853 else if (counter == len2)
855 p = p2;
856 move = UP;
857 continue;
859 else if (counter > len2)
861 asn1_delete_structure (element);
862 return ASN1_DER_ERROR;
864 p2 = p2->down;
865 while (p2)
867 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
869 if (type_field (p2->type) != TYPE_CHOICE)
870 ris =
871 _asn1_extract_tag_der (p2, der + counter,
872 len - counter, &len2);
873 else
875 p3 = p2->down;
876 while (p3)
878 ris =
879 _asn1_extract_tag_der (p3, der + counter,
880 len - counter, &len2);
881 if (ris == ASN1_SUCCESS)
882 break;
883 p3 = p3->right;
886 if (ris == ASN1_SUCCESS)
888 p2->type &= ~CONST_NOT_USED;
889 p = p2;
890 break;
893 p2 = p2->right;
895 if (p2 == NULL)
897 asn1_delete_structure (element);
898 return ASN1_DER_ERROR;
902 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
904 p2 = _asn1_find_up (p);
905 len2 = strtol (p2->value, NULL, 10);
906 if (counter == len2)
908 if (p->right)
910 p2 = p->right;
911 move = RIGHT;
913 else
914 move = UP;
916 if (p->type & CONST_OPTION)
917 asn1_delete_structure (&p);
919 p = p2;
920 continue;
924 if (type_field (p->type) == TYPE_CHOICE)
926 while (p->down)
928 if (counter < len)
929 ris =
930 _asn1_extract_tag_der (p->down, der + counter,
931 len - counter, &len2);
932 else
933 ris = ASN1_DER_ERROR;
934 if (ris == ASN1_SUCCESS)
936 while (p->down->right)
938 p2 = p->down->right;
939 asn1_delete_structure (&p2);
941 break;
943 else if (ris == ASN1_ERROR_TYPE_ANY)
945 asn1_delete_structure (element);
946 return ASN1_ERROR_TYPE_ANY;
948 else
950 p2 = p->down;
951 asn1_delete_structure (&p2);
955 if (p->down == NULL)
957 if (!(p->type & CONST_OPTION))
959 asn1_delete_structure (element);
960 return ASN1_DER_ERROR;
963 else
964 p = p->down;
967 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
969 p2 = _asn1_find_up (p);
970 len2 = strtol (p2->value, NULL, 10);
971 if ((len2 != -1) && (counter > len2))
972 ris = ASN1_TAG_ERROR;
975 if (ris == ASN1_SUCCESS)
976 ris =
977 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
978 if (ris != ASN1_SUCCESS)
980 if (p->type & CONST_OPTION)
982 p->type |= CONST_NOT_USED;
983 move = RIGHT;
985 else if (p->type & CONST_DEFAULT)
987 _asn1_set_value (p, NULL, 0);
988 move = RIGHT;
990 else
992 if (errorDescription != NULL)
993 _asn1_error_description_tag_error (p, errorDescription);
995 asn1_delete_structure (element);
996 return ASN1_TAG_ERROR;
999 else
1000 counter += len2;
1003 if (ris == ASN1_SUCCESS)
1005 switch (type_field (p->type))
1007 case TYPE_NULL:
1008 if (der[counter])
1010 asn1_delete_structure (element);
1011 return ASN1_DER_ERROR;
1013 counter++;
1014 move = RIGHT;
1015 break;
1016 case TYPE_BOOLEAN:
1017 if (der[counter++] != 1)
1019 asn1_delete_structure (element);
1020 return ASN1_DER_ERROR;
1022 if (der[counter++] == 0)
1023 _asn1_set_value (p, "F", 1);
1024 else
1025 _asn1_set_value (p, "T", 1);
1026 move = RIGHT;
1027 break;
1028 case TYPE_INTEGER:
1029 case TYPE_ENUMERATED:
1030 len2 =
1031 asn1_get_length_der (der + counter, len - counter, &len3);
1032 if (len2 < 0)
1033 return ASN1_DER_ERROR;
1034 if (len2 + len3 > len - counter)
1035 return ASN1_DER_ERROR;
1036 _asn1_set_value (p, der + counter, len3 + len2);
1037 counter += len3 + len2;
1038 move = RIGHT;
1039 break;
1040 case TYPE_OBJECT_ID:
1041 result =
1042 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1043 temp, sizeof (temp));
1044 if (result != ASN1_SUCCESS)
1046 asn1_delete_structure (element);
1047 return result;
1050 tlen = strlen (temp);
1051 if (tlen > 0)
1052 _asn1_set_value (p, temp, tlen + 1);
1053 counter += len2;
1054 move = RIGHT;
1055 break;
1056 case TYPE_TIME:
1057 result =
1058 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1059 sizeof (temp) - 1);
1060 if (result != ASN1_SUCCESS)
1062 asn1_delete_structure (element);
1063 return result;
1065 tlen = strlen (temp);
1066 if (tlen > 0)
1067 _asn1_set_value (p, temp, tlen + 1);
1068 counter += len2;
1069 move = RIGHT;
1070 break;
1071 case TYPE_OCTET_STRING:
1072 len3 = len - counter;
1073 ris = _asn1_get_octet_string (der + counter, p, &len3);
1074 if (ris != ASN1_SUCCESS)
1075 return ris;
1076 counter += len3;
1077 move = RIGHT;
1078 break;
1079 case TYPE_GENERALSTRING:
1080 len2 =
1081 asn1_get_length_der (der + counter, len - counter, &len3);
1082 if (len2 < 0)
1083 return ASN1_DER_ERROR;
1084 if (len3 + len2 > len - counter)
1085 return ASN1_DER_ERROR;
1086 _asn1_set_value (p, der + counter, len3 + len2);
1087 counter += len3 + len2;
1088 move = RIGHT;
1089 break;
1090 case TYPE_BIT_STRING:
1091 len2 =
1092 asn1_get_length_der (der + counter, len - counter, &len3);
1093 if (len2 < 0)
1094 return ASN1_DER_ERROR;
1095 if (len3 + len2 > len - counter)
1096 return ASN1_DER_ERROR;
1097 _asn1_set_value (p, der + counter, len3 + len2);
1098 counter += len3 + len2;
1099 move = RIGHT;
1100 break;
1101 case TYPE_SEQUENCE:
1102 case TYPE_SET:
1103 if (move == UP)
1105 len2 = strtol (p->value, NULL, 10);
1106 _asn1_set_value (p, NULL, 0);
1107 if (len2 == -1)
1108 { /* indefinite length method */
1109 if (len - counter + 1 > 0)
1111 if ((der[counter]) || der[counter + 1])
1113 asn1_delete_structure (element);
1114 return ASN1_DER_ERROR;
1117 else
1118 return ASN1_DER_ERROR;
1119 counter += 2;
1121 else
1122 { /* definite length method */
1123 if (len2 != counter)
1125 asn1_delete_structure (element);
1126 return ASN1_DER_ERROR;
1129 move = RIGHT;
1131 else
1132 { /* move==DOWN || move==RIGHT */
1133 len3 =
1134 asn1_get_length_der (der + counter, len - counter, &len2);
1135 if (len3 < -1)
1136 return ASN1_DER_ERROR;
1137 counter += len2;
1138 if (len3 > 0)
1140 _asn1_ltostr (counter + len3, temp);
1141 tlen = strlen (temp);
1142 if (tlen > 0)
1143 _asn1_set_value (p, temp, tlen + 1);
1144 move = DOWN;
1146 else if (len3 == 0)
1148 p2 = p->down;
1149 while (p2)
1151 if (type_field (p2->type) != TYPE_TAG)
1153 p3 = p2->right;
1154 asn1_delete_structure (&p2);
1155 p2 = p3;
1157 else
1158 p2 = p2->right;
1160 move = RIGHT;
1162 else
1163 { /* indefinite length method */
1164 _asn1_set_value (p, "-1", 3);
1165 move = DOWN;
1168 break;
1169 case TYPE_SEQUENCE_OF:
1170 case TYPE_SET_OF:
1171 if (move == UP)
1173 len2 = strtol (p->value, NULL, 10);
1174 if (len2 == -1)
1175 { /* indefinite length method */
1176 if ((counter + 2) > len)
1177 return ASN1_DER_ERROR;
1178 if ((der[counter]) || der[counter + 1])
1180 _asn1_append_sequence_set (p);
1181 p = p->down;
1182 while (p->right)
1183 p = p->right;
1184 move = RIGHT;
1185 continue;
1187 _asn1_set_value (p, NULL, 0);
1188 counter += 2;
1190 else
1191 { /* definite length method */
1192 if (len2 > counter)
1194 _asn1_append_sequence_set (p);
1195 p = p->down;
1196 while (p->right)
1197 p = p->right;
1198 move = RIGHT;
1199 continue;
1201 _asn1_set_value (p, NULL, 0);
1202 if (len2 != counter)
1204 asn1_delete_structure (element);
1205 return ASN1_DER_ERROR;
1209 else
1210 { /* move==DOWN || move==RIGHT */
1211 len3 =
1212 asn1_get_length_der (der + counter, len - counter, &len2);
1213 if (len3 < -1)
1214 return ASN1_DER_ERROR;
1215 counter += len2;
1216 if (len3)
1218 if (len3 > 0)
1219 { /* definite length method */
1220 _asn1_ltostr (counter + len3, temp);
1221 tlen = strlen (temp);
1223 if (tlen > 0)
1224 _asn1_set_value (p, temp, tlen + 1);
1226 else
1227 { /* indefinite length method */
1228 _asn1_set_value (p, "-1", 3);
1230 p2 = p->down;
1231 while ((type_field (p2->type) == TYPE_TAG)
1232 || (type_field (p2->type) == TYPE_SIZE))
1233 p2 = p2->right;
1234 if (p2->right == NULL)
1235 _asn1_append_sequence_set (p);
1236 p = p2;
1239 move = RIGHT;
1240 break;
1241 case TYPE_ANY:
1242 if (asn1_get_tag_der
1243 (der + counter, len - counter, &class, &len2,
1244 &tag) != ASN1_SUCCESS)
1245 return ASN1_DER_ERROR;
1246 if (counter + len2 > len)
1247 return ASN1_DER_ERROR;
1248 len4 =
1249 asn1_get_length_der (der + counter + len2,
1250 len - counter - len2, &len3);
1251 if (len4 < -1)
1252 return ASN1_DER_ERROR;
1253 if (len4 > len - counter + len2 + len3)
1254 return ASN1_DER_ERROR;
1255 if (len4 != -1)
1257 len2 += len4;
1258 _asn1_set_value_octet (p, der + counter, len2 + len3);
1259 counter += len2 + len3;
1261 else
1262 { /* indefinite length */
1263 /* Check indefinite lenth method in an EXPLICIT TAG */
1264 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1265 indefinite = 1;
1266 else
1267 indefinite = 0;
1269 len2 = len - counter;
1270 ris =
1271 _asn1_get_indefinite_length_string (der + counter, &len2);
1272 if (ris != ASN1_SUCCESS)
1274 asn1_delete_structure (element);
1275 return ris;
1278 _asn1_set_value_octet (p, der + counter, len2);
1279 counter += len2;
1281 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1282 an indefinite length method. */
1283 if (indefinite)
1285 if (!der[counter] && !der[counter + 1])
1287 counter += 2;
1289 else
1291 asn1_delete_structure (element);
1292 return ASN1_DER_ERROR;
1296 move = RIGHT;
1297 break;
1298 default:
1299 move = (move == UP) ? RIGHT : DOWN;
1300 break;
1304 if (p == node && move != DOWN)
1305 break;
1307 if (move == DOWN)
1309 if (p->down)
1310 p = p->down;
1311 else
1312 move = RIGHT;
1314 if ((move == RIGHT) && !(p->type & CONST_SET))
1316 if (p->right)
1317 p = p->right;
1318 else
1319 move = UP;
1321 if (move == UP)
1322 p = _asn1_find_up (p);
1325 _asn1_delete_not_used (*element);
1327 if (counter != len)
1329 asn1_delete_structure (element);
1330 return ASN1_DER_ERROR;
1333 return ASN1_SUCCESS;
1336 #define FOUND 1
1337 #define SAME_BRANCH 2
1338 #define OTHER_BRANCH 3
1339 #define EXIT 4
1342 * asn1_der_decoding_element:
1343 * @structure: pointer to an ASN1 structure
1344 * @elementName: name of the element to fill
1345 * @ider: vector that contains the DER encoding of the whole structure.
1346 * @len: number of bytes of *der: der[0]..der[len-1]
1347 * @errorDescription: null-terminated string contains details when an
1348 * error occurred.
1350 * Fill the element named @ELEMENTNAME with values of a DER encoding
1351 * string. The structure must just be created with function
1352 * asn1_create_element(). The DER vector must contain the encoding
1353 * string of the whole @STRUCTURE. If an error occurs during the
1354 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1355 * %ASN1_TYPE_EMPTY.
1357 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1358 * if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
1359 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1360 * match the structure @structure (*ELEMENT deleted).
1362 asn1_retCode
1363 asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
1364 const void *ider, int len, char *errorDescription)
1366 ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
1367 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1368 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1369 int counter, len2, len3, len4, move, ris, tlen;
1370 unsigned char class, *temp2;
1371 unsigned long tag;
1372 int indefinite, result;
1373 const unsigned char *der = ider;
1375 node = *structure;
1377 if (node == ASN1_TYPE_EMPTY)
1378 return ASN1_ELEMENT_NOT_FOUND;
1380 if (elementName == NULL)
1382 asn1_delete_structure (structure);
1383 return ASN1_ELEMENT_NOT_FOUND;
1386 if (node->type & CONST_OPTION)
1388 asn1_delete_structure (structure);
1389 return ASN1_GENERIC_ERROR;
1392 if ((*structure)->name)
1393 { /* Has *structure got a name? */
1394 nameLen -= strlen ((*structure)->name);
1395 if (nameLen > 0)
1396 strcpy (currentName, (*structure)->name);
1397 else
1399 asn1_delete_structure (structure);
1400 return ASN1_MEM_ERROR;
1402 if (!(strcmp (currentName, elementName)))
1404 state = FOUND;
1405 nodeFound = *structure;
1407 else if (!memcmp (currentName, elementName, strlen (currentName)))
1408 state = SAME_BRANCH;
1409 else
1410 state = OTHER_BRANCH;
1412 else
1413 { /* *structure doesn't have a name? */
1414 currentName[0] = 0;
1415 if (elementName[0] == 0)
1417 state = FOUND;
1418 nodeFound = *structure;
1420 else
1422 state = SAME_BRANCH;
1426 counter = 0;
1427 move = DOWN;
1428 p = node;
1429 while (1)
1432 ris = ASN1_SUCCESS;
1434 if (move != UP)
1436 if (p->type & CONST_SET)
1438 p2 = _asn1_find_up (p);
1439 len2 = strtol (p2->value, NULL, 10);
1440 if (counter == len2)
1442 p = p2;
1443 move = UP;
1444 continue;
1446 else if (counter > len2)
1448 asn1_delete_structure (structure);
1449 return ASN1_DER_ERROR;
1451 p2 = p2->down;
1452 while (p2)
1454 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1456 if (type_field (p2->type) != TYPE_CHOICE)
1457 ris =
1458 _asn1_extract_tag_der (p2, der + counter,
1459 len - counter, &len2);
1460 else
1462 p3 = p2->down;
1463 while (p3)
1465 ris =
1466 _asn1_extract_tag_der (p3, der + counter,
1467 len - counter, &len2);
1468 if (ris == ASN1_SUCCESS)
1469 break;
1470 p3 = p3->right;
1473 if (ris == ASN1_SUCCESS)
1475 p2->type &= ~CONST_NOT_USED;
1476 p = p2;
1477 break;
1480 p2 = p2->right;
1482 if (p2 == NULL)
1484 asn1_delete_structure (structure);
1485 return ASN1_DER_ERROR;
1489 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1491 p2 = _asn1_find_up (p);
1492 len2 = strtol (p2->value, NULL, 10);
1493 if (counter == len2)
1495 if (p->right)
1497 p2 = p->right;
1498 move = RIGHT;
1500 else
1501 move = UP;
1503 if (p->type & CONST_OPTION)
1504 asn1_delete_structure (&p);
1506 p = p2;
1507 continue;
1511 if (type_field (p->type) == TYPE_CHOICE)
1513 while (p->down)
1515 if (counter < len)
1516 ris =
1517 _asn1_extract_tag_der (p->down, der + counter,
1518 len - counter, &len2);
1519 else
1520 ris = ASN1_DER_ERROR;
1521 if (ris == ASN1_SUCCESS)
1523 while (p->down->right)
1525 p2 = p->down->right;
1526 asn1_delete_structure (&p2);
1528 break;
1530 else if (ris == ASN1_ERROR_TYPE_ANY)
1532 asn1_delete_structure (structure);
1533 return ASN1_ERROR_TYPE_ANY;
1535 else
1537 p2 = p->down;
1538 asn1_delete_structure (&p2);
1542 if (p->down == NULL)
1544 if (!(p->type & CONST_OPTION))
1546 asn1_delete_structure (structure);
1547 return ASN1_DER_ERROR;
1550 else
1551 p = p->down;
1554 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1556 p2 = _asn1_find_up (p);
1557 len2 = strtol (p2->value, NULL, 10);
1558 if (counter > len2)
1559 ris = ASN1_TAG_ERROR;
1562 if (ris == ASN1_SUCCESS)
1563 ris =
1564 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1565 if (ris != ASN1_SUCCESS)
1567 if (p->type & CONST_OPTION)
1569 p->type |= CONST_NOT_USED;
1570 move = RIGHT;
1572 else if (p->type & CONST_DEFAULT)
1574 _asn1_set_value (p, NULL, 0);
1575 move = RIGHT;
1577 else
1579 if (errorDescription != NULL)
1580 _asn1_error_description_tag_error (p, errorDescription);
1582 asn1_delete_structure (structure);
1583 return ASN1_TAG_ERROR;
1586 else
1587 counter += len2;
1590 if (ris == ASN1_SUCCESS)
1592 switch (type_field (p->type))
1594 case TYPE_NULL:
1595 if (der[counter])
1597 asn1_delete_structure (structure);
1598 return ASN1_DER_ERROR;
1601 if (p == nodeFound)
1602 state = EXIT;
1604 counter++;
1605 move = RIGHT;
1606 break;
1607 case TYPE_BOOLEAN:
1608 if (der[counter++] != 1)
1610 asn1_delete_structure (structure);
1611 return ASN1_DER_ERROR;
1614 if (state == FOUND)
1616 if (der[counter++] == 0)
1617 _asn1_set_value (p, "F", 1);
1618 else
1619 _asn1_set_value (p, "T", 1);
1621 if (p == nodeFound)
1622 state = EXIT;
1625 else
1626 counter++;
1628 move = RIGHT;
1629 break;
1630 case TYPE_INTEGER:
1631 case TYPE_ENUMERATED:
1632 len2 =
1633 asn1_get_length_der (der + counter, len - counter, &len3);
1634 if (len2 < 0)
1635 return ASN1_DER_ERROR;
1636 if (state == FOUND)
1638 if (len3 + len2 > len - counter)
1639 return ASN1_DER_ERROR;
1640 _asn1_set_value (p, der + counter, len3 + len2);
1642 if (p == nodeFound)
1643 state = EXIT;
1645 counter += len3 + len2;
1646 move = RIGHT;
1647 break;
1648 case TYPE_OBJECT_ID:
1649 if (state == FOUND)
1651 result =
1652 _asn1_get_objectid_der (der + counter, len - counter,
1653 &len2, temp, sizeof (temp));
1654 if (result != ASN1_SUCCESS)
1656 return result;
1659 tlen = strlen (temp);
1661 if (tlen > 0)
1662 _asn1_set_value (p, temp, tlen + 1);
1664 if (p == nodeFound)
1665 state = EXIT;
1667 else
1669 len2 =
1670 asn1_get_length_der (der + counter, len - counter, &len3);
1671 if (len2 < 0)
1672 return ASN1_DER_ERROR;
1673 len2 += len3;
1676 counter += len2;
1677 move = RIGHT;
1678 break;
1679 case TYPE_TIME:
1680 if (state == FOUND)
1682 result =
1683 _asn1_get_time_der (der + counter, len - counter, &len2,
1684 temp, sizeof (temp) - 1);
1685 if (result != ASN1_SUCCESS)
1687 asn1_delete_structure (structure);
1688 return result;
1691 tlen = strlen (temp);
1692 if (tlen > 0)
1693 _asn1_set_value (p, temp, tlen + 1);
1695 if (p == nodeFound)
1696 state = EXIT;
1698 else
1700 len2 =
1701 asn1_get_length_der (der + counter, len - counter, &len3);
1702 if (len2 < 0)
1703 return ASN1_DER_ERROR;
1704 len2 += len3;
1707 counter += len2;
1708 move = RIGHT;
1709 break;
1710 case TYPE_OCTET_STRING:
1711 len3 = len - counter;
1712 if (state == FOUND)
1714 ris = _asn1_get_octet_string (der + counter, p, &len3);
1715 if (p == nodeFound)
1716 state = EXIT;
1718 else
1719 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
1721 if (ris != ASN1_SUCCESS)
1722 return ris;
1723 counter += len3;
1724 move = RIGHT;
1725 break;
1726 case TYPE_GENERALSTRING:
1727 len2 =
1728 asn1_get_length_der (der + counter, len - counter, &len3);
1729 if (len2 < 0)
1730 return ASN1_DER_ERROR;
1731 if (state == FOUND)
1733 if (len3 + len2 > len - counter)
1734 return ASN1_DER_ERROR;
1735 _asn1_set_value (p, der + counter, len3 + len2);
1737 if (p == nodeFound)
1738 state = EXIT;
1740 counter += len3 + len2;
1741 move = RIGHT;
1742 break;
1743 case TYPE_BIT_STRING:
1744 len2 =
1745 asn1_get_length_der (der + counter, len - counter, &len3);
1746 if (len2 < 0)
1747 return ASN1_DER_ERROR;
1748 if (state == FOUND)
1750 if (len3 + len2 > len - counter)
1751 return ASN1_DER_ERROR;
1752 _asn1_set_value (p, der + counter, len3 + len2);
1754 if (p == nodeFound)
1755 state = EXIT;
1757 counter += len3 + len2;
1758 move = RIGHT;
1759 break;
1760 case TYPE_SEQUENCE:
1761 case TYPE_SET:
1762 if (move == UP)
1764 len2 = strtol (p->value, NULL, 10);
1765 _asn1_set_value (p, NULL, 0);
1766 if (len2 == -1)
1767 { /* indefinite length method */
1768 if ((der[counter]) || der[counter + 1])
1770 asn1_delete_structure (structure);
1771 return ASN1_DER_ERROR;
1773 counter += 2;
1775 else
1776 { /* definite length method */
1777 if (len2 != counter)
1779 asn1_delete_structure (structure);
1780 return ASN1_DER_ERROR;
1783 if (p == nodeFound)
1784 state = EXIT;
1785 move = RIGHT;
1787 else
1788 { /* move==DOWN || move==RIGHT */
1789 if (state == OTHER_BRANCH)
1791 len3 =
1792 asn1_get_length_der (der + counter, len - counter,
1793 &len2);
1794 if (len3 < 0)
1795 return ASN1_DER_ERROR;
1796 counter += len2 + len3;
1797 move = RIGHT;
1799 else
1800 { /* state==SAME_BRANCH or state==FOUND */
1801 len3 =
1802 asn1_get_length_der (der + counter, len - counter,
1803 &len2);
1804 if (len3 < 0)
1805 return ASN1_DER_ERROR;
1806 counter += len2;
1807 if (len3 > 0)
1809 _asn1_ltostr (counter + len3, temp);
1810 tlen = strlen (temp);
1812 if (tlen > 0)
1813 _asn1_set_value (p, temp, tlen + 1);
1814 move = DOWN;
1816 else if (len3 == 0)
1818 p2 = p->down;
1819 while (p2)
1821 if (type_field (p2->type) != TYPE_TAG)
1823 p3 = p2->right;
1824 asn1_delete_structure (&p2);
1825 p2 = p3;
1827 else
1828 p2 = p2->right;
1830 move = RIGHT;
1832 else
1833 { /* indefinite length method */
1834 _asn1_set_value (p, "-1", 3);
1835 move = DOWN;
1839 break;
1840 case TYPE_SEQUENCE_OF:
1841 case TYPE_SET_OF:
1842 if (move == UP)
1844 len2 = strtol (p->value, NULL, 10);
1845 if (len2 > counter)
1847 _asn1_append_sequence_set (p);
1848 p = p->down;
1849 while (p->right)
1850 p = p->right;
1851 move = RIGHT;
1852 continue;
1854 _asn1_set_value (p, NULL, 0);
1855 if (len2 != counter)
1857 asn1_delete_structure (structure);
1858 return ASN1_DER_ERROR;
1861 if (p == nodeFound)
1862 state = EXIT;
1864 else
1865 { /* move==DOWN || move==RIGHT */
1866 if (state == OTHER_BRANCH)
1868 len3 =
1869 asn1_get_length_der (der + counter, len - counter,
1870 &len2);
1871 if (len3 < 0)
1872 return ASN1_DER_ERROR;
1873 counter += len2 + len3;
1874 move = RIGHT;
1876 else
1877 { /* state==FOUND or state==SAME_BRANCH */
1878 len3 =
1879 asn1_get_length_der (der + counter, len - counter,
1880 &len2);
1881 if (len3 < 0)
1882 return ASN1_DER_ERROR;
1883 counter += len2;
1884 if (len3)
1886 _asn1_ltostr (counter + len3, temp);
1887 tlen = strlen (temp);
1889 if (tlen > 0)
1890 _asn1_set_value (p, temp, tlen + 1);
1891 p2 = p->down;
1892 while ((type_field (p2->type) == TYPE_TAG)
1893 || (type_field (p2->type) == TYPE_SIZE))
1894 p2 = p2->right;
1895 if (p2->right == NULL)
1896 _asn1_append_sequence_set (p);
1897 p = p2;
1898 state = FOUND;
1903 break;
1904 case TYPE_ANY:
1905 if (asn1_get_tag_der
1906 (der + counter, len - counter, &class, &len2,
1907 &tag) != ASN1_SUCCESS)
1908 return ASN1_DER_ERROR;
1909 if (counter + len2 > len)
1910 return ASN1_DER_ERROR;
1912 len4 =
1913 asn1_get_length_der (der + counter + len2,
1914 len - counter - len2, &len3);
1915 if (len4 < -1)
1916 return ASN1_DER_ERROR;
1918 if (len4 != -1)
1920 len2 += len4;
1921 if (state == FOUND)
1923 _asn1_set_value_octet (p, der + counter, len2 + len3);
1924 temp2 = NULL;
1926 if (p == nodeFound)
1927 state = EXIT;
1929 counter += len2 + len3;
1931 else
1932 { /* indefinite length */
1933 /* Check indefinite lenth method in an EXPLICIT TAG */
1934 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1935 indefinite = 1;
1936 else
1937 indefinite = 0;
1939 len2 = len - counter;
1940 ris =
1941 _asn1_get_indefinite_length_string (der + counter, &len2);
1942 if (ris != ASN1_SUCCESS)
1944 asn1_delete_structure (structure);
1945 return ris;
1948 if (state == FOUND)
1950 _asn1_set_value_octet (p, der + counter, len2);
1952 if (p == nodeFound)
1953 state = EXIT;
1956 counter += len2;
1958 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1959 an indefinite length method. */
1960 if (indefinite)
1962 if (!der[counter] && !der[counter + 1])
1964 counter += 2;
1966 else
1968 asn1_delete_structure (structure);
1969 return ASN1_DER_ERROR;
1973 move = RIGHT;
1974 break;
1976 default:
1977 move = (move == UP) ? RIGHT : DOWN;
1978 break;
1982 if ((p == node && move != DOWN) || (state == EXIT))
1983 break;
1985 if (move == DOWN)
1987 if (p->down)
1989 p = p->down;
1991 if (state != FOUND)
1993 nameLen -= strlen (p->name) + 1;
1994 if (nameLen > 0)
1996 if (currentName[0])
1997 strcat (currentName, ".");
1998 strcat (currentName, p->name);
2000 else
2002 asn1_delete_structure (structure);
2003 return ASN1_MEM_ERROR;
2005 if (!(strcmp (currentName, elementName)))
2007 state = FOUND;
2008 nodeFound = p;
2010 else
2011 if (!memcmp
2012 (currentName, elementName, strlen (currentName)))
2013 state = SAME_BRANCH;
2014 else
2015 state = OTHER_BRANCH;
2018 else
2019 move = RIGHT;
2022 if ((move == RIGHT) && !(p->type & CONST_SET))
2024 if (p->right)
2026 p = p->right;
2028 if (state != FOUND)
2030 dot_p = char_p = currentName;
2031 while ((char_p = strchr (char_p, '.')))
2033 dot_p = char_p++;
2034 dot_p++;
2037 nameLen += strlen (currentName) - (dot_p - currentName);
2038 *dot_p = 0;
2040 nameLen -= strlen (p->name);
2041 if (nameLen > 0)
2042 strcat (currentName, p->name);
2043 else
2045 asn1_delete_structure (structure);
2046 return ASN1_MEM_ERROR;
2049 if (!(strcmp (currentName, elementName)))
2051 state = FOUND;
2052 nodeFound = p;
2054 else
2055 if (!memcmp
2056 (currentName, elementName, strlen (currentName)))
2057 state = SAME_BRANCH;
2058 else
2059 state = OTHER_BRANCH;
2062 else
2063 move = UP;
2066 if (move == UP)
2068 p = _asn1_find_up (p);
2070 if (state != FOUND)
2072 dot_p = char_p = currentName;
2073 while ((char_p = strchr (char_p, '.')))
2075 dot_p = char_p++;
2076 dot_p++;
2079 nameLen += strlen (currentName) - (dot_p - currentName);
2080 *dot_p = 0;
2082 if (!(strcmp (currentName, elementName)))
2084 state = FOUND;
2085 nodeFound = p;
2087 else
2088 if (!memcmp (currentName, elementName, strlen (currentName)))
2089 state = SAME_BRANCH;
2090 else
2091 state = OTHER_BRANCH;
2096 _asn1_delete_not_used (*structure);
2098 if (counter > len)
2100 asn1_delete_structure (structure);
2101 return ASN1_DER_ERROR;
2104 return ASN1_SUCCESS;
2108 * asn1_der_decoding_startEnd:
2109 * @element: pointer to an ASN1 element
2110 * @ider: vector that contains the DER encoding.
2111 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2112 * @name_element: an element of NAME structure.
2113 * @start: the position of the first byte of NAME_ELEMENT decoding
2114 * (@ider[*start])
2115 * @end: the position of the last byte of NAME_ELEMENT decoding
2116 * (@ider[*end])
2118 * Find the start and end point of an element in a DER encoding
2119 * string. I mean that if you have a der encoding and you have already
2120 * used the function asn1_der_decoding() to fill a structure, it may
2121 * happen that you want to find the piece of string concerning an
2122 * element of the structure.
2124 * One example is the sequence "tbsCertificate" inside an X509
2125 * certificate.
2127 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2128 * if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
2129 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2130 * doesn't match the structure ELEMENT.
2132 asn1_retCode
2133 asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
2134 const char *name_element, int *start, int *end)
2136 ASN1_TYPE node, node_to_find, p, p2, p3;
2137 int counter, len2, len3, len4, move, ris;
2138 unsigned char class;
2139 unsigned long tag;
2140 int indefinite;
2141 const unsigned char *der = ider;
2143 node = element;
2145 if (node == ASN1_TYPE_EMPTY)
2146 return ASN1_ELEMENT_NOT_FOUND;
2148 node_to_find = asn1_find_node (node, name_element);
2150 if (node_to_find == NULL)
2151 return ASN1_ELEMENT_NOT_FOUND;
2153 if (node_to_find == node)
2155 *start = 0;
2156 *end = len - 1;
2157 return ASN1_SUCCESS;
2160 if (node->type & CONST_OPTION)
2161 return ASN1_GENERIC_ERROR;
2163 counter = 0;
2164 move = DOWN;
2165 p = node;
2166 while (1)
2168 ris = ASN1_SUCCESS;
2170 if (move != UP)
2172 if (p->type & CONST_SET)
2174 p2 = _asn1_find_up (p);
2175 len2 = strtol (p2->value, NULL, 10);
2176 if (len2 == -1)
2178 if (!der[counter] && !der[counter + 1])
2180 p = p2;
2181 move = UP;
2182 counter += 2;
2183 continue;
2186 else if (counter == len2)
2188 p = p2;
2189 move = UP;
2190 continue;
2192 else if (counter > len2)
2193 return ASN1_DER_ERROR;
2194 p2 = p2->down;
2195 while (p2)
2197 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2198 { /* CONTROLLARE */
2199 if (type_field (p2->type) != TYPE_CHOICE)
2200 ris =
2201 _asn1_extract_tag_der (p2, der + counter,
2202 len - counter, &len2);
2203 else
2205 p3 = p2->down;
2206 ris =
2207 _asn1_extract_tag_der (p3, der + counter,
2208 len - counter, &len2);
2210 if (ris == ASN1_SUCCESS)
2212 p2->type &= ~CONST_NOT_USED;
2213 p = p2;
2214 break;
2217 p2 = p2->right;
2219 if (p2 == NULL)
2220 return ASN1_DER_ERROR;
2223 if (p == node_to_find)
2224 *start = counter;
2226 if (type_field (p->type) == TYPE_CHOICE)
2228 p = p->down;
2229 ris =
2230 _asn1_extract_tag_der (p, der + counter, len - counter,
2231 &len2);
2232 if (p == node_to_find)
2233 *start = counter;
2236 if (ris == ASN1_SUCCESS)
2237 ris =
2238 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2239 if (ris != ASN1_SUCCESS)
2241 if (p->type & CONST_OPTION)
2243 p->type |= CONST_NOT_USED;
2244 move = RIGHT;
2246 else if (p->type & CONST_DEFAULT)
2248 move = RIGHT;
2250 else
2252 return ASN1_TAG_ERROR;
2255 else
2256 counter += len2;
2259 if (ris == ASN1_SUCCESS)
2261 switch (type_field (p->type))
2263 case TYPE_NULL:
2264 if (der[counter])
2265 return ASN1_DER_ERROR;
2266 counter++;
2267 move = RIGHT;
2268 break;
2269 case TYPE_BOOLEAN:
2270 if (der[counter++] != 1)
2271 return ASN1_DER_ERROR;
2272 counter++;
2273 move = RIGHT;
2274 break;
2275 case TYPE_INTEGER:
2276 case TYPE_ENUMERATED:
2277 len2 =
2278 asn1_get_length_der (der + counter, len - counter, &len3);
2279 if (len2 < 0)
2280 return ASN1_DER_ERROR;
2281 counter += len3 + len2;
2282 move = RIGHT;
2283 break;
2284 case TYPE_OBJECT_ID:
2285 len2 =
2286 asn1_get_length_der (der + counter, len - counter, &len3);
2287 if (len2 < 0)
2288 return ASN1_DER_ERROR;
2289 counter += len2 + len3;
2290 move = RIGHT;
2291 break;
2292 case TYPE_TIME:
2293 len2 =
2294 asn1_get_length_der (der + counter, len - counter, &len3);
2295 if (len2 < 0)
2296 return ASN1_DER_ERROR;
2297 counter += len2 + len3;
2298 move = RIGHT;
2299 break;
2300 case TYPE_OCTET_STRING:
2301 len3 = len - counter;
2302 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2303 if (ris != ASN1_SUCCESS)
2304 return ris;
2305 counter += len3;
2306 move = RIGHT;
2307 break;
2308 case TYPE_GENERALSTRING:
2309 len2 =
2310 asn1_get_length_der (der + counter, len - counter, &len3);
2311 if (len2 < 0)
2312 return ASN1_DER_ERROR;
2313 counter += len3 + len2;
2314 move = RIGHT;
2315 break;
2316 case TYPE_BIT_STRING:
2317 len2 =
2318 asn1_get_length_der (der + counter, len - counter, &len3);
2319 if (len2 < 0)
2320 return ASN1_DER_ERROR;
2321 counter += len3 + len2;
2322 move = RIGHT;
2323 break;
2324 case TYPE_SEQUENCE:
2325 case TYPE_SET:
2326 if (move != UP)
2328 len3 =
2329 asn1_get_length_der (der + counter, len - counter, &len2);
2330 if (len3 < -1)
2331 return ASN1_DER_ERROR;
2332 counter += len2;
2333 if (len3 == 0)
2334 move = RIGHT;
2335 else
2336 move = DOWN;
2338 else
2340 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2341 counter += 2;
2342 move = RIGHT;
2344 break;
2345 case TYPE_SEQUENCE_OF:
2346 case TYPE_SET_OF:
2347 if (move != UP)
2349 len3 =
2350 asn1_get_length_der (der + counter, len - counter, &len2);
2351 if (len3 < -1)
2352 return ASN1_DER_ERROR;
2353 counter += len2;
2354 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2355 counter += 2;
2356 else if (len3)
2358 p2 = p->down;
2359 while ((type_field (p2->type) == TYPE_TAG) ||
2360 (type_field (p2->type) == TYPE_SIZE))
2361 p2 = p2->right;
2362 p = p2;
2365 else
2367 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2368 counter += 2;
2370 move = RIGHT;
2371 break;
2372 case TYPE_ANY:
2373 if (asn1_get_tag_der
2374 (der + counter, len - counter, &class, &len2,
2375 &tag) != ASN1_SUCCESS)
2376 return ASN1_DER_ERROR;
2377 if (counter + len2 > len)
2378 return ASN1_DER_ERROR;
2380 len4 =
2381 asn1_get_length_der (der + counter + len2,
2382 len - counter - len2, &len3);
2383 if (len4 < -1)
2384 return ASN1_DER_ERROR;
2386 if (len4 != -1)
2388 counter += len2 + len4 + len3;
2390 else
2391 { /* indefinite length */
2392 /* Check indefinite lenth method in an EXPLICIT TAG */
2393 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2394 indefinite = 1;
2395 else
2396 indefinite = 0;
2398 len2 = len - counter;
2399 ris =
2400 _asn1_get_indefinite_length_string (der + counter, &len2);
2401 if (ris != ASN1_SUCCESS)
2402 return ris;
2403 counter += len2;
2405 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2406 an indefinite length method. */
2407 if (indefinite)
2409 if (!der[counter] && !der[counter + 1])
2410 counter += 2;
2411 else
2412 return ASN1_DER_ERROR;
2415 move = RIGHT;
2416 break;
2417 default:
2418 move = (move == UP) ? RIGHT : DOWN;
2419 break;
2423 if ((p == node_to_find) && (move == RIGHT))
2425 *end = counter - 1;
2426 return ASN1_SUCCESS;
2429 if (p == node && move != DOWN)
2430 break;
2432 if (move == DOWN)
2434 if (p->down)
2435 p = p->down;
2436 else
2437 move = RIGHT;
2439 if ((move == RIGHT) && !(p->type & CONST_SET))
2441 if (p->right)
2442 p = p->right;
2443 else
2444 move = UP;
2446 if (move == UP)
2447 p = _asn1_find_up (p);
2450 return ASN1_ELEMENT_NOT_FOUND;
2454 * asn1_expand_any_defined_by:
2455 * @definitions: ASN1 definitions
2456 * @element: pointer to an ASN1 structure
2458 * Expands every "ANY DEFINED BY" element of a structure created from
2459 * a DER decoding process (asn1_der_decoding function). The element
2460 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2461 * expand the element ANY is the first one following the definition of
2462 * the actual value of the OBJECT IDENTIFIER.
2464 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2465 * some "ANY DEFINED BY" element couldn't be expanded due to a
2466 * problem in OBJECT_ID -> TYPE association, or other error codes
2467 * depending on DER decoding.
2469 asn1_retCode
2470 asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
2472 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2473 value[ASN1_MAX_NAME_SIZE];
2474 asn1_retCode retCode = ASN1_SUCCESS, result;
2475 int len, len2, len3;
2476 ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
2477 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2479 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2480 return ASN1_ELEMENT_NOT_FOUND;
2482 strcpy (definitionsName, definitions->name);
2483 strcat (definitionsName, ".");
2485 p = *element;
2486 while (p)
2489 switch (type_field (p->type))
2491 case TYPE_ANY:
2492 if ((p->type & CONST_DEFINED_BY) && (p->value))
2494 /* search the "DEF_BY" element */
2495 p2 = p->down;
2496 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2497 p2 = p2->right;
2499 if (!p2)
2501 retCode = ASN1_ERROR_TYPE_ANY;
2502 break;
2505 p3 = _asn1_find_up (p);
2507 if (!p3)
2509 retCode = ASN1_ERROR_TYPE_ANY;
2510 break;
2513 p3 = p3->down;
2514 while (p3)
2516 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2517 break;
2518 p3 = p3->right;
2521 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2522 (p3->value == NULL))
2525 p3 = _asn1_find_up (p);
2526 p3 = _asn1_find_up (p3);
2528 if (!p3)
2530 retCode = ASN1_ERROR_TYPE_ANY;
2531 break;
2534 p3 = p3->down;
2536 while (p3)
2538 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2539 break;
2540 p3 = p3->right;
2543 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2544 (p3->value == NULL))
2546 retCode = ASN1_ERROR_TYPE_ANY;
2547 break;
2551 /* search the OBJECT_ID into definitions */
2552 p2 = definitions->down;
2553 while (p2)
2555 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2556 (p2->type & CONST_ASSIGN))
2558 strcpy (name, definitionsName);
2559 strcat (name, p2->name);
2561 len = ASN1_MAX_NAME_SIZE;
2562 result =
2563 asn1_read_value (definitions, name, value, &len);
2565 if ((result == ASN1_SUCCESS)
2566 && (!strcmp (p3->value, value)))
2568 p2 = p2->right; /* pointer to the structure to
2569 use for expansion */
2570 while ((p2) && (p2->type & CONST_ASSIGN))
2571 p2 = p2->right;
2573 if (p2)
2575 strcpy (name, definitionsName);
2576 strcat (name, p2->name);
2578 result =
2579 asn1_create_element (definitions, name, &aux);
2580 if (result == ASN1_SUCCESS)
2582 _asn1_set_name (aux, p->name);
2583 len2 =
2584 asn1_get_length_der (p->value,
2585 p->value_len, &len3);
2586 if (len2 < 0)
2587 return ASN1_DER_ERROR;
2589 result =
2590 asn1_der_decoding (&aux, p->value + len3,
2591 len2,
2592 errorDescription);
2593 if (result == ASN1_SUCCESS)
2596 _asn1_set_right (aux, p->right);
2597 _asn1_set_right (p, aux);
2599 result = asn1_delete_structure (&p);
2600 if (result == ASN1_SUCCESS)
2602 p = aux;
2603 aux = ASN1_TYPE_EMPTY;
2604 break;
2606 else
2607 { /* error with asn1_delete_structure */
2608 asn1_delete_structure (&aux);
2609 retCode = result;
2610 break;
2613 else
2614 { /* error with asn1_der_decoding */
2615 retCode = result;
2616 break;
2619 else
2620 { /* error with asn1_create_element */
2621 retCode = result;
2622 break;
2625 else
2626 { /* error with the pointer to the structure to exapand */
2627 retCode = ASN1_ERROR_TYPE_ANY;
2628 break;
2632 p2 = p2->right;
2633 } /* end while */
2635 if (!p2)
2637 retCode = ASN1_ERROR_TYPE_ANY;
2638 break;
2642 break;
2643 default:
2644 break;
2648 if (p->down)
2650 p = p->down;
2652 else if (p == *element)
2654 p = NULL;
2655 break;
2657 else if (p->right)
2658 p = p->right;
2659 else
2661 while (1)
2663 p = _asn1_find_up (p);
2664 if (p == *element)
2666 p = NULL;
2667 break;
2669 if (p->right)
2671 p = p->right;
2672 break;
2678 return retCode;
2682 * asn1_expand_octet_string:
2683 * @definitions: ASN1 definitions
2684 * @element: pointer to an ASN1 structure
2685 * @octetName: name of the OCTECT STRING field to expand.
2686 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2687 * the type for expansion.
2689 * Expands an "OCTET STRING" element of a structure created from a DER
2690 * decoding process (the asn1_der_decoding() function). The type used
2691 * for expansion is the first one following the definition of the
2692 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2694 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2695 * if @objectName or @octetName are not correct,
2696 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2697 * use for expansion, or other errors depending on DER decoding.
2699 asn1_retCode
2700 asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
2701 const char *octetName, const char *objectName)
2703 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2704 asn1_retCode retCode = ASN1_SUCCESS, result;
2705 int len, len2, len3;
2706 ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
2707 ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
2708 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2710 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2711 return ASN1_ELEMENT_NOT_FOUND;
2713 octetNode = asn1_find_node (*element, octetName);
2714 if (octetNode == ASN1_TYPE_EMPTY)
2715 return ASN1_ELEMENT_NOT_FOUND;
2716 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2717 return ASN1_ELEMENT_NOT_FOUND;
2718 if (octetNode->value == NULL)
2719 return ASN1_VALUE_NOT_FOUND;
2721 objectNode = asn1_find_node (*element, objectName);
2722 if (objectNode == ASN1_TYPE_EMPTY)
2723 return ASN1_ELEMENT_NOT_FOUND;
2725 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2726 return ASN1_ELEMENT_NOT_FOUND;
2728 if (objectNode->value == NULL)
2729 return ASN1_VALUE_NOT_FOUND;
2732 /* search the OBJECT_ID into definitions */
2733 p2 = definitions->down;
2734 while (p2)
2736 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2737 (p2->type & CONST_ASSIGN))
2739 strcpy (name, definitions->name);
2740 strcat (name, ".");
2741 strcat (name, p2->name);
2743 len = sizeof (value);
2744 result = asn1_read_value (definitions, name, value, &len);
2746 if ((result == ASN1_SUCCESS)
2747 && (!strcmp (objectNode->value, value)))
2750 p2 = p2->right; /* pointer to the structure to
2751 use for expansion */
2752 while ((p2) && (p2->type & CONST_ASSIGN))
2753 p2 = p2->right;
2755 if (p2)
2757 strcpy (name, definitions->name);
2758 strcat (name, ".");
2759 strcat (name, p2->name);
2761 result = asn1_create_element (definitions, name, &aux);
2762 if (result == ASN1_SUCCESS)
2764 _asn1_set_name (aux, octetNode->name);
2765 len2 =
2766 asn1_get_length_der (octetNode->value,
2767 octetNode->value_len, &len3);
2768 if (len2 < 0)
2769 return ASN1_DER_ERROR;
2771 result =
2772 asn1_der_decoding (&aux, octetNode->value + len3,
2773 len2, errorDescription);
2774 if (result == ASN1_SUCCESS)
2777 _asn1_set_right (aux, octetNode->right);
2778 _asn1_set_right (octetNode, aux);
2780 result = asn1_delete_structure (&octetNode);
2781 if (result == ASN1_SUCCESS)
2783 aux = ASN1_TYPE_EMPTY;
2784 break;
2786 else
2787 { /* error with asn1_delete_structure */
2788 asn1_delete_structure (&aux);
2789 retCode = result;
2790 break;
2793 else
2794 { /* error with asn1_der_decoding */
2795 retCode = result;
2796 break;
2799 else
2800 { /* error with asn1_create_element */
2801 retCode = result;
2802 break;
2805 else
2806 { /* error with the pointer to the structure to exapand */
2807 retCode = ASN1_VALUE_NOT_VALID;
2808 break;
2813 p2 = p2->right;
2817 if (!p2)
2818 retCode = ASN1_VALUE_NOT_VALID;
2820 return retCode;