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