Introduced ASN1_ETYPE_UTC_TIME and ASN1_ETYPE_GENERALIZED_TIME
[platform/upstream/libtasn1.git] / lib / decoding.c
1 /*
2  * Copyright (C) 2002-2012 Free Software Foundation, Inc.
3  *
4  * This file is part of LIBTASN1.
5  *
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.
10  *
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.
15  *
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
20  */
21
22
23 /*****************************************************/
24 /* File: decoding.c                                  */
25 /* Description: Functions to manage DER decoding     */
26 /*****************************************************/
27
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>
34
35 static int
36 _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
37
38 static void
39 _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
40 {
41
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, "'");
46
47 }
48
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.
54  *
55  * Extract a length field from DER data.
56  *
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)
63 {
64   unsigned int ans, sum, last;
65   int k, punt;
66
67   *len = 0;
68   if (der_len <= 0)
69     return 0;
70
71   if (!(der[0] & 128))
72     {
73       /* short form */
74       *len = 1;
75       ans = der[0];
76     }
77   else
78     {
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)
86             {
87               last = ans;
88
89               ans = (ans*256) + der[punt++];
90               if (ans < last)
91                 /* we wrapped around, no bignum support... */
92                 return -2;
93             }
94         }
95       else
96         {                       /* indefinite length method */
97           *len = punt;
98           return -1;
99         }
100
101       *len = punt;
102     }
103
104   sum = ans + *len;
105
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;
110
111   if (((int) sum) > der_len)
112     return -4;
113
114   return ans;
115 }
116
117 /**
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.
124  *
125  * Decode the class and TAG from DER code.
126  *
127  * Returns: Returns %ASN1_SUCCESS on success, or an error.
128  **/
129 int
130 asn1_get_tag_der (const unsigned char *der, int der_len,
131                   unsigned char *cls, int *len, unsigned long *tag)
132 {
133   unsigned int ris;
134   int punt;
135   unsigned int last;
136
137   if (der == NULL || der_len < 2 || len == NULL)
138     return ASN1_DER_ERROR;
139
140   *cls = der[0] & 0xE0;
141   if ((der[0] & 0x1F) != 0x1F)
142     {
143       /* short form */
144       *len = 1;
145       ris = der[0] & 0x1F;
146     }
147   else
148     {
149       /* Long form */
150       punt = 1;
151       ris = 0;
152       while (punt <= der_len && der[punt] & 128)
153         {
154           last = ris;
155
156           ris = (ris * 128) + (der[punt++] & 0x7F);
157           if (ris < last)
158             /* wrapped around, and no bignums... */
159             return ASN1_DER_ERROR;
160         }
161
162       if (punt >= der_len)
163         return ASN1_DER_ERROR;
164
165       last = ris;
166
167       ris = (ris * 128) + (der[punt++] & 0x7F);
168       if (ris < last)
169         return ASN1_DER_ERROR;
170
171       *len = punt;
172     }
173   if (tag)
174     *tag = ris;
175   return ASN1_SUCCESS;
176 }
177
178 /**
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.
183  *
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.
187  *
188  * Returns: Return the decoded length value, or negative value when
189  *   the value was too big.
190  *
191  * Since: 2.0
192  **/
193 long
194 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
195 {
196   int ret;
197   long err;
198
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;
206     }
207
208   return ret;
209 }
210
211 /**
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.
219  *
220  * Extract an OCTET SEQUENCE from DER data.
221  *
222  * Returns: Returns %ASN1_SUCCESS on success, or an error.
223  **/
224 int
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)
228 {
229   int len_len;
230
231   if (der_len <= 0)
232     return ASN1_GENERIC_ERROR;
233
234   /* if(str==NULL) return ASN1_SUCCESS; */
235   *str_len = asn1_get_length_der (der, der_len, &len_len);
236
237   if (*str_len < 0)
238     return ASN1_DER_ERROR;
239
240   *ret_len = *str_len + len_len;
241   if (str_size >= *str_len)
242     memcpy (str, der + len_len, *str_len);
243   else
244     {
245       return ASN1_MEM_ERROR;
246     }
247
248   return ASN1_SUCCESS;
249 }
250
251 /* Returns ASN1_SUCCESS on success or an error code on error.
252  */
253 static int
254 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
255                     char *str, int str_size)
256 {
257   int len_len, str_len;
258
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;
267
268   return ASN1_SUCCESS;
269 }
270
271 static int
272 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
273                         char *str, int str_size)
274 {
275   int len_len, len, k;
276   int leading;
277   char temp[20];
278   unsigned long val, val1, prev_val;
279
280   *ret_len = 0;
281   if (str && str_size > 0)
282     str[0] = 0;                 /* no oid */
283
284   if (str == NULL || der_len <= 0)
285     return ASN1_GENERIC_ERROR;
286   len = asn1_get_length_der (der, der_len, &len_len);
287
288   if (len < 0 || len > der_len || len_len > der_len)
289     return ASN1_DER_ERROR;
290
291   val1 = der[len_len] / 40;
292   val = der[len_len] - val1 * 40;
293
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));
297
298   prev_val = 0;
299   val = 0;
300   leading = 1;
301   for (k = 1; k < len; k++)
302     {
303       /* X.690 mandates that the leading byte must never be 0x80
304        */
305       if (leading != 0 && der[len_len + k] == 0x80)
306         return ASN1_DER_ERROR;
307       leading = 0;
308
309       /* check for wrap around */
310       val = val << 7;
311       val |= der[len_len + k] & 0x7F;
312
313       if (val < prev_val)
314         return ASN1_DER_ERROR;
315
316       prev_val = val;
317
318       if (!(der[len_len + k] & 0x80))
319         {
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;
325         }
326     }
327   *ret_len = len + len_len;
328
329   return ASN1_SUCCESS;
330 }
331
332 /**
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.
340  *
341  * Extract a BIT SEQUENCE from DER data.
342  *
343  * Returns: Return %ASN1_SUCCESS on success, or an error.
344  **/
345 int
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)
349 {
350   int len_len, len_byte;
351
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;
357
358   *ret_len = len_byte + len_len + 1;
359   *bit_len = len_byte * 8 - der[len_len];
360
361   if (str_size >= len_byte)
362     memcpy (str, der + len_len + 1, len_byte);
363   else
364     {
365       return ASN1_MEM_ERROR;
366     }
367
368   return ASN1_SUCCESS;
369 }
370
371 static int
372 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
373                        int *ret_len)
374 {
375   asn1_node p;
376   int counter, len2, len3, is_tag_implicit;
377   unsigned long tag, tag_implicit = 0;
378   unsigned char class, class2, class_implicit = 0;
379
380   if (der_len <= 0)
381     return ASN1_GENERIC_ERROR;
382
383   counter = is_tag_implicit = 0;
384
385   if (node->type & CONST_TAG)
386     {
387       p = node->down;
388       while (p)
389         {
390           if (type_field (p->type) == ASN1_ETYPE_TAG)
391             {
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;
400
401               if (p->type & CONST_EXPLICIT)
402                 {
403                   if (asn1_get_tag_der
404                       (der + counter, der_len - counter, &class, &len2,
405                        &tag) != ASN1_SUCCESS)
406                     return ASN1_DER_ERROR;
407
408                   if (counter + len2 > der_len)
409                     return ASN1_DER_ERROR;
410                   counter += len2;
411
412                   len3 =
413                     asn1_get_length_ber (der + counter, der_len - counter,
414                                          &len2);
415                   if (len3 < 0)
416                     return ASN1_DER_ERROR;
417
418                   counter += len2;
419                   if (counter > der_len)
420                     return ASN1_DER_ERROR;
421
422                   if (!is_tag_implicit)
423                     {
424                       if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
425                           (tag != strtoul ((char *) p->value, NULL, 10)))
426                         return ASN1_TAG_ERROR;
427                     }
428                   else
429                     {           /* ASN1_TAG_IMPLICIT */
430                       if ((class != class_implicit) || (tag != tag_implicit))
431                         return ASN1_TAG_ERROR;
432                     }
433                   is_tag_implicit = 0;
434                 }
435               else
436                 {               /* ASN1_TAG_IMPLICIT */
437                   if (!is_tag_implicit)
438                     {
439                       if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
440                           (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) ||
441                           (type_field (node->type) == ASN1_ETYPE_SET) ||
442                           (type_field (node->type) == ASN1_ETYPE_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;
447                     }
448                 }
449             }
450           p = p->right;
451         }
452     }
453
454   if (is_tag_implicit)
455     {
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;
462
463       if ((class != class_implicit) || (tag != tag_implicit))
464         {
465           if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
466             {
467               class_implicit |= ASN1_CLASS_STRUCTURED;
468               if ((class != class_implicit) || (tag != tag_implicit))
469                 return ASN1_TAG_ERROR;
470             }
471           else
472             return ASN1_TAG_ERROR;
473         }
474     }
475   else
476     {
477       unsigned type = type_field (node->type);
478       if (type == ASN1_ETYPE_TAG)
479         {
480           counter = 0;
481           *ret_len = counter;
482           return ASN1_SUCCESS;
483         }
484
485       if (asn1_get_tag_der
486           (der + counter, der_len - counter, &class, &len2,
487            &tag) != ASN1_SUCCESS)
488         return ASN1_DER_ERROR;
489
490       if (counter + len2 > der_len)
491         return ASN1_DER_ERROR;
492
493       switch (type)
494         {
495         case ASN1_ETYPE_NULL:
496         case ASN1_ETYPE_BOOLEAN:
497         case ASN1_ETYPE_INTEGER:
498         case ASN1_ETYPE_ENUMERATED:
499         case ASN1_ETYPE_OBJECT_ID:
500         case ASN1_ETYPE_GENERALSTRING:
501         case ASN1_ETYPE_NUMERIC_STRING:
502         case ASN1_ETYPE_IA5_STRING:
503         case ASN1_ETYPE_TELETEX_STRING:
504         case ASN1_ETYPE_PRINTABLE_STRING:
505         case ASN1_ETYPE_UNIVERSAL_STRING:
506         case ASN1_ETYPE_BMP_STRING:
507         case ASN1_ETYPE_UTF8_STRING:
508         case ASN1_ETYPE_VISIBLE_STRING:
509         case ASN1_ETYPE_BIT_STRING:
510         case ASN1_ETYPE_SEQUENCE:
511         case ASN1_ETYPE_SEQUENCE_OF:
512         case ASN1_ETYPE_SET:
513         case ASN1_ETYPE_SET_OF:
514         case ASN1_ETYPE_GENERALIZED_TIME:
515         case ASN1_ETYPE_UTC_TIME:
516           if ((class != _asn1_tags[type].class) || (tag != _asn1_tags[type].tag))
517             return ASN1_DER_ERROR;
518           break;
519
520         case ASN1_ETYPE_OCTET_STRING:
521           /* OCTET STRING is handled differently to allow
522            * BER encodings (structured class). */
523           if (((class != ASN1_CLASS_UNIVERSAL)
524                && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
525               || (tag != ASN1_TAG_OCTET_STRING))
526             return ASN1_DER_ERROR;
527           break;
528         case ASN1_ETYPE_ANY:
529           counter -= len2;
530           break;
531         default:
532           return ASN1_DER_ERROR;
533           break;
534         }
535     }
536
537   counter += len2;
538   *ret_len = counter;
539   return ASN1_SUCCESS;
540 }
541
542 static int
543 _asn1_delete_not_used (asn1_node node)
544 {
545   asn1_node p, p2;
546
547   if (node == NULL)
548     return ASN1_ELEMENT_NOT_FOUND;
549
550   p = node;
551   while (p)
552     {
553       if (p->type & CONST_NOT_USED)
554         {
555           p2 = NULL;
556           if (p != node)
557             {
558               p2 = _asn1_find_left (p);
559               if (!p2)
560                 p2 = _asn1_find_up (p);
561             }
562           asn1_delete_structure (&p);
563           p = p2;
564         }
565
566       if (!p)
567         break;                  /* reach node */
568
569       if (p->down)
570         {
571           p = p->down;
572         }
573       else
574         {
575           if (p == node)
576             p = NULL;
577           else if (p->right)
578             p = p->right;
579           else
580             {
581               while (1)
582                 {
583                   p = _asn1_find_up (p);
584                   if (p == node)
585                     {
586                       p = NULL;
587                       break;
588                     }
589                   if (p->right)
590                     {
591                       p = p->right;
592                       break;
593                     }
594                 }
595             }
596         }
597     }
598   return ASN1_SUCCESS;
599 }
600
601 static int
602 _asn1_extract_der_octet (asn1_node node, const unsigned char *der,
603                          int der_len)
604 {
605   int len2, len3;
606   int counter2, counter_end;
607
608   len2 = asn1_get_length_der (der, der_len, &len3);
609   if (len2 < -1)
610     return ASN1_DER_ERROR;
611
612   counter2 = len3 + 1;
613
614   if (len2 == -1)
615     counter_end = der_len - 2;
616   else
617     counter_end = der_len;
618
619   while (counter2 < counter_end)
620     {
621       len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
622
623       if (len2 < -1)
624         return ASN1_DER_ERROR;
625
626       if (len2 > 0)
627         {
628           _asn1_append_value (node, der + counter2 + len3, len2);
629         }
630       else
631         {                       /* indefinite */
632
633           len2 =
634             _asn1_extract_der_octet (node, der + counter2 + len3,
635                                      der_len - counter2 - len3);
636           if (len2 < 0)
637             return len2;
638         }
639
640       counter2 += len2 + len3 + 1;
641     }
642
643   return ASN1_SUCCESS;
644 }
645
646 static int
647 _asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len)
648 {
649   int len2, len3, counter, tot_len, indefinite;
650
651   counter = 0;
652
653   if (*(der - 1) & ASN1_CLASS_STRUCTURED)
654     {
655       tot_len = 0;
656       indefinite = asn1_get_length_der (der, *len, &len3);
657       if (indefinite < -1)
658         return ASN1_DER_ERROR;
659
660       counter += len3;
661       if (indefinite >= 0)
662         indefinite += len3;
663
664       while (1)
665         {
666           if (counter > (*len))
667             return ASN1_DER_ERROR;
668
669           if (indefinite == -1)
670             {
671               if ((der[counter] == 0) && (der[counter + 1] == 0))
672                 {
673                   counter += 2;
674                   break;
675                 }
676             }
677           else if (counter >= indefinite)
678             break;
679
680           if (der[counter] != ASN1_TAG_OCTET_STRING)
681             return ASN1_DER_ERROR;
682
683           counter++;
684
685           len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
686           if (len2 <= 0)
687             return ASN1_DER_ERROR;
688
689           counter += len3 + len2;
690           tot_len += len2;
691         }
692
693       /* copy */
694       if (node)
695         {
696           unsigned char temp[DER_LEN];
697           int ret;
698
699           len2 = sizeof (temp);
700
701           asn1_length_der (tot_len, temp, &len2);
702           _asn1_set_value (node, temp, len2);
703
704           ret = _asn1_extract_der_octet (node, der, *len);
705           if (ret != ASN1_SUCCESS)
706             return ret;
707
708         }
709     }
710   else
711     {                           /* NOT STRUCTURED */
712       len2 = asn1_get_length_der (der, *len, &len3);
713       if (len2 < 0)
714         return ASN1_DER_ERROR;
715
716       counter = len3 + len2;
717       if (node)
718         _asn1_set_value (node, der, counter);
719     }
720
721   *len = counter;
722   return ASN1_SUCCESS;
723
724 }
725
726 static int
727 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
728 {
729   int len2, len3, counter, indefinite;
730   unsigned long tag;
731   unsigned char class;
732
733   counter = indefinite = 0;
734
735   while (1)
736     {
737       if ((*len) < counter)
738         return ASN1_DER_ERROR;
739
740       if ((der[counter] == 0) && (der[counter + 1] == 0))
741         {
742           counter += 2;
743           indefinite--;
744           if (indefinite <= 0)
745             break;
746           else
747             continue;
748         }
749
750       if (asn1_get_tag_der
751           (der + counter, *len - counter, &class, &len2,
752            &tag) != ASN1_SUCCESS)
753         return ASN1_DER_ERROR;
754       if (counter + len2 > *len)
755         return ASN1_DER_ERROR;
756       counter += len2;
757       len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
758       if (len2 < -1)
759         return ASN1_DER_ERROR;
760       if (len2 == -1)
761         {
762           indefinite++;
763           counter += 1;
764         }
765       else
766         {
767           counter += len2 + len3;
768         }
769     }
770
771   *len = counter;
772   return ASN1_SUCCESS;
773
774 }
775
776 /**
777  * asn1_der_decoding:
778  * @element: pointer to an ASN1 structure.
779  * @ider: vector that contains the DER encoding.
780  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
781  * @errorDescription: null-terminated string contains details when an
782  *   error occurred.
783  *
784  * Fill the structure *@ELEMENT with values of a DER encoding
785  * string. The structure must just be created with function
786  * asn1_create_element().  If an error occurs during the decoding
787  * procedure, the *@ELEMENT is deleted and set equal to
788  * %NULL.
789  *
790  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
791  *   if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
792  *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
793  *   name (*@ELEMENT deleted).
794  **/
795 int
796 asn1_der_decoding (asn1_node * element, const void *ider, int len,
797                    char *errorDescription)
798 {
799   asn1_node node, p, p2, p3;
800   char temp[128];
801   int counter, len2, len3, len4, move, ris, tlen;
802   unsigned char class;
803   unsigned long tag;
804   int indefinite, result;
805   const unsigned char *der = ider;
806
807   node = *element;
808
809   if (errorDescription != NULL)
810     errorDescription[0] = 0;
811
812   if (node == NULL)
813     return ASN1_ELEMENT_NOT_FOUND;
814
815   if (node->type & CONST_OPTION)
816     {
817       result = ASN1_GENERIC_ERROR;
818       goto cleanup;
819     }
820
821   counter = 0;
822   move = DOWN;
823   p = node;
824   while (1)
825     {
826       ris = ASN1_SUCCESS;
827       if (move != UP)
828         {
829           if (p->type & CONST_SET)
830             {
831               p2 = _asn1_find_up (p);
832               len2 = _asn1_strtol (p2->value, NULL, 10);
833               if (len2 == -1)
834                 {
835                   if (!der[counter] && !der[counter + 1])
836                     {
837                       p = p2;
838                       move = UP;
839                       counter += 2;
840                       continue;
841                     }
842                 }
843               else if (counter == len2)
844                 {
845                   p = p2;
846                   move = UP;
847                   continue;
848                 }
849               else if (counter > len2)
850                 {
851                   result = ASN1_DER_ERROR;
852                   goto cleanup;
853                 }
854               p2 = p2->down;
855               while (p2)
856                 {
857                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
858                     {
859                       if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
860                         ris =
861                           _asn1_extract_tag_der (p2, der + counter,
862                                                  len - counter, &len2);
863                       else
864                         {
865                           p3 = p2->down;
866                           while (p3)
867                             {
868                               ris =
869                                 _asn1_extract_tag_der (p3, der + counter,
870                                                        len - counter, &len2);
871                               if (ris == ASN1_SUCCESS)
872                                 break;
873                               p3 = p3->right;
874                             }
875                         }
876                       if (ris == ASN1_SUCCESS)
877                         {
878                           p2->type &= ~CONST_NOT_USED;
879                           p = p2;
880                           break;
881                         }
882                     }
883                   p2 = p2->right;
884                 }
885               if (p2 == NULL)
886                 {
887                   result = ASN1_DER_ERROR;
888                   goto cleanup;
889                 }
890             }
891
892           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
893             {
894               p2 = _asn1_find_up (p);
895               len2 = _asn1_strtol (p2->value, NULL, 10);
896               if (counter == len2)
897                 {
898                   if (p->right)
899                     {
900                       p2 = p->right;
901                       move = RIGHT;
902                     }
903                   else
904                     move = UP;
905
906                   if (p->type & CONST_OPTION)
907                     asn1_delete_structure (&p);
908
909                   p = p2;
910                   continue;
911                 }
912             }
913
914           if (type_field (p->type) == ASN1_ETYPE_CHOICE)
915             {
916               while (p->down)
917                 {
918                   if (counter < len)
919                     ris =
920                       _asn1_extract_tag_der (p->down, der + counter,
921                                              len - counter, &len2);
922                   else
923                     ris = ASN1_DER_ERROR;
924                   if (ris == ASN1_SUCCESS)
925                     {
926                       while (p->down->right)
927                         {
928                           p2 = p->down->right;
929                           asn1_delete_structure (&p2);
930                         }
931                       break;
932                     }
933                   else if (ris == ASN1_ERROR_TYPE_ANY)
934                     {
935                       result = ASN1_ERROR_TYPE_ANY;
936                       goto cleanup;
937                     }
938                   else
939                     {
940                       p2 = p->down;
941                       asn1_delete_structure (&p2);
942                     }
943                 }
944
945               if (p->down == NULL)
946                 {
947                   if (!(p->type & CONST_OPTION))
948                     {
949                       result = ASN1_DER_ERROR;
950                       goto cleanup;
951                     }
952                 }
953               else
954                 p = p->down;
955             }
956
957           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
958             {
959               p2 = _asn1_find_up (p);
960               len2 = _asn1_strtol (p2->value, NULL, 10);
961               if ((len2 != -1) && (counter > len2))
962                 ris = ASN1_TAG_ERROR;
963             }
964
965           if (ris == ASN1_SUCCESS)
966             ris =
967               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
968           if (ris != ASN1_SUCCESS)
969             {
970               if (p->type & CONST_OPTION)
971                 {
972                   p->type |= CONST_NOT_USED;
973                   move = RIGHT;
974                 }
975               else if (p->type & CONST_DEFAULT)
976                 {
977                   _asn1_set_value (p, NULL, 0);
978                   move = RIGHT;
979                 }
980               else
981                 {
982                   if (errorDescription != NULL)
983                     _asn1_error_description_tag_error (p, errorDescription);
984
985                   result = ASN1_TAG_ERROR;
986                   goto cleanup;
987                 }
988             }
989           else
990             counter += len2;
991         }
992
993       if (ris == ASN1_SUCCESS)
994         {
995           switch (type_field (p->type))
996             {
997             case ASN1_ETYPE_NULL:
998               if (der[counter])
999                 {
1000                   result = ASN1_DER_ERROR;
1001                   goto cleanup;
1002                 }
1003               counter++;
1004               move = RIGHT;
1005               break;
1006             case ASN1_ETYPE_BOOLEAN:
1007               if (der[counter++] != 1)
1008                 {
1009                   result = ASN1_DER_ERROR;
1010                   goto cleanup;
1011                 }
1012               if (der[counter++] == 0)
1013                 _asn1_set_value (p, "F", 1);
1014               else
1015                 _asn1_set_value (p, "T", 1);
1016               move = RIGHT;
1017               break;
1018             case ASN1_ETYPE_INTEGER:
1019             case ASN1_ETYPE_ENUMERATED:
1020               len2 =
1021                 asn1_get_length_der (der + counter, len - counter, &len3);
1022               if (len2 < 0)
1023                 {
1024                   result = ASN1_DER_ERROR;
1025                   goto cleanup;
1026                 }
1027
1028               _asn1_set_value (p, der + counter, len3 + len2);
1029               counter += len3 + len2;
1030               move = RIGHT;
1031               break;
1032             case ASN1_ETYPE_OBJECT_ID:
1033               result =
1034                 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1035                                         temp, sizeof (temp));
1036               if (result != ASN1_SUCCESS)
1037                 goto cleanup;
1038
1039               tlen = strlen (temp);
1040               if (tlen > 0)
1041                 _asn1_set_value (p, temp, tlen + 1);
1042               counter += len2;
1043               move = RIGHT;
1044               break;
1045             case ASN1_ETYPE_GENERALIZED_TIME:
1046             case ASN1_ETYPE_UTC_TIME:
1047               result =
1048                 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1049                                     sizeof (temp) - 1);
1050               if (result != ASN1_SUCCESS)
1051                 goto cleanup;
1052
1053               tlen = strlen (temp);
1054               if (tlen > 0)
1055                 _asn1_set_value (p, temp, tlen + 1);
1056               counter += len2;
1057               move = RIGHT;
1058               break;
1059             case ASN1_ETYPE_OCTET_STRING:
1060               len3 = len - counter;
1061               result = _asn1_get_octet_string (der + counter, p, &len3);
1062               if (result != ASN1_SUCCESS)
1063                 goto cleanup;
1064
1065               counter += len3;
1066               move = RIGHT;
1067               break;
1068             case ASN1_ETYPE_GENERALSTRING:
1069             case ASN1_ETYPE_NUMERIC_STRING:
1070             case ASN1_ETYPE_IA5_STRING:
1071             case ASN1_ETYPE_TELETEX_STRING:
1072             case ASN1_ETYPE_PRINTABLE_STRING:
1073             case ASN1_ETYPE_UNIVERSAL_STRING:
1074             case ASN1_ETYPE_BMP_STRING:
1075             case ASN1_ETYPE_UTF8_STRING:
1076             case ASN1_ETYPE_VISIBLE_STRING:
1077             case ASN1_ETYPE_BIT_STRING:
1078               len2 =
1079                 asn1_get_length_der (der + counter, len - counter, &len3);
1080               if (len2 < 0)
1081                 {
1082                   result = ASN1_DER_ERROR;
1083                   goto cleanup;
1084                 }
1085
1086               _asn1_set_value (p, der + counter, len3 + len2);
1087               counter += len3 + len2;
1088               move = RIGHT;
1089               break;
1090             case ASN1_ETYPE_SEQUENCE:
1091             case ASN1_ETYPE_SET:
1092               if (move == UP)
1093                 {
1094                   len2 = _asn1_strtol (p->value, NULL, 10);
1095                   _asn1_set_value (p, NULL, 0);
1096                   if (len2 == -1)
1097                     {           /* indefinite length method */
1098                       if (len - counter + 1 > 0)
1099                         {
1100                           if ((der[counter]) || der[counter + 1])
1101                             {
1102                               result = ASN1_DER_ERROR;
1103                               goto cleanup;
1104                             }
1105                         }
1106                       else
1107                         {
1108                           result = ASN1_DER_ERROR;
1109                           goto cleanup;
1110                         }
1111                       counter += 2;
1112                     }
1113                   else
1114                     {           /* definite length method */
1115                       if (len2 != counter)
1116                         {
1117                           result = ASN1_DER_ERROR;
1118                           goto cleanup;
1119                         }
1120                     }
1121                   move = RIGHT;
1122                 }
1123               else
1124                 {               /* move==DOWN || move==RIGHT */
1125                   len3 =
1126                     asn1_get_length_der (der + counter, len - counter, &len2);
1127                   if (len3 < -1)
1128                     {
1129                       result = ASN1_DER_ERROR;
1130                       goto cleanup;
1131                     }
1132                   counter += len2;
1133                   if (len3 > 0)
1134                     {
1135                       _asn1_ltostr (counter + len3, temp);
1136                       tlen = strlen (temp);
1137                       if (tlen > 0)
1138                         _asn1_set_value (p, temp, tlen + 1);
1139                       move = DOWN;
1140                     }
1141                   else if (len3 == 0)
1142                     {
1143                       p2 = p->down;
1144                       while (p2)
1145                         {
1146                           if (type_field (p2->type) != ASN1_ETYPE_TAG)
1147                             {
1148                               p3 = p2->right;
1149                               asn1_delete_structure (&p2);
1150                               p2 = p3;
1151                             }
1152                           else
1153                             p2 = p2->right;
1154                         }
1155                       move = RIGHT;
1156                     }
1157                   else
1158                     {           /* indefinite length method */
1159                       _asn1_set_value (p, "-1", 3);
1160                       move = DOWN;
1161                     }
1162                 }
1163               break;
1164             case ASN1_ETYPE_SEQUENCE_OF:
1165             case ASN1_ETYPE_SET_OF:
1166               if (move == UP)
1167                 {
1168                   len2 = _asn1_strtol (p->value, NULL, 10);
1169                   if (len2 == -1)
1170                     {           /* indefinite length method */
1171                       if ((counter + 2) > len)
1172                         {
1173                           result = ASN1_DER_ERROR;
1174                           goto cleanup;
1175                         }
1176
1177                       if ((der[counter]) || der[counter + 1])
1178                         {
1179                           _asn1_append_sequence_set (p);
1180                           p = p->down;
1181                           while (p->right)
1182                             p = p->right;
1183                           move = RIGHT;
1184                           continue;
1185                         }
1186                       _asn1_set_value (p, NULL, 0);
1187                       counter += 2;
1188                     }
1189                   else
1190                     {           /* definite length method */
1191                       if (len2 > counter)
1192                         {
1193                           _asn1_append_sequence_set (p);
1194                           p = p->down;
1195                           while (p->right)
1196                             p = p->right;
1197                           move = RIGHT;
1198                           continue;
1199                         }
1200                       _asn1_set_value (p, NULL, 0);
1201                       if (len2 != counter)
1202                         {
1203                           result = ASN1_DER_ERROR;
1204                           goto cleanup;
1205                         }
1206                     }
1207                 }
1208               else
1209                 {               /* move==DOWN || move==RIGHT */
1210                   len3 =
1211                     asn1_get_length_der (der + counter, len - counter, &len2);
1212                   if (len3 < -1)
1213                     {
1214                       result = ASN1_DER_ERROR;
1215                       goto cleanup;
1216                     }
1217                   counter += len2;
1218                   if (len3)
1219                     {
1220                       if (len3 > 0)
1221                         {       /* definite length method */
1222                           _asn1_ltostr (counter + len3, temp);
1223                           tlen = strlen (temp);
1224
1225                           if (tlen > 0)
1226                             _asn1_set_value (p, temp, tlen + 1);
1227                         }
1228                       else
1229                         {       /* indefinite length method */
1230                           _asn1_set_value (p, "-1", 3);
1231                         }
1232                       p2 = p->down;
1233                       while ((type_field (p2->type) == ASN1_ETYPE_TAG)
1234                              || (type_field (p2->type) == ASN1_ETYPE_SIZE))
1235                         p2 = p2->right;
1236                       if (p2->right == NULL)
1237                         _asn1_append_sequence_set (p);
1238                       p = p2;
1239                     }
1240                 }
1241               move = RIGHT;
1242               break;
1243             case ASN1_ETYPE_ANY:
1244               if (asn1_get_tag_der
1245                   (der + counter, len - counter, &class, &len2,
1246                    &tag) != ASN1_SUCCESS)
1247                 {
1248                   result = ASN1_DER_ERROR;
1249                   goto cleanup;
1250                 }
1251
1252               if (counter + len2 > len)
1253                 {
1254                   result = ASN1_DER_ERROR;
1255                   goto cleanup;
1256                 }
1257               len4 =
1258                 asn1_get_length_der (der + counter + len2,
1259                                      len - counter - len2, &len3);
1260               if (len4 < -1)
1261                 {
1262                   result = ASN1_DER_ERROR;
1263                   goto cleanup;
1264                 }
1265               if (len4 != -1)
1266                 {
1267                   len2 += len4;
1268                   _asn1_set_value_lv (p, der + counter, len2 + len3);
1269                   counter += len2 + len3;
1270                 }
1271               else
1272                 {               /* indefinite length */
1273                   /* Check indefinite lenth method in an EXPLICIT TAG */
1274                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1275                     indefinite = 1;
1276                   else
1277                     indefinite = 0;
1278
1279                   len2 = len - counter;
1280                   result =
1281                     _asn1_get_indefinite_length_string (der + counter, &len2);
1282                   if (result != ASN1_SUCCESS)
1283                     goto cleanup;
1284
1285                   _asn1_set_value_lv (p, der + counter, len2);
1286                   counter += len2;
1287
1288                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1289                      an indefinite length method. */
1290                   if (indefinite)
1291                     {
1292                       if (!der[counter] && !der[counter + 1])
1293                         {
1294                           counter += 2;
1295                         }
1296                       else
1297                         {
1298                           result = ASN1_DER_ERROR;
1299                           goto cleanup;
1300                         }
1301                     }
1302                 }
1303               move = RIGHT;
1304               break;
1305             default:
1306               move = (move == UP) ? RIGHT : DOWN;
1307               break;
1308             }
1309         }
1310
1311       if (p == node && move != DOWN)
1312         break;
1313
1314       if (move == DOWN)
1315         {
1316           if (p->down)
1317             p = p->down;
1318           else
1319             move = RIGHT;
1320         }
1321       if ((move == RIGHT) && !(p->type & CONST_SET))
1322         {
1323           if (p->right)
1324             p = p->right;
1325           else
1326             move = UP;
1327         }
1328       if (move == UP)
1329         p = _asn1_find_up (p);
1330     }
1331
1332   _asn1_delete_not_used (*element);
1333
1334   if (counter != len)
1335     {
1336       result = ASN1_DER_ERROR;
1337       goto cleanup;
1338     }
1339
1340   return ASN1_SUCCESS;
1341
1342 cleanup:
1343   asn1_delete_structure (element);
1344   return result;
1345 }
1346
1347 #define FOUND        1
1348 #define SAME_BRANCH  2
1349 #define OTHER_BRANCH 3
1350 #define EXIT         4
1351
1352 /**
1353  * asn1_der_decoding_element:
1354  * @structure: pointer to an ASN1 structure
1355  * @elementName: name of the element to fill
1356  * @ider: vector that contains the DER encoding of the whole structure.
1357  * @len: number of bytes of *der: der[0]..der[len-1]
1358  * @errorDescription: null-terminated string contains details when an
1359  *   error occurred.
1360  *
1361  * Fill the element named @ELEMENTNAME with values of a DER encoding
1362  * string.  The structure must just be created with function
1363  * asn1_create_element().  The DER vector must contain the encoding
1364  * string of the whole @STRUCTURE.  If an error occurs during the
1365  * decoding procedure, the *@STRUCTURE is deleted and set equal to
1366  * %NULL.
1367  *
1368  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1369  *   if ELEMENT is %NULL or @elementName == NULL, and
1370  *   %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1371  *   match the structure @structure (*ELEMENT deleted).
1372  **/
1373 int
1374 asn1_der_decoding_element (asn1_node * structure, const char *elementName,
1375                            const void *ider, int len, char *errorDescription)
1376 {
1377   asn1_node node, p, p2, p3, nodeFound = NULL;
1378   char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1379   int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1380   int counter, len2, len3, len4, move, ris, tlen;
1381   unsigned char class;
1382   unsigned long tag;
1383   int indefinite, result;
1384   const unsigned char *der = ider;
1385
1386   node = *structure;
1387
1388   if (node == NULL)
1389     return ASN1_ELEMENT_NOT_FOUND;
1390
1391   if (elementName == NULL)
1392     {
1393       result = ASN1_ELEMENT_NOT_FOUND;
1394       goto cleanup;
1395     }
1396
1397   if (node->type & CONST_OPTION)
1398     {
1399       result = ASN1_GENERIC_ERROR;
1400       goto cleanup;
1401     }
1402
1403   if ((*structure)->name[0] != 0)
1404     {                           /* Has *structure got a name? */
1405       nameLen -= strlen ((*structure)->name);
1406       if (nameLen > 0)
1407         strcpy (currentName, (*structure)->name);
1408       else
1409         {
1410           result = ASN1_MEM_ERROR;
1411           goto cleanup;
1412         }
1413       if (!(strcmp (currentName, elementName)))
1414         {
1415           state = FOUND;
1416           nodeFound = *structure;
1417         }
1418       else if (!memcmp (currentName, elementName, strlen (currentName)))
1419         state = SAME_BRANCH;
1420       else
1421         state = OTHER_BRANCH;
1422     }
1423   else
1424     {                           /* *structure doesn't have a name? */
1425       currentName[0] = 0;
1426       if (elementName[0] == 0)
1427         {
1428           state = FOUND;
1429           nodeFound = *structure;
1430         }
1431       else
1432         {
1433           state = SAME_BRANCH;
1434         }
1435     }
1436
1437   counter = 0;
1438   move = DOWN;
1439   p = node;
1440   while (1)
1441     {
1442
1443       ris = ASN1_SUCCESS;
1444
1445       if (move != UP)
1446         {
1447           if (p->type & CONST_SET)
1448             {
1449               p2 = _asn1_find_up (p);
1450               len2 = _asn1_strtol (p2->value, NULL, 10);
1451               if (counter == len2)
1452                 {
1453                   p = p2;
1454                   move = UP;
1455                   continue;
1456                 }
1457               else if (counter > len2)
1458                 {
1459                   result = ASN1_DER_ERROR;
1460                   goto cleanup;
1461                 }
1462               p2 = p2->down;
1463               while (p2)
1464                 {
1465                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1466                     {
1467                       if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
1468                         ris =
1469                           _asn1_extract_tag_der (p2, der + counter,
1470                                                  len - counter, &len2);
1471                       else
1472                         {
1473                           p3 = p2->down;
1474                           while (p3)
1475                             {
1476                               ris =
1477                                 _asn1_extract_tag_der (p3, der + counter,
1478                                                        len - counter, &len2);
1479                               if (ris == ASN1_SUCCESS)
1480                                 break;
1481                               p3 = p3->right;
1482                             }
1483                         }
1484                       if (ris == ASN1_SUCCESS)
1485                         {
1486                           p2->type &= ~CONST_NOT_USED;
1487                           p = p2;
1488                           break;
1489                         }
1490                     }
1491                   p2 = p2->right;
1492                 }
1493               if (p2 == NULL)
1494                 {
1495                   result = ASN1_DER_ERROR;
1496                   goto cleanup;
1497                 }
1498             }
1499
1500           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1501             {
1502               p2 = _asn1_find_up (p);
1503               len2 = _asn1_strtol (p2->value, NULL, 10);
1504               if (counter == len2)
1505                 {
1506                   if (p->right)
1507                     {
1508                       p2 = p->right;
1509                       move = RIGHT;
1510                     }
1511                   else
1512                     move = UP;
1513
1514                   if (p->type & CONST_OPTION)
1515                     asn1_delete_structure (&p);
1516
1517                   p = p2;
1518                   continue;
1519                 }
1520             }
1521
1522           if (type_field (p->type) == ASN1_ETYPE_CHOICE)
1523             {
1524               while (p->down)
1525                 {
1526                   if (counter < len)
1527                     ris =
1528                       _asn1_extract_tag_der (p->down, der + counter,
1529                                              len - counter, &len2);
1530                   else
1531                     ris = ASN1_DER_ERROR;
1532                   if (ris == ASN1_SUCCESS)
1533                     {
1534                       while (p->down->right)
1535                         {
1536                           p2 = p->down->right;
1537                           asn1_delete_structure (&p2);
1538                         }
1539                       break;
1540                     }
1541                   else if (ris == ASN1_ERROR_TYPE_ANY)
1542                     {
1543                       result = ASN1_ERROR_TYPE_ANY;
1544                       goto cleanup;
1545                     }
1546                   else
1547                     {
1548                       p2 = p->down;
1549                       asn1_delete_structure (&p2);
1550                     }
1551                 }
1552
1553               if (p->down == NULL)
1554                 {
1555                   if (!(p->type & CONST_OPTION))
1556                     {
1557                       result = ASN1_DER_ERROR;
1558                       goto cleanup;
1559                     }
1560                 }
1561               else
1562                 p = p->down;
1563             }
1564
1565           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1566             {
1567               p2 = _asn1_find_up (p);
1568               len2 = _asn1_strtol (p2->value, NULL, 10);
1569               if (counter > len2)
1570                 ris = ASN1_TAG_ERROR;
1571             }
1572
1573           if (ris == ASN1_SUCCESS)
1574             ris =
1575               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1576           if (ris != ASN1_SUCCESS)
1577             {
1578               if (p->type & CONST_OPTION)
1579                 {
1580                   p->type |= CONST_NOT_USED;
1581                   move = RIGHT;
1582                 }
1583               else if (p->type & CONST_DEFAULT)
1584                 {
1585                   _asn1_set_value (p, NULL, 0);
1586                   move = RIGHT;
1587                 }
1588               else
1589                 {
1590                   if (errorDescription != NULL)
1591                     _asn1_error_description_tag_error (p, errorDescription);
1592
1593                   result = ASN1_TAG_ERROR;
1594                   goto cleanup;
1595                 }
1596             }
1597           else
1598             counter += len2;
1599         }
1600
1601       if (ris == ASN1_SUCCESS)
1602         {
1603           switch (type_field (p->type))
1604             {
1605             case ASN1_ETYPE_NULL:
1606               if (der[counter])
1607                 {
1608                   result = ASN1_DER_ERROR;
1609                   goto cleanup;
1610                 }
1611
1612               if (p == nodeFound)
1613                 state = EXIT;
1614
1615               counter++;
1616               move = RIGHT;
1617               break;
1618             case ASN1_ETYPE_BOOLEAN:
1619               if (der[counter++] != 1)
1620                 {
1621                   result = ASN1_DER_ERROR;
1622                   goto cleanup;
1623                 }
1624
1625               if (state == FOUND)
1626                 {
1627                   if (der[counter++] == 0)
1628                     _asn1_set_value (p, "F", 1);
1629                   else
1630                     _asn1_set_value (p, "T", 1);
1631
1632                   if (p == nodeFound)
1633                     state = EXIT;
1634
1635                 }
1636               else
1637                 counter++;
1638
1639               move = RIGHT;
1640               break;
1641             case ASN1_ETYPE_INTEGER:
1642             case ASN1_ETYPE_ENUMERATED:
1643               len2 =
1644                 asn1_get_length_der (der + counter, len - counter, &len3);
1645               if (len2 < 0)
1646                 {
1647                   result = ASN1_DER_ERROR;
1648                   goto cleanup;
1649                 }
1650
1651               if (state == FOUND)
1652                 {
1653                   if (len3 + len2 > len - counter)
1654                     {
1655                       result = ASN1_DER_ERROR;
1656                       goto cleanup;
1657                     }
1658                   _asn1_set_value (p, der + counter, len3 + len2);
1659
1660                   if (p == nodeFound)
1661                     state = EXIT;
1662                 }
1663               counter += len3 + len2;
1664               move = RIGHT;
1665               break;
1666             case ASN1_ETYPE_OBJECT_ID:
1667               if (state == FOUND)
1668                 {
1669                   result =
1670                     _asn1_get_objectid_der (der + counter, len - counter,
1671                                             &len2, temp, sizeof (temp));
1672                   if (result != ASN1_SUCCESS)
1673                     goto cleanup;
1674
1675                   tlen = strlen (temp);
1676
1677                   if (tlen > 0)
1678                     _asn1_set_value (p, temp, tlen + 1);
1679
1680                   if (p == nodeFound)
1681                     state = EXIT;
1682                 }
1683               else
1684                 {
1685                   len2 =
1686                     asn1_get_length_der (der + counter, len - counter, &len3);
1687                   if (len2 < 0)
1688                     {
1689                       result = ASN1_DER_ERROR;
1690                       goto cleanup;
1691                     }
1692                   len2 += len3;
1693                 }
1694
1695               counter += len2;
1696               move = RIGHT;
1697               break;
1698             case ASN1_ETYPE_GENERALIZED_TIME:
1699             case ASN1_ETYPE_UTC_TIME:
1700               if (state == FOUND)
1701                 {
1702                   result =
1703                     _asn1_get_time_der (der + counter, len - counter, &len2,
1704                                         temp, sizeof (temp) - 1);
1705                   if (result != ASN1_SUCCESS)
1706                     goto cleanup;
1707
1708                   tlen = strlen (temp);
1709                   if (tlen > 0)
1710                     _asn1_set_value (p, temp, tlen + 1);
1711
1712                   if (p == nodeFound)
1713                     state = EXIT;
1714                 }
1715               else
1716                 {
1717                   len2 =
1718                     asn1_get_length_der (der + counter, len - counter, &len3);
1719                   if (len2 < 0)
1720                     {
1721                       result = ASN1_DER_ERROR;
1722                       goto cleanup;
1723                     }
1724                   len2 += len3;
1725                 }
1726
1727               counter += len2;
1728               move = RIGHT;
1729               break;
1730             case ASN1_ETYPE_OCTET_STRING:
1731               len3 = len - counter;
1732               if (state == FOUND)
1733                 {
1734                   result = _asn1_get_octet_string (der + counter, p, &len3);
1735                   if (p == nodeFound)
1736                     state = EXIT;
1737                 }
1738               else
1739                 result = _asn1_get_octet_string (der + counter, NULL, &len3);
1740
1741               if (result != ASN1_SUCCESS)
1742                 goto cleanup;
1743
1744               counter += len3;
1745               move = RIGHT;
1746               break;
1747             case ASN1_ETYPE_GENERALSTRING:
1748             case ASN1_ETYPE_NUMERIC_STRING:
1749             case ASN1_ETYPE_IA5_STRING:
1750             case ASN1_ETYPE_TELETEX_STRING:
1751             case ASN1_ETYPE_PRINTABLE_STRING:
1752             case ASN1_ETYPE_UNIVERSAL_STRING:
1753             case ASN1_ETYPE_BMP_STRING:
1754             case ASN1_ETYPE_UTF8_STRING:
1755             case ASN1_ETYPE_VISIBLE_STRING:
1756             case ASN1_ETYPE_BIT_STRING:
1757               len2 =
1758                 asn1_get_length_der (der + counter, len - counter, &len3);
1759               if (len2 < 0)
1760                 {
1761                   result = ASN1_DER_ERROR;
1762                   goto cleanup;
1763                 }
1764
1765               if (state == FOUND)
1766                 {
1767                   if (len3 + len2 > len - counter)
1768                     {
1769                       result = ASN1_DER_ERROR;
1770                       goto cleanup;
1771                     }
1772                   _asn1_set_value (p, der + counter, len3 + len2);
1773
1774                   if (p == nodeFound)
1775                     state = EXIT;
1776                 }
1777               counter += len3 + len2;
1778               move = RIGHT;
1779               break;
1780             case ASN1_ETYPE_SEQUENCE:
1781             case ASN1_ETYPE_SET:
1782               if (move == UP)
1783                 {
1784                   len2 = _asn1_strtol (p->value, NULL, 10);
1785                   _asn1_set_value (p, NULL, 0);
1786                   if (len2 == -1)
1787                     {           /* indefinite length method */
1788                       if ((der[counter]) || der[counter + 1])
1789                         {
1790                           result = ASN1_DER_ERROR;
1791                           goto cleanup;
1792                         }
1793                       counter += 2;
1794                     }
1795                   else
1796                     {           /* definite length method */
1797                       if (len2 != counter)
1798                         {
1799                           result = ASN1_DER_ERROR;
1800                           goto cleanup;
1801                         }
1802                     }
1803                   if (p == nodeFound)
1804                     state = EXIT;
1805                   move = RIGHT;
1806                 }
1807               else
1808                 {               /* move==DOWN || move==RIGHT */
1809                   if (state == OTHER_BRANCH)
1810                     {
1811                       len3 =
1812                         asn1_get_length_der (der + counter, len - counter,
1813                                              &len2);
1814                       if (len3 < 0)
1815                         {
1816                           result = ASN1_DER_ERROR;
1817                           goto cleanup;
1818                         }
1819                       counter += len2 + len3;
1820                       move = RIGHT;
1821                     }
1822                   else
1823                     {           /*  state==SAME_BRANCH or state==FOUND */
1824                       len3 =
1825                         asn1_get_length_der (der + counter, len - counter,
1826                                              &len2);
1827                       if (len3 < 0)
1828                         {
1829                           result = ASN1_DER_ERROR;
1830                           goto cleanup;
1831                         }
1832                       counter += len2;
1833                       if (len3 > 0)
1834                         {
1835                           _asn1_ltostr (counter + len3, temp);
1836                           tlen = strlen (temp);
1837
1838                           if (tlen > 0)
1839                             _asn1_set_value (p, temp, tlen + 1);
1840                           move = DOWN;
1841                         }
1842                       else if (len3 == 0)
1843                         {
1844                           p2 = p->down;
1845                           while (p2)
1846                             {
1847                               if (type_field (p2->type) != ASN1_ETYPE_TAG)
1848                                 {
1849                                   p3 = p2->right;
1850                                   asn1_delete_structure (&p2);
1851                                   p2 = p3;
1852                                 }
1853                               else
1854                                 p2 = p2->right;
1855                             }
1856                           move = RIGHT;
1857                         }
1858                       else
1859                         {       /* indefinite length method */
1860                           _asn1_set_value (p, "-1", 3);
1861                           move = DOWN;
1862                         }
1863                     }
1864                 }
1865               break;
1866             case ASN1_ETYPE_SEQUENCE_OF:
1867             case ASN1_ETYPE_SET_OF:
1868               if (move == UP)
1869                 {
1870                   len2 = _asn1_strtol (p->value, NULL, 10);
1871                   if (len2 > counter)
1872                     {
1873                       _asn1_append_sequence_set (p);
1874                       p = p->down;
1875                       while (p->right)
1876                         p = p->right;
1877                       move = RIGHT;
1878                       continue;
1879                     }
1880                   _asn1_set_value (p, NULL, 0);
1881                   if (len2 != counter)
1882                     {
1883                       result = ASN1_DER_ERROR;
1884                       goto cleanup;
1885                     }
1886
1887                   if (p == nodeFound)
1888                     state = EXIT;
1889                 }
1890               else
1891                 {               /* move==DOWN || move==RIGHT */
1892                   if (state == OTHER_BRANCH)
1893                     {
1894                       len3 =
1895                         asn1_get_length_der (der + counter, len - counter,
1896                                              &len2);
1897                       if (len3 < 0)
1898                         {
1899                           result = ASN1_DER_ERROR;
1900                           goto cleanup;
1901                         }
1902                       counter += len2 + len3;
1903                       move = RIGHT;
1904                     }
1905                   else
1906                     {           /* state==FOUND or state==SAME_BRANCH */
1907                       len3 =
1908                         asn1_get_length_der (der + counter, len - counter,
1909                                              &len2);
1910                       if (len3 < 0)
1911                         {
1912                           result = ASN1_DER_ERROR;
1913                           goto cleanup;
1914                         }
1915                       counter += len2;
1916                       if (len3)
1917                         {
1918                           _asn1_ltostr (counter + len3, temp);
1919                           tlen = strlen (temp);
1920
1921                           if (tlen > 0)
1922                             _asn1_set_value (p, temp, tlen + 1);
1923                           p2 = p->down;
1924                           while ((type_field (p2->type) == ASN1_ETYPE_TAG)
1925                                  || (type_field (p2->type) == ASN1_ETYPE_SIZE))
1926                             p2 = p2->right;
1927                           if (p2->right == NULL)
1928                             _asn1_append_sequence_set (p);
1929                           p = p2;
1930                           state = FOUND;
1931                         }
1932                     }
1933                 }
1934
1935               break;
1936             case ASN1_ETYPE_ANY:
1937               if (asn1_get_tag_der
1938                   (der + counter, len - counter, &class, &len2,
1939                    &tag) != ASN1_SUCCESS)
1940                 {
1941                   result = ASN1_DER_ERROR;
1942                   goto cleanup;
1943                 }
1944
1945               if (counter + len2 > len)
1946                 {
1947                   result = ASN1_DER_ERROR;
1948                   goto cleanup;
1949                 }
1950
1951               len4 =
1952                 asn1_get_length_der (der + counter + len2,
1953                                      len - counter - len2, &len3);
1954               if (len4 < -1)
1955                 {
1956                   result = ASN1_DER_ERROR;
1957                   goto cleanup;
1958                 }
1959
1960               if (len4 != -1)
1961                 {
1962                   len2 += len4;
1963                   if (state == FOUND)
1964                     {
1965                       _asn1_set_value_lv (p, der + counter, len2 + len3);
1966
1967                       if (p == nodeFound)
1968                         state = EXIT;
1969                     }
1970                   counter += len2 + len3;
1971                 }
1972               else
1973                 {               /* indefinite length */
1974                   /* Check indefinite lenth method in an EXPLICIT TAG */
1975                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1976                     indefinite = 1;
1977                   else
1978                     indefinite = 0;
1979
1980                   len2 = len - counter;
1981                   result =
1982                     _asn1_get_indefinite_length_string (der + counter, &len2);
1983                   if (result != ASN1_SUCCESS)
1984                     goto cleanup;
1985
1986                   if (state == FOUND)
1987                     {
1988                       _asn1_set_value_lv (p, der + counter, len2);
1989
1990                       if (p == nodeFound)
1991                         state = EXIT;
1992                     }
1993
1994                   counter += len2;
1995
1996                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1997                      an indefinite length method. */
1998                   if (indefinite)
1999                     {
2000                       if (!der[counter] && !der[counter + 1])
2001                         {
2002                           counter += 2;
2003                         }
2004                       else
2005                         {
2006                           result = ASN1_DER_ERROR;
2007                           goto cleanup;
2008                         }
2009                     }
2010                 }
2011               move = RIGHT;
2012               break;
2013
2014             default:
2015               move = (move == UP) ? RIGHT : DOWN;
2016               break;
2017             }
2018         }
2019
2020       if ((p == node && move != DOWN) || (state == EXIT))
2021         break;
2022
2023       if (move == DOWN)
2024         {
2025           if (p->down)
2026             {
2027               p = p->down;
2028
2029               if (state != FOUND)
2030                 {
2031                   nameLen -= strlen (p->name) + 1;
2032                   if (nameLen > 0)
2033                     {
2034                       if (currentName[0])
2035                         strcat (currentName, ".");
2036                       strcat (currentName, p->name);
2037                     }
2038                   else
2039                     {
2040                       result = ASN1_MEM_ERROR;
2041                       goto cleanup;
2042                     }
2043                   if (!(strcmp (currentName, elementName)))
2044                     {
2045                       state = FOUND;
2046                       nodeFound = p;
2047                     }
2048                   else
2049                     if (!memcmp
2050                         (currentName, elementName, strlen (currentName)))
2051                     state = SAME_BRANCH;
2052                   else
2053                     state = OTHER_BRANCH;
2054                 }
2055             }
2056           else
2057             move = RIGHT;
2058         }
2059
2060       if ((move == RIGHT) && !(p->type & CONST_SET))
2061         {
2062           if (p->right)
2063             {
2064               p = p->right;
2065
2066               if (state != FOUND)
2067                 {
2068                   dot_p = char_p = currentName;
2069                   while ((char_p = strchr (char_p, '.')))
2070                     {
2071                       dot_p = char_p++;
2072                       dot_p++;
2073                     }
2074
2075                   nameLen += strlen (currentName) - (dot_p - currentName);
2076                   *dot_p = 0;
2077
2078                   nameLen -= strlen (p->name);
2079                   if (nameLen > 0)
2080                     strcat (currentName, p->name);
2081                   else
2082                     {
2083                       result = ASN1_MEM_ERROR;
2084                       goto cleanup;
2085                     }
2086
2087                   if (!(strcmp (currentName, elementName)))
2088                     {
2089                       state = FOUND;
2090                       nodeFound = p;
2091                     }
2092                   else
2093                     if (!memcmp
2094                         (currentName, elementName, strlen (currentName)))
2095                     state = SAME_BRANCH;
2096                   else
2097                     state = OTHER_BRANCH;
2098                 }
2099             }
2100           else
2101             move = UP;
2102         }
2103
2104       if (move == UP)
2105         {
2106           p = _asn1_find_up (p);
2107
2108           if (state != FOUND)
2109             {
2110               dot_p = char_p = currentName;
2111               while ((char_p = strchr (char_p, '.')))
2112                 {
2113                   dot_p = char_p++;
2114                   dot_p++;
2115                 }
2116
2117               nameLen += strlen (currentName) - (dot_p - currentName);
2118               *dot_p = 0;
2119
2120               if (!(strcmp (currentName, elementName)))
2121                 {
2122                   state = FOUND;
2123                   nodeFound = p;
2124                 }
2125               else
2126                 if (!memcmp (currentName, elementName, strlen (currentName)))
2127                 state = SAME_BRANCH;
2128               else
2129                 state = OTHER_BRANCH;
2130             }
2131         }
2132     }
2133
2134   _asn1_delete_not_used (*structure);
2135
2136   if (counter > len)
2137     {
2138       result = ASN1_DER_ERROR;
2139       goto cleanup;
2140     }
2141
2142   return ASN1_SUCCESS;
2143
2144 cleanup:
2145   asn1_delete_structure (structure);
2146   return result;
2147 }
2148
2149 /**
2150  * asn1_der_decoding_startEnd:
2151  * @element: pointer to an ASN1 element
2152  * @ider: vector that contains the DER encoding.
2153  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2154  * @name_element: an element of NAME structure.
2155  * @start: the position of the first byte of NAME_ELEMENT decoding
2156  *   (@ider[*start])
2157  * @end: the position of the last byte of NAME_ELEMENT decoding
2158  *  (@ider[*end])
2159  *
2160  * Find the start and end point of an element in a DER encoding
2161  * string. I mean that if you have a der encoding and you have already
2162  * used the function asn1_der_decoding() to fill a structure, it may
2163  * happen that you want to find the piece of string concerning an
2164  * element of the structure.
2165  *
2166  * One example is the sequence "tbsCertificate" inside an X509
2167  * certificate.
2168  *
2169  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2170  *   if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
2171  *   element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2172  *   doesn't match the structure ELEMENT.
2173  **/
2174 int
2175 asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
2176                             const char *name_element, int *start, int *end)
2177 {
2178   asn1_node node, node_to_find, p, p2, p3;
2179   int counter, len2, len3, len4, move, ris;
2180   unsigned char class;
2181   unsigned long tag;
2182   int indefinite;
2183   const unsigned char *der = ider;
2184
2185   node = element;
2186
2187   if (node == NULL)
2188     return ASN1_ELEMENT_NOT_FOUND;
2189
2190   node_to_find = asn1_find_node (node, name_element);
2191
2192   if (node_to_find == NULL)
2193     return ASN1_ELEMENT_NOT_FOUND;
2194
2195   if (node_to_find == node)
2196     {
2197       *start = 0;
2198       *end = len - 1;
2199       return ASN1_SUCCESS;
2200     }
2201
2202   if (node->type & CONST_OPTION)
2203     return ASN1_GENERIC_ERROR;
2204
2205   counter = 0;
2206   move = DOWN;
2207   p = node;
2208   while (1)
2209     {
2210       if (p == NULL)
2211         return ASN1_DER_ERROR;
2212
2213       ris = ASN1_SUCCESS;
2214
2215       if (move != UP)
2216         {
2217           if (p->type & CONST_SET)
2218             {
2219               p2 = _asn1_find_up (p);
2220               if (p2 == NULL)
2221                 return ASN1_DER_ERROR;
2222
2223               len2 = _asn1_strtol (p2->value, NULL, 10);
2224               if (len2 == -1)
2225                 {
2226                   if (!der[counter] && !der[counter + 1])
2227                     {
2228                       p = p2;
2229                       move = UP;
2230                       counter += 2;
2231                       continue;
2232                     }
2233                 }
2234               else if (counter == len2)
2235                 {
2236                   p = p2;
2237                   move = UP;
2238                   continue;
2239                 }
2240               else if (counter > len2)
2241                 return ASN1_DER_ERROR;
2242
2243               p2 = p2->down;
2244
2245               while (p2)
2246                 {
2247                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2248                     {           /* CONTROLLARE */
2249                       if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
2250                         ris =
2251                           _asn1_extract_tag_der (p2, der + counter,
2252                                                  len - counter, &len2);
2253                       else
2254                         {
2255                           p3 = p2->down;
2256                           if (p3 == NULL)
2257                             return ASN1_DER_ERROR;
2258
2259                           ris =
2260                             _asn1_extract_tag_der (p3, der + counter,
2261                                                    len - counter, &len2);
2262                         }
2263                       if (ris == ASN1_SUCCESS)
2264                         {
2265                           p2->type &= ~CONST_NOT_USED;
2266                           p = p2;
2267                           break;
2268                         }
2269                     }
2270                   p2 = p2->right;
2271                 }
2272               if (p2 == NULL)
2273                 return ASN1_DER_ERROR;
2274             }
2275
2276           if (p == node_to_find)
2277             *start = counter;
2278
2279           if (type_field (p->type) == ASN1_ETYPE_CHOICE)
2280             {
2281               p = p->down;
2282               if (p == NULL)
2283                 return ASN1_DER_ERROR;
2284
2285               ris =
2286                 _asn1_extract_tag_der (p, der + counter, len - counter,
2287                                        &len2);
2288               if (p == node_to_find)
2289                 *start = counter;
2290             }
2291
2292           if (ris == ASN1_SUCCESS)
2293             ris =
2294               _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2295           if (ris != ASN1_SUCCESS)
2296             {
2297               if (p->type & CONST_OPTION)
2298                 {
2299                   p->type |= CONST_NOT_USED;
2300                   move = RIGHT;
2301                 }
2302               else if (p->type & CONST_DEFAULT)
2303                 {
2304                   move = RIGHT;
2305                 }
2306               else
2307                 {
2308                   return ASN1_TAG_ERROR;
2309                 }
2310             }
2311           else
2312             counter += len2;
2313         }
2314
2315       if (ris == ASN1_SUCCESS)
2316         {
2317           switch (type_field (p->type))
2318             {
2319             case ASN1_ETYPE_NULL:
2320               if (der[counter])
2321                 return ASN1_DER_ERROR;
2322               counter++;
2323               move = RIGHT;
2324               break;
2325             case ASN1_ETYPE_BOOLEAN:
2326               if (der[counter++] != 1)
2327                 return ASN1_DER_ERROR;
2328               counter++;
2329               move = RIGHT;
2330               break;
2331             case ASN1_ETYPE_OCTET_STRING:
2332               len3 = len - counter;
2333               ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2334               if (ris != ASN1_SUCCESS)
2335                 return ris;
2336               counter += len3;
2337               move = RIGHT;
2338               break;
2339             case ASN1_ETYPE_UTC_TIME:
2340             case ASN1_ETYPE_GENERALIZED_TIME:
2341             case ASN1_ETYPE_OBJECT_ID:
2342             case ASN1_ETYPE_INTEGER:
2343             case ASN1_ETYPE_ENUMERATED:
2344             case ASN1_ETYPE_GENERALSTRING:
2345             case ASN1_ETYPE_NUMERIC_STRING:
2346             case ASN1_ETYPE_IA5_STRING:
2347             case ASN1_ETYPE_TELETEX_STRING:
2348             case ASN1_ETYPE_PRINTABLE_STRING:
2349             case ASN1_ETYPE_UNIVERSAL_STRING:
2350             case ASN1_ETYPE_BMP_STRING:
2351             case ASN1_ETYPE_UTF8_STRING:
2352             case ASN1_ETYPE_VISIBLE_STRING:
2353             case ASN1_ETYPE_BIT_STRING:
2354               len2 =
2355                 asn1_get_length_der (der + counter, len - counter, &len3);
2356               if (len2 < 0)
2357                 return ASN1_DER_ERROR;
2358               counter += len3 + len2;
2359               move = RIGHT;
2360               break;
2361             case ASN1_ETYPE_SEQUENCE:
2362             case ASN1_ETYPE_SET:
2363               if (move != UP)
2364                 {
2365                   len3 =
2366                     asn1_get_length_der (der + counter, len - counter, &len2);
2367                   if (len3 < -1)
2368                     return ASN1_DER_ERROR;
2369                   counter += len2;
2370                   if (len3 == 0)
2371                     move = RIGHT;
2372                   else
2373                     move = DOWN;
2374                 }
2375               else
2376                 {
2377                   if (!der[counter] && !der[counter + 1])       /* indefinite length method */
2378                     counter += 2;
2379                   move = RIGHT;
2380                 }
2381               break;
2382             case ASN1_ETYPE_SEQUENCE_OF:
2383             case ASN1_ETYPE_SET_OF:
2384               if (move != UP)
2385                 {
2386                   len3 =
2387                     asn1_get_length_der (der + counter, len - counter, &len2);
2388                   if (len3 < -1)
2389                     return ASN1_DER_ERROR;
2390                   counter += len2;
2391                   if ((len3 == -1) && !der[counter] && !der[counter + 1])
2392                     counter += 2;
2393                   else if (len3)
2394                     {
2395                       p2 = p->down;
2396                       while ((type_field (p2->type) == ASN1_ETYPE_TAG) ||
2397                              (type_field (p2->type) == ASN1_ETYPE_SIZE))
2398                         p2 = p2->right;
2399                       p = p2;
2400                     }
2401                 }
2402               else
2403                 {
2404                   if (!der[counter] && !der[counter + 1])       /* indefinite length method */
2405                     counter += 2;
2406                 }
2407               move = RIGHT;
2408               break;
2409             case ASN1_ETYPE_ANY:
2410               if (asn1_get_tag_der
2411                   (der + counter, len - counter, &class, &len2,
2412                    &tag) != ASN1_SUCCESS)
2413                 return ASN1_DER_ERROR;
2414               if (counter + len2 > len)
2415                 return ASN1_DER_ERROR;
2416
2417               len4 =
2418                 asn1_get_length_der (der + counter + len2,
2419                                      len - counter - len2, &len3);
2420               if (len4 < -1)
2421                 return ASN1_DER_ERROR;
2422
2423               if (len4 != -1)
2424                 {
2425                   counter += len2 + len4 + len3;
2426                 }
2427               else
2428                 {               /* indefinite length */
2429                   /* Check indefinite lenth method in an EXPLICIT TAG */
2430                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2431                     indefinite = 1;
2432                   else
2433                     indefinite = 0;
2434
2435                   len2 = len - counter;
2436                   ris =
2437                     _asn1_get_indefinite_length_string (der + counter, &len2);
2438                   if (ris != ASN1_SUCCESS)
2439                     return ris;
2440                   counter += len2;
2441
2442                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2443                      an indefinite length method. */
2444                   if (indefinite)
2445                     {
2446                       if (!der[counter] && !der[counter + 1])
2447                         counter += 2;
2448                       else
2449                         return ASN1_DER_ERROR;
2450                     }
2451                 }
2452               move = RIGHT;
2453               break;
2454             default:
2455               move = (move == UP) ? RIGHT : DOWN;
2456               break;
2457             }
2458         }
2459
2460       if ((p == node_to_find) && (move == RIGHT))
2461         {
2462           *end = counter - 1;
2463           return ASN1_SUCCESS;
2464         }
2465
2466       if (p == node && move != DOWN)
2467         break;
2468
2469       if (move == DOWN)
2470         {
2471           if (p->down)
2472             p = p->down;
2473           else
2474             move = RIGHT;
2475         }
2476       if ((move == RIGHT) && !(p->type & CONST_SET))
2477         {
2478           if (p->right)
2479             p = p->right;
2480           else
2481             move = UP;
2482         }
2483       if (move == UP)
2484         p = _asn1_find_up (p);
2485     }
2486
2487   return ASN1_ELEMENT_NOT_FOUND;
2488 }
2489
2490 /**
2491  * asn1_expand_any_defined_by:
2492  * @definitions: ASN1 definitions
2493  * @element: pointer to an ASN1 structure
2494  *
2495  * Expands every "ANY DEFINED BY" element of a structure created from
2496  * a DER decoding process (asn1_der_decoding function). The element
2497  * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2498  * expand the element ANY is the first one following the definition of
2499  * the actual value of the OBJECT IDENTIFIER.
2500  *
2501  * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2502  *   some "ANY DEFINED BY" element couldn't be expanded due to a
2503  *   problem in OBJECT_ID -> TYPE association, or other error codes
2504  *   depending on DER decoding.
2505  **/
2506 int
2507 asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
2508 {
2509   char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2510     value[ASN1_MAX_NAME_SIZE];
2511   int retCode = ASN1_SUCCESS, result;
2512   int len, len2, len3;
2513   asn1_node p, p2, p3, aux = NULL;
2514   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2515
2516   if ((definitions == NULL) || (*element == NULL))
2517     return ASN1_ELEMENT_NOT_FOUND;
2518
2519   strcpy (definitionsName, definitions->name);
2520   strcat (definitionsName, ".");
2521
2522   p = *element;
2523   while (p)
2524     {
2525
2526       switch (type_field (p->type))
2527         {
2528         case ASN1_ETYPE_ANY:
2529           if ((p->type & CONST_DEFINED_BY) && (p->value))
2530             {
2531               /* search the "DEF_BY" element */
2532               p2 = p->down;
2533               while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
2534                 p2 = p2->right;
2535
2536               if (!p2)
2537                 {
2538                   retCode = ASN1_ERROR_TYPE_ANY;
2539                   break;
2540                 }
2541
2542               p3 = _asn1_find_up (p);
2543
2544               if (!p3)
2545                 {
2546                   retCode = ASN1_ERROR_TYPE_ANY;
2547                   break;
2548                 }
2549
2550               p3 = p3->down;
2551               while (p3)
2552                 {
2553                   if (!(strcmp (p3->name, p2->name)))
2554                     break;
2555                   p3 = p3->right;
2556                 }
2557
2558               if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
2559                   (p3->value == NULL))
2560                 {
2561
2562                   p3 = _asn1_find_up (p);
2563                   p3 = _asn1_find_up (p3);
2564
2565                   if (!p3)
2566                     {
2567                       retCode = ASN1_ERROR_TYPE_ANY;
2568                       break;
2569                     }
2570
2571                   p3 = p3->down;
2572
2573                   while (p3)
2574                     {
2575                       if (!(strcmp (p3->name, p2->name)))
2576                         break;
2577                       p3 = p3->right;
2578                     }
2579
2580                   if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
2581                       (p3->value == NULL))
2582                     {
2583                       retCode = ASN1_ERROR_TYPE_ANY;
2584                       break;
2585                     }
2586                 }
2587
2588               /* search the OBJECT_ID into definitions */
2589               p2 = definitions->down;
2590               while (p2)
2591                 {
2592                   if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
2593                       (p2->type & CONST_ASSIGN))
2594                     {
2595                       strcpy (name, definitionsName);
2596                       strcat (name, p2->name);
2597
2598                       len = ASN1_MAX_NAME_SIZE;
2599                       result =
2600                         asn1_read_value (definitions, name, value, &len);
2601
2602                       if ((result == ASN1_SUCCESS)
2603                           && (!_asn1_strcmp (p3->value, value)))
2604                         {
2605                           p2 = p2->right;       /* pointer to the structure to
2606                                                    use for expansion */
2607                           while ((p2) && (p2->type & CONST_ASSIGN))
2608                             p2 = p2->right;
2609
2610                           if (p2)
2611                             {
2612                               strcpy (name, definitionsName);
2613                               strcat (name, p2->name);
2614
2615                               result =
2616                                 asn1_create_element (definitions, name, &aux);
2617                               if (result == ASN1_SUCCESS)
2618                                 {
2619                                   _asn1_cpy_name (aux, p);
2620                                   len2 =
2621                                     asn1_get_length_der (p->value,
2622                                                          p->value_len, &len3);
2623                                   if (len2 < 0)
2624                                     return ASN1_DER_ERROR;
2625
2626                                   result =
2627                                     asn1_der_decoding (&aux, p->value + len3,
2628                                                        len2,
2629                                                        errorDescription);
2630                                   if (result == ASN1_SUCCESS)
2631                                     {
2632
2633                                       _asn1_set_right (aux, p->right);
2634                                       _asn1_set_right (p, aux);
2635
2636                                       result = asn1_delete_structure (&p);
2637                                       if (result == ASN1_SUCCESS)
2638                                         {
2639                                           p = aux;
2640                                           aux = NULL;
2641                                           break;
2642                                         }
2643                                       else
2644                                         {       /* error with asn1_delete_structure */
2645                                           asn1_delete_structure (&aux);
2646                                           retCode = result;
2647                                           break;
2648                                         }
2649                                     }
2650                                   else
2651                                     {   /* error with asn1_der_decoding */
2652                                       retCode = result;
2653                                       break;
2654                                     }
2655                                 }
2656                               else
2657                                 {       /* error with asn1_create_element */
2658                                   retCode = result;
2659                                   break;
2660                                 }
2661                             }
2662                           else
2663                             {   /* error with the pointer to the structure to exapand */
2664                               retCode = ASN1_ERROR_TYPE_ANY;
2665                               break;
2666                             }
2667                         }
2668                     }
2669                   p2 = p2->right;
2670                 }               /* end while */
2671
2672               if (!p2)
2673                 {
2674                   retCode = ASN1_ERROR_TYPE_ANY;
2675                   break;
2676                 }
2677
2678             }
2679           break;
2680         default:
2681           break;
2682         }
2683
2684
2685       if (p->down)
2686         {
2687           p = p->down;
2688         }
2689       else if (p == *element)
2690         {
2691           p = NULL;
2692           break;
2693         }
2694       else if (p->right)
2695         p = p->right;
2696       else
2697         {
2698           while (1)
2699             {
2700               p = _asn1_find_up (p);
2701               if (p == *element)
2702                 {
2703                   p = NULL;
2704                   break;
2705                 }
2706               if (p->right)
2707                 {
2708                   p = p->right;
2709                   break;
2710                 }
2711             }
2712         }
2713     }
2714
2715   return retCode;
2716 }
2717
2718 /**
2719  * asn1_expand_octet_string:
2720  * @definitions: ASN1 definitions
2721  * @element: pointer to an ASN1 structure
2722  * @octetName: name of the OCTECT STRING field to expand.
2723  * @objectName: name of the OBJECT IDENTIFIER field to use to define
2724  *    the type for expansion.
2725  *
2726  * Expands an "OCTET STRING" element of a structure created from a DER
2727  * decoding process (the asn1_der_decoding() function).  The type used
2728  * for expansion is the first one following the definition of the
2729  * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2730  *
2731  * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2732  *   if @objectName or @octetName are not correct,
2733  *   %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2734  *   use for expansion, or other errors depending on DER decoding.
2735  **/
2736 int
2737 asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
2738                           const char *octetName, const char *objectName)
2739 {
2740   char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2741   int retCode = ASN1_SUCCESS, result;
2742   int len, len2, len3;
2743   asn1_node p2, aux = NULL;
2744   asn1_node octetNode = NULL, objectNode = NULL;
2745   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2746
2747   if ((definitions == NULL) || (*element == NULL))
2748     return ASN1_ELEMENT_NOT_FOUND;
2749
2750   octetNode = asn1_find_node (*element, octetName);
2751   if (octetNode == NULL)
2752     return ASN1_ELEMENT_NOT_FOUND;
2753   if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
2754     return ASN1_ELEMENT_NOT_FOUND;
2755   if (octetNode->value == NULL)
2756     return ASN1_VALUE_NOT_FOUND;
2757
2758   objectNode = asn1_find_node (*element, objectName);
2759   if (objectNode == NULL)
2760     return ASN1_ELEMENT_NOT_FOUND;
2761
2762   if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
2763     return ASN1_ELEMENT_NOT_FOUND;
2764
2765   if (objectNode->value == NULL)
2766     return ASN1_VALUE_NOT_FOUND;
2767
2768
2769   /* search the OBJECT_ID into definitions */
2770   p2 = definitions->down;
2771   while (p2)
2772     {
2773       if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
2774           (p2->type & CONST_ASSIGN))
2775         {
2776           strcpy (name, definitions->name);
2777           strcat (name, ".");
2778           strcat (name, p2->name);
2779
2780           len = sizeof (value);
2781           result = asn1_read_value (definitions, name, value, &len);
2782
2783           if ((result == ASN1_SUCCESS)
2784               && (!_asn1_strcmp (objectNode->value, value)))
2785             {
2786
2787               p2 = p2->right;   /* pointer to the structure to
2788                                    use for expansion */
2789               while ((p2) && (p2->type & CONST_ASSIGN))
2790                 p2 = p2->right;
2791
2792               if (p2)
2793                 {
2794                   strcpy (name, definitions->name);
2795                   strcat (name, ".");
2796                   strcat (name, p2->name);
2797
2798                   result = asn1_create_element (definitions, name, &aux);
2799                   if (result == ASN1_SUCCESS)
2800                     {
2801                       _asn1_cpy_name (aux, octetNode);
2802                       len2 =
2803                         asn1_get_length_der (octetNode->value,
2804                                              octetNode->value_len, &len3);
2805                       if (len2 < 0)
2806                         return ASN1_DER_ERROR;
2807
2808                       result =
2809                         asn1_der_decoding (&aux, octetNode->value + len3,
2810                                            len2, errorDescription);
2811                       if (result == ASN1_SUCCESS)
2812                         {
2813
2814                           _asn1_set_right (aux, octetNode->right);
2815                           _asn1_set_right (octetNode, aux);
2816
2817                           result = asn1_delete_structure (&octetNode);
2818                           if (result == ASN1_SUCCESS)
2819                             {
2820                               aux = NULL;
2821                               break;
2822                             }
2823                           else
2824                             {   /* error with asn1_delete_structure */
2825                               asn1_delete_structure (&aux);
2826                               retCode = result;
2827                               break;
2828                             }
2829                         }
2830                       else
2831                         {       /* error with asn1_der_decoding */
2832                           retCode = result;
2833                           break;
2834                         }
2835                     }
2836                   else
2837                     {           /* error with asn1_create_element */
2838                       retCode = result;
2839                       break;
2840                     }
2841                 }
2842               else
2843                 {               /* error with the pointer to the structure to exapand */
2844                   retCode = ASN1_VALUE_NOT_VALID;
2845                   break;
2846                 }
2847             }
2848         }
2849
2850       p2 = p2->right;
2851
2852     }
2853
2854   if (!p2)
2855     retCode = ASN1_VALUE_NOT_VALID;
2856
2857   return retCode;
2858 }
2859
2860 /**
2861  * asn1_decode_simple_der:
2862  * @etype: The type of the string to be encoded (ASN1_ETYPE_)
2863  * @der: the encoded string
2864  * @der_len: the bytes of the encoded string
2865  * @str: a pointer to the data
2866  * @str_len: the length of the data
2867  *
2868  * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
2869  * The output is a pointer inside the @der.
2870  *
2871  * Returns: %ASN1_SUCCESS if successful or an error value. 
2872  **/
2873 int
2874 asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
2875                         const unsigned char **str, unsigned int *str_len)
2876 {
2877   int tag_len, len_len;
2878   const unsigned char* p;
2879   unsigned char class;
2880   unsigned long tag;
2881   long ret;
2882
2883   if (der == NULL || der_len == 0)
2884     return ASN1_VALUE_NOT_VALID;
2885
2886   if (ETYPE_OK(etype) == 0)
2887     return ASN1_VALUE_NOT_VALID;
2888
2889   /* doesn't handle constructed classes */
2890   if (ETYPE_CLASS(etype) != ASN1_CLASS_UNIVERSAL)
2891     return ASN1_VALUE_NOT_VALID;
2892
2893   p = der;
2894   ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
2895   if (ret != ASN1_SUCCESS)
2896     return ret;
2897   
2898   if (class != ETYPE_CLASS(etype) || tag != ETYPE_TAG(etype))
2899     return ASN1_DER_ERROR;
2900
2901   p += tag_len;
2902   der_len -= tag_len;
2903   
2904   ret = asn1_get_length_der (p, der_len, &len_len);
2905   if (ret < 0) 
2906     return ASN1_DER_ERROR;
2907
2908   p += len_len;
2909   der_len -= len_len;
2910   
2911   *str_len = ret;
2912   *str = p;
2913
2914   return ASN1_SUCCESS;
2915 }