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