remove -Werror from automake
[platform/upstream/libtasn1.git] / lib / decoding.c
1 /*
2  * Copyright (C) 2002-2014 Free Software Foundation, Inc.
3  *
4  * This file is part of LIBTASN1.
5  *
6  * The LIBTASN1 library is free software; you can redistribute it
7  * and/or modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA
20  */
21
22
23 /*****************************************************/
24 /* File: decoding.c                                  */
25 /* Description: Functions to manage DER decoding     */
26 /*****************************************************/
27
28 #include <int.h>
29 #include <parser_aux.h>
30 #include <gstr.h>
31 #include <structure.h>
32 #include <element.h>
33 #include <limits.h>
34 #include <intprops.h>
35
36 #ifdef DEBUG
37 # define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
38 #else
39 # define warn()
40 #endif
41
42 #define HAVE_TWO(x) (x>=2?1:0)
43
44 #define DECR_LEN(l, s) do { \
45           l -= s; \
46           if (l < 0) { \
47             warn(); \
48             result = ASN1_DER_ERROR; \
49             goto cleanup; \
50           } \
51         } while (0)
52
53 static int
54 _asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len);
55
56 static void
57 _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
58 {
59
60   Estrcpy (ErrorDescription, ":: tag error near element '");
61   _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
62                            ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
63   Estrcat (ErrorDescription, "'");
64
65 }
66
67 /**
68  * asn1_get_length_der:
69  * @der: DER data to decode.
70  * @der_len: Length of DER data to decode.
71  * @len: Output variable containing the length of the DER length field.
72  *
73  * Extract a length field from DER data.
74  *
75  * Returns: Return the decoded length value, or -1 on indefinite
76  *   length, or -2 when the value was too big to fit in a int, or -4
77  *   when the decoded length value plus @len would exceed @der_len.
78  **/
79 long
80 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
81 {
82   unsigned int ans;
83   int k, punt, sum;
84
85   *len = 0;
86   if (der_len <= 0)
87     return 0;
88
89   if (!(der[0] & 128))
90     {
91       /* short form */
92       *len = 1;
93       ans = der[0];
94     }
95   else
96     {
97       /* Long form */
98       k = der[0] & 0x7F;
99       punt = 1;
100       if (k)
101         {                       /* definite length method */
102           ans = 0;
103           while (punt <= k && punt < der_len)
104             {
105               if (INT_MULTIPLY_OVERFLOW (ans, 256))
106                 return -2;
107               ans *= 256;
108
109               if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
110                 return -2;
111               ans += der[punt];
112               punt++;
113             }
114         }
115       else
116         {                       /* indefinite length method */
117           *len = punt;
118           return -1;
119         }
120
121       *len = punt;
122     }
123
124   sum = ans;
125   if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
126     return -2;
127   sum += *len;
128
129   if (sum > der_len)
130     return -4;
131
132   return ans;
133 }
134
135 /**
136  * asn1_get_tag_der:
137  * @der: DER data to decode.
138  * @der_len: Length of DER data to decode.
139  * @cls: Output variable containing decoded class.
140  * @len: Output variable containing the length of the DER TAG data.
141  * @tag: Output variable containing the decoded tag.
142  *
143  * Decode the class and TAG from DER code.
144  *
145  * Returns: Returns %ASN1_SUCCESS on success, or an error.
146  **/
147 int
148 asn1_get_tag_der (const unsigned char *der, int der_len,
149                   unsigned char *cls, int *len, unsigned long *tag)
150 {
151   unsigned int ris;
152   int punt;
153
154   if (der == NULL || der_len < 2 || len == NULL)
155     return ASN1_DER_ERROR;
156
157   *cls = der[0] & 0xE0;
158   if ((der[0] & 0x1F) != 0x1F)
159     {
160       /* short form */
161       *len = 1;
162       ris = der[0] & 0x1F;
163     }
164   else
165     {
166       /* Long form */
167       punt = 1;
168       ris = 0;
169       while (punt < der_len && der[punt] & 128)
170         {
171
172           if (INT_MULTIPLY_OVERFLOW (ris, 128))
173             return ASN1_DER_ERROR;
174           ris *= 128;
175
176           if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
177             return ASN1_DER_ERROR;
178           ris += (der[punt] & 0x7F);
179           punt++;
180         }
181
182       if (punt >= der_len)
183         return ASN1_DER_ERROR;
184
185       if (INT_MULTIPLY_OVERFLOW (ris, 128))
186         return ASN1_DER_ERROR;
187       ris *= 128;
188
189       if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
190         return ASN1_DER_ERROR;
191       ris += (der[punt] & 0x7F);
192       punt++;
193
194       *len = punt;
195     }
196
197   if (tag)
198     *tag = ris;
199   return ASN1_SUCCESS;
200 }
201
202 /**
203  * asn1_get_length_ber:
204  * @ber: BER data to decode.
205  * @ber_len: Length of BER data to decode.
206  * @len: Output variable containing the length of the BER length field.
207  *
208  * Extract a length field from BER data.  The difference to
209  * asn1_get_length_der() is that this function will return a length
210  * even if the value has indefinite encoding.
211  *
212  * Returns: Return the decoded length value, or negative value when
213  *   the value was too big.
214  *
215  * Since: 2.0
216  **/
217 long
218 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
219 {
220   int ret;
221   long err;
222
223   ret = asn1_get_length_der (ber, ber_len, len);
224   if (ret == -1)
225     {                           /* indefinite length method */
226       err = _asn1_get_indefinite_length_string (ber + 1, ber_len, &ret);
227       if (err != ASN1_SUCCESS)
228         return -3;
229     }
230
231   return ret;
232 }
233
234 /**
235  * asn1_get_octet_der:
236  * @der: DER data to decode containing the OCTET SEQUENCE.
237  * @der_len: Length of DER data to decode.
238  * @ret_len: Output variable containing the length of the DER data.
239  * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
240  * @str_size: Length of pre-allocated output buffer.
241  * @str_len: Output variable containing the length of the OCTET SEQUENCE.
242  *
243  * Extract an OCTET SEQUENCE from DER data.
244  *
245  * Returns: Returns %ASN1_SUCCESS on success, or an error.
246  **/
247 int
248 asn1_get_octet_der (const unsigned char *der, int der_len,
249                     int *ret_len, unsigned char *str, int str_size,
250                     int *str_len)
251 {
252   int len_len = 0;
253
254   if (der_len <= 0)
255     return ASN1_GENERIC_ERROR;
256
257   *str_len = asn1_get_length_der (der, der_len, &len_len);
258
259   if (*str_len < 0)
260     return ASN1_DER_ERROR;
261
262   *ret_len = *str_len + len_len;
263   if (str_size >= *str_len)
264     {
265       if (*str_len > 0 && str != NULL)
266         memcpy (str, der + len_len, *str_len);
267     }
268   else
269     {
270       return ASN1_MEM_ERROR;
271     }
272
273   return ASN1_SUCCESS;
274 }
275
276 /* Returns ASN1_SUCCESS on success or an error code on error.
277  */
278 static int
279 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
280                     char *str, int str_size)
281 {
282   int len_len, str_len;
283
284   if (der_len <= 0 || str == NULL)
285     return ASN1_DER_ERROR;
286
287   str_len = asn1_get_length_der (der, der_len, &len_len);
288   if (str_len <= 0 || str_size < str_len)
289     return ASN1_DER_ERROR;
290
291   memcpy (str, der + len_len, str_len);
292   str[str_len] = 0;
293   *ret_len = str_len + len_len;
294
295   return ASN1_SUCCESS;
296 }
297
298 static int
299 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
300                         char *str, int str_size)
301 {
302   int len_len, len, k;
303   int leading;
304   char temp[LTOSTR_MAX_SIZE];
305   unsigned long val, val1;
306
307   *ret_len = 0;
308   if (str && str_size > 0)
309     str[0] = 0;                 /* no oid */
310
311   if (str == NULL || der_len <= 0)
312     return ASN1_GENERIC_ERROR;
313
314   len = asn1_get_length_der (der, der_len, &len_len);
315
316   if (len <= 0 || len + len_len > der_len)
317     return ASN1_DER_ERROR;
318
319   val1 = der[len_len] / 40;
320   val = der[len_len] - val1 * 40;
321
322   _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
323   _asn1_str_cat (str, str_size, ".");
324   _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
325
326   val = 0;
327   leading = 1;
328   for (k = 1; k < len; k++)
329     {
330       /* X.690 mandates that the leading byte must never be 0x80
331        */
332       if (leading != 0 && der[len_len + k] == 0x80)
333         return ASN1_DER_ERROR;
334       leading = 0;
335
336       /* check for wrap around */
337       if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
338         return ASN1_DER_ERROR;
339
340       val = val << 7;
341       val |= der[len_len + k] & 0x7F;
342
343       if (!(der[len_len + k] & 0x80))
344         {
345           _asn1_str_cat (str, str_size, ".");
346           _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
347           val = 0;
348           leading = 1;
349         }
350     }
351
352   if (INT_ADD_OVERFLOW (len, len_len))
353     return ASN1_DER_ERROR;
354
355   *ret_len = len + len_len;
356
357   return ASN1_SUCCESS;
358 }
359
360 /**
361  * asn1_get_bit_der:
362  * @der: DER data to decode containing the BIT SEQUENCE.
363  * @der_len: Length of DER data to decode.
364  * @ret_len: Output variable containing the length of the DER data.
365  * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
366  * @str_size: Length of pre-allocated output buffer.
367  * @bit_len: Output variable containing the size of the BIT SEQUENCE.
368  *
369  * Extract a BIT SEQUENCE from DER data.
370  *
371  * Returns: Return %ASN1_SUCCESS on success, or an error.
372  **/
373 int
374 asn1_get_bit_der (const unsigned char *der, int der_len,
375                   int *ret_len, unsigned char *str, int str_size,
376                   int *bit_len)
377 {
378   int len_len = 0, len_byte;
379
380   if (der_len <= 0)
381     return ASN1_GENERIC_ERROR;
382
383   len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
384   if (len_byte < 0)
385     return ASN1_DER_ERROR;
386
387   *ret_len = len_byte + len_len + 1;
388   *bit_len = len_byte * 8 - der[len_len];
389
390   if (*bit_len < 0)
391     return ASN1_DER_ERROR;
392
393   if (str_size >= len_byte)
394     {
395       if (len_byte > 0 && str)
396         memcpy (str, der + len_len + 1, len_byte);
397     }
398   else
399     {
400       return ASN1_MEM_ERROR;
401     }
402
403   return ASN1_SUCCESS;
404 }
405
406
407 static int
408 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
409                        int *ret_len)
410 {
411   asn1_node p;
412   int counter, len2, len3, is_tag_implicit;
413   int result;
414   unsigned long tag, tag_implicit = 0;
415   unsigned char class, class2, class_implicit = 0;
416
417   if (der_len <= 0)
418     return ASN1_GENERIC_ERROR;
419
420   counter = is_tag_implicit = 0;
421
422   if (node->type & CONST_TAG)
423     {
424       p = node->down;
425       while (p)
426         {
427           if (type_field (p->type) == ASN1_ETYPE_TAG)
428             {
429               if (p->type & CONST_APPLICATION)
430                 class2 = ASN1_CLASS_APPLICATION;
431               else if (p->type & CONST_UNIVERSAL)
432                 class2 = ASN1_CLASS_UNIVERSAL;
433               else if (p->type & CONST_PRIVATE)
434                 class2 = ASN1_CLASS_PRIVATE;
435               else
436                 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
437
438               if (p->type & CONST_EXPLICIT)
439                 {
440                   if (asn1_get_tag_der
441                       (der + counter, der_len, &class, &len2,
442                        &tag) != ASN1_SUCCESS)
443                     return ASN1_DER_ERROR;
444
445                   DECR_LEN(der_len, len2);
446                   counter += len2;
447
448                   len3 =
449                     asn1_get_length_ber (der + counter, der_len,
450                                          &len2);
451                   if (len3 < 0)
452                     return ASN1_DER_ERROR;
453
454                   DECR_LEN(der_len, len2);
455                   counter += len2;
456
457                   if (!is_tag_implicit)
458                     {
459                       if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
460                           (tag != strtoul ((char *) p->value, NULL, 10)))
461                         return ASN1_TAG_ERROR;
462                     }
463                   else
464                     {           /* ASN1_TAG_IMPLICIT */
465                       if ((class != class_implicit) || (tag != tag_implicit))
466                         return ASN1_TAG_ERROR;
467                     }
468                   is_tag_implicit = 0;
469                 }
470               else
471                 {               /* ASN1_TAG_IMPLICIT */
472                   if (!is_tag_implicit)
473                     {
474                       if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
475                           (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
476                           || (type_field (node->type) == ASN1_ETYPE_SET)
477                           || (type_field (node->type) == ASN1_ETYPE_SET_OF))
478                         class2 |= ASN1_CLASS_STRUCTURED;
479                       class_implicit = class2;
480                       tag_implicit = strtoul ((char *) p->value, NULL, 10);
481                       is_tag_implicit = 1;
482                     }
483                 }
484             }
485           p = p->right;
486         }
487     }
488
489   if (is_tag_implicit)
490     {
491       if (asn1_get_tag_der
492           (der + counter, der_len, &class, &len2,
493            &tag) != ASN1_SUCCESS)
494         return ASN1_DER_ERROR;
495
496       DECR_LEN(der_len, len2);
497
498       if ((class != class_implicit) || (tag != tag_implicit))
499         {
500           if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
501             {
502               class_implicit |= ASN1_CLASS_STRUCTURED;
503               if ((class != class_implicit) || (tag != tag_implicit))
504                 return ASN1_TAG_ERROR;
505             }
506           else
507             return ASN1_TAG_ERROR;
508         }
509     }
510   else
511     {
512       unsigned type = type_field (node->type);
513       if (type == ASN1_ETYPE_TAG)
514         {
515           *ret_len = 0;
516           return ASN1_SUCCESS;
517         }
518
519       if (asn1_get_tag_der
520           (der + counter, der_len, &class, &len2,
521            &tag) != ASN1_SUCCESS)
522         return ASN1_DER_ERROR;
523
524       DECR_LEN(der_len, len2);
525
526       switch (type)
527         {
528         case ASN1_ETYPE_NULL:
529         case ASN1_ETYPE_BOOLEAN:
530         case ASN1_ETYPE_INTEGER:
531         case ASN1_ETYPE_ENUMERATED:
532         case ASN1_ETYPE_OBJECT_ID:
533         case ASN1_ETYPE_GENERALSTRING:
534         case ASN1_ETYPE_NUMERIC_STRING:
535         case ASN1_ETYPE_IA5_STRING:
536         case ASN1_ETYPE_TELETEX_STRING:
537         case ASN1_ETYPE_PRINTABLE_STRING:
538         case ASN1_ETYPE_UNIVERSAL_STRING:
539         case ASN1_ETYPE_BMP_STRING:
540         case ASN1_ETYPE_UTF8_STRING:
541         case ASN1_ETYPE_VISIBLE_STRING:
542         case ASN1_ETYPE_BIT_STRING:
543         case ASN1_ETYPE_SEQUENCE:
544         case ASN1_ETYPE_SEQUENCE_OF:
545         case ASN1_ETYPE_SET:
546         case ASN1_ETYPE_SET_OF:
547         case ASN1_ETYPE_GENERALIZED_TIME:
548         case ASN1_ETYPE_UTC_TIME:
549           if ((class != _asn1_tags[type].class)
550               || (tag != _asn1_tags[type].tag))
551             return ASN1_DER_ERROR;
552           break;
553
554         case ASN1_ETYPE_OCTET_STRING:
555           /* OCTET STRING is handled differently to allow
556            * BER encodings (structured class). */
557           if (((class != ASN1_CLASS_UNIVERSAL)
558                && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
559               || (tag != ASN1_TAG_OCTET_STRING))
560             return ASN1_DER_ERROR;
561           break;
562         case ASN1_ETYPE_ANY:
563           counter -= len2;
564           break;
565         case ASN1_ETYPE_CHOICE:
566           counter -= len2;
567           break;
568         default:
569           return ASN1_DER_ERROR;
570           break;
571         }
572     }
573
574   counter += len2;
575   *ret_len = counter;
576   return ASN1_SUCCESS;
577
578 cleanup:
579   return result;
580 }
581
582 static int
583 extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len,
584                        int *ret_len)
585 {
586 asn1_node p;
587 int ris = ASN1_DER_ERROR;
588
589   if (type_field (node->type) == ASN1_ETYPE_CHOICE)
590     {
591       p = node->down;
592       while (p)
593         {
594           ris = _asn1_extract_tag_der (p, der, der_len, ret_len);
595           if (ris == ASN1_SUCCESS)
596             break;
597           p = p->right;
598         }
599
600       *ret_len = 0;
601       return ris;
602     }
603   else
604     return _asn1_extract_tag_der (node, der, der_len, ret_len);
605 }
606
607 static int
608 _asn1_delete_not_used (asn1_node node)
609 {
610   asn1_node p, p2;
611
612   if (node == NULL)
613     return ASN1_ELEMENT_NOT_FOUND;
614
615   p = node;
616   while (p)
617     {
618       if (p->type & CONST_NOT_USED)
619         {
620           p2 = NULL;
621           if (p != node)
622             {
623               p2 = _asn1_find_left (p);
624               if (!p2)
625                 p2 = _asn1_get_up (p);
626             }
627           asn1_delete_structure (&p);
628           p = p2;
629         }
630
631       if (!p)
632         break;                  /* reach node */
633
634       if (p->down)
635         {
636           p = p->down;
637         }
638       else
639         {
640           if (p == node)
641             p = NULL;
642           else if (p->right)
643             p = p->right;
644           else
645             {
646               while (1)
647                 {
648                   p = _asn1_get_up (p);
649                   if (p == node)
650                     {
651                       p = NULL;
652                       break;
653                     }
654                   if (p->right)
655                     {
656                       p = p->right;
657                       break;
658                     }
659                 }
660             }
661         }
662     }
663   return ASN1_SUCCESS;
664 }
665
666 static int
667 _asn1_extract_der_octet (asn1_node node, const unsigned char *der,
668                          int der_len)
669 {
670   int len2, len3;
671   int counter, counter_end;
672   int result;
673
674   len2 = asn1_get_length_der (der, der_len, &len3);
675   if (len2 < -1)
676     return ASN1_DER_ERROR;
677
678   counter = len3 + 1;
679
680   if (len2 == -1)
681     counter_end = der_len - 2;
682   else
683     counter_end = der_len;
684
685   while (counter < counter_end)
686     {
687       len2 = asn1_get_length_der (der + counter, der_len, &len3);
688
689       if (len2 < -1)
690         return ASN1_DER_ERROR;
691
692       if (len2 >= 0)
693         {
694           DECR_LEN(der_len, len2+len3);
695           _asn1_append_value (node, der + counter + len3, len2);
696         }
697       else
698         {                       /* indefinite */
699           DECR_LEN(der_len, len3);
700           result =
701             _asn1_extract_der_octet (node, der + counter + len3,
702                                      der_len);
703           if (result != ASN1_SUCCESS)
704             return result;
705           len2 = 0;
706         }
707
708       DECR_LEN(der_len, 1);
709       counter += len2 + len3 + 1;
710     }
711
712   return ASN1_SUCCESS;
713
714 cleanup:
715   return result;
716 }
717
718 static int
719 _asn1_get_octet_string (asn1_node node, const unsigned char *der, int der_len, int *len)
720 {
721   int len2, len3, counter, tot_len, indefinite;
722   int result;
723
724   counter = 0;
725
726   if (*(der - 1) & ASN1_CLASS_STRUCTURED)
727     {
728       tot_len = 0;
729       indefinite = asn1_get_length_der (der, der_len, &len3);
730       if (indefinite < -1)
731         return ASN1_DER_ERROR;
732
733       counter += len3;
734       DECR_LEN(der_len, len3);
735
736       if (indefinite >= 0)
737         indefinite += len3;
738
739       while (1)
740         {
741           if (indefinite == -1)
742             {
743               if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
744                 {
745                   counter += 2;
746                   DECR_LEN(der_len, 2);
747                   break;
748                 }
749             }
750           else if (counter >= indefinite)
751             break;
752
753           DECR_LEN(der_len, 1);
754           if (der[counter] != ASN1_TAG_OCTET_STRING)
755             return ASN1_DER_ERROR;
756
757           counter++;
758
759           len2 = asn1_get_length_der (der + counter, der_len, &len3);
760           if (len2 <= 0)
761             return ASN1_DER_ERROR;
762
763           DECR_LEN(der_len, len3 + len2);
764           counter += len3 + len2;
765
766           tot_len += len2;
767         }
768
769       /* copy */
770       if (node)
771         {
772           unsigned char temp[ASN1_MAX_LENGTH_SIZE];
773           int ret;
774
775           len2 = sizeof (temp);
776
777           asn1_length_der (tot_len, temp, &len2);
778           _asn1_set_value (node, temp, len2);
779
780           ret = _asn1_extract_der_octet (node, der, der_len);
781           if (ret != ASN1_SUCCESS)
782             return ret;
783
784         }
785     }
786   else
787     {                           /* NOT STRUCTURED */
788       len2 = asn1_get_length_der (der, der_len, &len3);
789       if (len2 < 0)
790         return ASN1_DER_ERROR;
791
792       DECR_LEN(der_len, len3+len2);
793       counter = len3 + len2;
794       if (node)
795         _asn1_set_value (node, der, counter);
796     }
797
798   *len = counter;
799   return ASN1_SUCCESS;
800
801 cleanup:
802   return result;
803 }
804
805 static int
806 _asn1_get_indefinite_length_string (const unsigned char *der,
807                                     int der_len, int *len)
808 {
809   int len2, len3, counter, indefinite;
810   int result;
811   unsigned long tag;
812   unsigned char class;
813
814   counter = indefinite = 0;
815
816   while (1)
817     {
818       if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
819         {
820           counter += 2;
821           DECR_LEN(der_len, 2);
822
823           indefinite--;
824           if (indefinite <= 0)
825             break;
826           else
827             continue;
828         }
829
830       if (asn1_get_tag_der
831           (der + counter, der_len, &class, &len2,
832            &tag) != ASN1_SUCCESS)
833         return ASN1_DER_ERROR;
834
835       DECR_LEN(der_len, len2);
836       counter += len2;
837
838       len2 = asn1_get_length_der (der + counter, der_len, &len3);
839       if (len2 < -1)
840         return ASN1_DER_ERROR;
841
842       if (len2 == -1)
843         {
844           indefinite++;
845           counter += 1;
846           DECR_LEN(der_len, 1);
847         }
848       else
849         {
850           counter += len2 + len3;
851           DECR_LEN(der_len, len2+len3);
852         }
853     }
854
855   *len = counter;
856   return ASN1_SUCCESS;
857
858 cleanup:
859   return result;
860 }
861
862 static void delete_unneeded_choice_fields(asn1_node p)
863 {
864   asn1_node p2;
865
866   while (p->right)
867     {
868       p2 = p->right;
869       asn1_delete_structure (&p2);
870     }
871 }
872
873
874
875 /**
876  * asn1_der_decoding:
877  * @element: pointer to an ASN1 structure.
878  * @ider: vector that contains the DER encoding.
879  * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1].
880  * @errorDescription: null-terminated string contains details when an
881  *   error occurred.
882  *
883  * Fill the structure *@element with values of a DER encoding
884  * string. The structure must just be created with function
885  * asn1_create_element(). 
886  *
887  * Note that the *@element variable is provided as a pointer for
888  * historical reasons.
889  *
890  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
891  *   if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
892  *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
893  *   name (*@ELEMENT deleted).
894  **/
895 int
896 asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
897                    char *errorDescription)
898 {
899   asn1_node node, p, p2, p3;
900   char temp[128];
901   int counter, len2, len3, len4, move, ris, tlen;
902   asn1_node ptail = NULL;
903   unsigned char class;
904   unsigned long tag;
905   int indefinite, result, total_len = ider_len;
906   const unsigned char *der = ider;
907
908   node = *element;
909
910   if (errorDescription != NULL)
911     errorDescription[0] = 0;
912
913   if (node == NULL)
914     return ASN1_ELEMENT_NOT_FOUND;
915
916   if (node->type & CONST_OPTION)
917     {
918       result = ASN1_GENERIC_ERROR;
919       warn();
920       goto cleanup;
921     }
922
923   counter = 0;
924   move = DOWN;
925   p = node;
926   while (1)
927     {
928       ris = ASN1_SUCCESS;
929       if (move != UP)
930         {
931           if (p->type & CONST_SET)
932             {
933               p2 = _asn1_get_up (p);
934               len2 = p2->tmp_ival;
935               if (len2 == -1)
936                 {
937                   if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1])
938                     {
939                       p = p2;
940                       move = UP;
941                       counter += 2;
942                       DECR_LEN(ider_len, 2);
943                       continue;
944                     }
945                 }
946               else if (counter == len2)
947                 {
948                   p = p2;
949                   move = UP;
950                   continue;
951                 }
952               else if (counter > len2)
953                 {
954                   result = ASN1_DER_ERROR;
955                   warn();
956                   goto cleanup;
957                 }
958               p2 = p2->down;
959               while (p2)
960                 {
961                   if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
962                     {
963                       ris =
964                           extract_tag_der_recursive (p2, der + counter,
965                                                      ider_len, &len2);
966                       if (ris == ASN1_SUCCESS)
967                         {
968                           p2->type &= ~CONST_NOT_USED;
969                           p = p2;
970                           break;
971                         }
972                     }
973                   p2 = p2->right;
974                 }
975               if (p2 == NULL)
976                 {
977                   result = ASN1_DER_ERROR;
978                   warn();
979                   goto cleanup;
980                 }
981             }
982
983           /* the position in the DER structure this starts */
984           p->start = counter;
985           p->end = total_len;
986
987           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
988             {
989               p2 = _asn1_get_up (p);
990               len2 = p2->tmp_ival;
991               if (counter == len2)
992                 {
993                   if (p->right)
994                     {
995                       p2 = p->right;
996                       move = RIGHT;
997                     }
998                   else
999                     move = UP;
1000
1001                   if (p->type & CONST_OPTION)
1002                     asn1_delete_structure (&p);
1003
1004                   p = p2;
1005                   continue;
1006                 }
1007             }
1008
1009           if (type_field (p->type) == ASN1_ETYPE_CHOICE)
1010             {
1011               while (p->down)
1012                 {
1013                   ris =
1014                       extract_tag_der_recursive (p->down, der + counter,
1015                                                  ider_len, &len2);
1016
1017                   if (ris == ASN1_SUCCESS)
1018                     {
1019                       delete_unneeded_choice_fields(p->down);
1020                       break;
1021                     }
1022                   else if (ris == ASN1_ERROR_TYPE_ANY)
1023                     {
1024                       result = ASN1_ERROR_TYPE_ANY;
1025                       warn();
1026                       goto cleanup;
1027                     }
1028                   else
1029                     {
1030                       p2 = p->down;
1031                       asn1_delete_structure (&p2);
1032                     }
1033                 }
1034
1035               if (p->down == NULL)
1036                 {
1037                   if (!(p->type & CONST_OPTION))
1038                     {
1039                       result = ASN1_DER_ERROR;
1040                       warn();
1041                       goto cleanup;
1042                     }
1043                 }
1044               else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
1045                 p = p->down;
1046
1047               p->start = counter;
1048             }
1049
1050           if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1051             {
1052               p2 = _asn1_get_up (p);
1053               len2 = p2->tmp_ival;
1054
1055               if ((len2 != -1) && (counter > len2))
1056                 ris = ASN1_TAG_ERROR;
1057             }
1058
1059           if (ris == ASN1_SUCCESS)
1060             ris =
1061               extract_tag_der_recursive (p, der + counter, ider_len, &len2);
1062
1063           if (ris != ASN1_SUCCESS)
1064             {
1065               if (p->type & CONST_OPTION)
1066                 {
1067                   p->type |= CONST_NOT_USED;
1068                   move = RIGHT;
1069                 }
1070               else if (p->type & CONST_DEFAULT)
1071                 {
1072                   _asn1_set_value (p, NULL, 0);
1073                   move = RIGHT;
1074                 }
1075               else
1076                 {
1077                   if (errorDescription != NULL)
1078                     _asn1_error_description_tag_error (p, errorDescription);
1079
1080                   result = ASN1_TAG_ERROR;
1081                   warn();
1082                   goto cleanup;
1083                 }
1084             }
1085           else
1086             {
1087               DECR_LEN(ider_len, len2);
1088               counter += len2;
1089             }
1090         }
1091
1092       if (ris == ASN1_SUCCESS)
1093         {
1094           switch (type_field (p->type))
1095             {
1096             case ASN1_ETYPE_NULL:
1097               DECR_LEN(ider_len, 1);
1098               if (der[counter])
1099                 {
1100                   result = ASN1_DER_ERROR;
1101                   warn();
1102                   goto cleanup;
1103                 }
1104               counter++;
1105               move = RIGHT;
1106               break;
1107             case ASN1_ETYPE_BOOLEAN:
1108               DECR_LEN(ider_len, 2);
1109
1110               if (der[counter++] != 1)
1111                 {
1112                   result = ASN1_DER_ERROR;
1113                   warn();
1114                   goto cleanup;
1115                 }
1116               if (der[counter++] == 0)
1117                 _asn1_set_value (p, "F", 1);
1118               else
1119                 _asn1_set_value (p, "T", 1);
1120               move = RIGHT;
1121               break;
1122             case ASN1_ETYPE_INTEGER:
1123             case ASN1_ETYPE_ENUMERATED:
1124               len2 =
1125                 asn1_get_length_der (der + counter, ider_len, &len3);
1126               if (len2 < 0)
1127                 {
1128                   result = ASN1_DER_ERROR;
1129                   warn();
1130                   goto cleanup;
1131                 }
1132
1133               DECR_LEN(ider_len, len3+len2);
1134
1135               _asn1_set_value (p, der + counter, len3 + len2);
1136               counter += len3 + len2;
1137               move = RIGHT;
1138               break;
1139             case ASN1_ETYPE_OBJECT_ID:
1140               result =
1141                 _asn1_get_objectid_der (der + counter, ider_len, &len2,
1142                                         temp, sizeof (temp));
1143               if (result != ASN1_SUCCESS)
1144                 {
1145                   warn();
1146                   goto cleanup;
1147                 }
1148
1149               DECR_LEN(ider_len, len2);
1150
1151               tlen = strlen (temp);
1152               if (tlen > 0)
1153                 _asn1_set_value (p, temp, tlen + 1);
1154
1155               counter += len2;
1156               move = RIGHT;
1157               break;
1158             case ASN1_ETYPE_GENERALIZED_TIME:
1159             case ASN1_ETYPE_UTC_TIME:
1160               result =
1161                 _asn1_get_time_der (der + counter, ider_len, &len2, temp,
1162                                     sizeof (temp) - 1);
1163               if (result != ASN1_SUCCESS)
1164                 {
1165                   warn();
1166                   goto cleanup;
1167                 }
1168
1169               DECR_LEN(ider_len, len2);
1170
1171               tlen = strlen (temp);
1172               if (tlen > 0)
1173                 _asn1_set_value (p, temp, tlen);
1174
1175               counter += len2;
1176               move = RIGHT;
1177               break;
1178             case ASN1_ETYPE_OCTET_STRING:
1179               result = _asn1_get_octet_string (p, der + counter, ider_len, &len3);
1180               if (result != ASN1_SUCCESS)
1181                 {
1182                   warn();
1183                   goto cleanup;
1184                 }
1185
1186               DECR_LEN(ider_len, len3);
1187               counter += len3;
1188               move = RIGHT;
1189               break;
1190             case ASN1_ETYPE_GENERALSTRING:
1191             case ASN1_ETYPE_NUMERIC_STRING:
1192             case ASN1_ETYPE_IA5_STRING:
1193             case ASN1_ETYPE_TELETEX_STRING:
1194             case ASN1_ETYPE_PRINTABLE_STRING:
1195             case ASN1_ETYPE_UNIVERSAL_STRING:
1196             case ASN1_ETYPE_BMP_STRING:
1197             case ASN1_ETYPE_UTF8_STRING:
1198             case ASN1_ETYPE_VISIBLE_STRING:
1199             case ASN1_ETYPE_BIT_STRING:
1200               len2 =
1201                 asn1_get_length_der (der + counter, ider_len, &len3);
1202               if (len2 < 0)
1203                 {
1204                   result = ASN1_DER_ERROR;
1205                   warn();
1206                   goto cleanup;
1207                 }
1208
1209               DECR_LEN(ider_len, len3+len2);
1210
1211               _asn1_set_value (p, der + counter, len3 + len2);
1212               counter += len3 + len2;
1213               move = RIGHT;
1214               break;
1215             case ASN1_ETYPE_SEQUENCE:
1216             case ASN1_ETYPE_SET:
1217               if (move == UP)
1218                 {
1219                   len2 = p->tmp_ival;
1220                   p->tmp_ival = 0;
1221                   if (len2 == -1)
1222                     {           /* indefinite length method */
1223                       DECR_LEN(ider_len, 2);
1224                       if ((der[counter]) || der[counter + 1])
1225                         {
1226                           result = ASN1_DER_ERROR;
1227                           warn();
1228                           goto cleanup;
1229                         }
1230                       counter += 2;
1231                     }
1232                   else
1233                     {           /* definite length method */
1234                       if (len2 != counter)
1235                         {
1236                           result = ASN1_DER_ERROR;
1237                           warn();
1238                           goto cleanup;
1239                         }
1240                     }
1241                   move = RIGHT;
1242                 }
1243               else
1244                 {               /* move==DOWN || move==RIGHT */
1245                   len3 =
1246                     asn1_get_length_der (der + counter, ider_len, &len2);
1247                   if (len3 < -1)
1248                     {
1249                       result = ASN1_DER_ERROR;
1250                       warn();
1251                       goto cleanup;
1252                     }
1253
1254                   DECR_LEN(ider_len, len2);
1255                   counter += len2;
1256
1257                   if (len3 > 0)
1258                     {
1259                       p->tmp_ival = counter + len3;
1260                       move = DOWN;
1261                     }
1262                   else if (len3 == 0)
1263                     {
1264                       p2 = p->down;
1265                       while (p2)
1266                         {
1267                           if (type_field (p2->type) != ASN1_ETYPE_TAG)
1268                             {
1269                               p3 = p2->right;
1270                               asn1_delete_structure (&p2);
1271                               p2 = p3;
1272                             }
1273                           else
1274                             p2 = p2->right;
1275                         }
1276                       move = RIGHT;
1277                     }
1278                   else
1279                     {           /* indefinite length method */
1280                       p->tmp_ival = -1;
1281                       move = DOWN;
1282                     }
1283                 }
1284               break;
1285             case ASN1_ETYPE_SEQUENCE_OF:
1286             case ASN1_ETYPE_SET_OF:
1287               if (move == UP)
1288                 {
1289                   len2 = p->tmp_ival;
1290                   if (len2 == -1)
1291                     {           /* indefinite length method */
1292                       if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
1293                         {
1294                           _asn1_append_sequence_set (p, &ptail);
1295                           p = ptail;
1296                           move = RIGHT;
1297                           continue;
1298                         }
1299
1300                       p->tmp_ival = 0;
1301                       ptail = NULL; /* finished decoding this structure */
1302                       DECR_LEN(ider_len, 2);
1303                       counter += 2;
1304                     }
1305                   else
1306                     {           /* definite length method */
1307                       if (len2 > counter)
1308                         {
1309                           _asn1_append_sequence_set (p, &ptail);
1310                           p = ptail;
1311                           move = RIGHT;
1312                           continue;
1313                         }
1314
1315                       p->tmp_ival = 0;
1316                       ptail = NULL; /* finished decoding this structure */
1317
1318                       if (len2 != counter)
1319                         {
1320                           result = ASN1_DER_ERROR;
1321                           warn();
1322                           goto cleanup;
1323                         }
1324                     }
1325                 }
1326               else
1327                 {               /* move==DOWN || move==RIGHT */
1328                   len3 =
1329                     asn1_get_length_der (der + counter, ider_len, &len2);
1330                   if (len3 < -1)
1331                     {
1332                       result = ASN1_DER_ERROR;
1333                       warn();
1334                       goto cleanup;
1335                     }
1336
1337                   DECR_LEN(ider_len, len2);
1338                   counter += len2;
1339                   if (len3)
1340                     {
1341                       if (len3 > 0)
1342                         {       /* definite length method */
1343                           p->tmp_ival = counter + len3;
1344                         }
1345                       else
1346                         {       /* indefinite length method */
1347                           p->tmp_ival = -1;
1348                         }
1349                       p2 = p->down;
1350                       while ((type_field (p2->type) == ASN1_ETYPE_TAG)
1351                              || (type_field (p2->type) == ASN1_ETYPE_SIZE))
1352                         p2 = p2->right;
1353                       if (p2->right == NULL)
1354                         _asn1_append_sequence_set (p, &ptail);
1355                       p = p2;
1356                     }
1357                 }
1358               move = RIGHT;
1359               break;
1360             case ASN1_ETYPE_ANY:
1361               if (asn1_get_tag_der
1362                   (der + counter, ider_len, &class, &len2,
1363                    &tag) != ASN1_SUCCESS)
1364                 {
1365                   result = ASN1_DER_ERROR;
1366                   warn();
1367                   goto cleanup;
1368                 }
1369
1370               DECR_LEN(ider_len, len2);
1371
1372               len4 =
1373                 asn1_get_length_der (der + counter + len2,
1374                                      ider_len, &len3);
1375               if (len4 < -1)
1376                 {
1377                   result = ASN1_DER_ERROR;
1378                   warn();
1379                   goto cleanup;
1380                 }
1381               if (len4 != -1) /* definite */
1382                 {
1383                   len2 += len4;
1384
1385                   DECR_LEN(ider_len, len4+len3);
1386                   _asn1_set_value_lv (p, der + counter, len2 + len3);
1387                   counter += len2 + len3;
1388                 }
1389               else /* == -1 */
1390                 {               /* indefinite length */
1391                   ider_len += len2; /* undo DECR_LEN */
1392
1393                   if (counter == 0)
1394                     {
1395                       result = ASN1_DER_ERROR;
1396                       warn();
1397                       goto cleanup;
1398                     }
1399
1400                   /* Check indefinite lenth method in an EXPLICIT TAG */
1401                   if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1402                     indefinite = 1;
1403                   else
1404                     indefinite = 0;
1405
1406                   result =
1407                     _asn1_get_indefinite_length_string (der + counter, ider_len, &len2);
1408                   if (result != ASN1_SUCCESS)
1409                     {
1410                       warn();
1411                       goto cleanup;
1412                     }
1413
1414                   DECR_LEN(ider_len, len2);
1415                   _asn1_set_value_lv (p, der + counter, len2);
1416                   counter += len2;
1417
1418                   /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1419                      an indefinite length method. */
1420                   if (indefinite)
1421                     {
1422                       DECR_LEN(ider_len, 2);
1423                       if (!der[counter] && !der[counter + 1])
1424                         {
1425                           counter += 2;
1426                         }
1427                       else
1428                         {
1429                           result = ASN1_DER_ERROR;
1430                           warn();
1431                           goto cleanup;
1432                         }
1433                     }
1434                 }
1435               move = RIGHT;
1436               break;
1437             default:
1438               move = (move == UP) ? RIGHT : DOWN;
1439               break;
1440             }
1441         }
1442
1443       if (p)
1444         {
1445           p->end = counter - 1;
1446         }
1447
1448       if (p == node && move != DOWN)
1449         break;
1450
1451       if (move == DOWN)
1452         {
1453           if (p->down)
1454             p = p->down;
1455           else
1456             move = RIGHT;
1457         }
1458       if ((move == RIGHT) && !(p->type & CONST_SET))
1459         {
1460           if (p->right)
1461             p = p->right;
1462           else
1463             move = UP;
1464         }
1465       if (move == UP)
1466         p = _asn1_get_up (p);
1467     }
1468
1469   _asn1_delete_not_used (*element);
1470
1471   if (ider_len != 0)
1472     {
1473       warn();
1474       result = ASN1_DER_ERROR;
1475       goto cleanup;
1476     }
1477
1478   return ASN1_SUCCESS;
1479
1480 cleanup:
1481   asn1_delete_structure (element);
1482   return result;
1483 }
1484
1485 #define FOUND        1
1486 #define SAME_BRANCH  2
1487 #define OTHER_BRANCH 3
1488 #define EXIT         4
1489
1490 /**
1491  * asn1_der_decoding_element:
1492  * @structure: pointer to an ASN1 structure
1493  * @elementName: name of the element to fill
1494  * @ider: vector that contains the DER encoding of the whole structure.
1495  * @len: number of bytes of *der: der[0]..der[len-1]
1496  * @errorDescription: null-terminated string contains details when an
1497  *   error occurred.
1498  *
1499  * Fill the element named @ELEMENTNAME with values of a DER encoding
1500  * string.  The structure must just be created with function
1501  * asn1_create_element().  The DER vector must contain the encoding
1502  * string of the whole @STRUCTURE.  If an error occurs during the
1503  * decoding procedure, the *@STRUCTURE is deleted and set equal to
1504  * %NULL.
1505  *
1506  * This function is deprecated and may just be an alias to asn1_der_decoding
1507  * in future versions. Use asn1_der_decoding() instead.
1508  *
1509  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1510  *   if ELEMENT is %NULL or @elementName == NULL, and
1511  *   %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1512  *   match the structure @structure (*ELEMENT deleted).
1513  **/
1514 int
1515 asn1_der_decoding_element (asn1_node * structure, const char *elementName,
1516                            const void *ider, int len, char *errorDescription)
1517 {
1518   return asn1_der_decoding(structure, ider, len, errorDescription);
1519 }
1520
1521 /**
1522  * asn1_der_decoding_startEnd:
1523  * @element: pointer to an ASN1 element
1524  * @ider: vector that contains the DER encoding.
1525  * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1526  * @name_element: an element of NAME structure.
1527  * @start: the position of the first byte of NAME_ELEMENT decoding
1528  *   (@ider[*start])
1529  * @end: the position of the last byte of NAME_ELEMENT decoding
1530  *  (@ider[*end])
1531  *
1532  * Find the start and end point of an element in a DER encoding
1533  * string. I mean that if you have a der encoding and you have already
1534  * used the function asn1_der_decoding() to fill a structure, it may
1535  * happen that you want to find the piece of string concerning an
1536  * element of the structure.
1537  *
1538  * One example is the sequence "tbsCertificate" inside an X509
1539  * certificate.
1540  *
1541  * Note that since libtasn1 3.7 the @ider and @ider_len parameters
1542  * can be omitted, if the element is already decoded using asn1_der_decoding().
1543  *
1544  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1545  *   if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
1546  *   element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
1547  *   doesn't match the structure ELEMENT.
1548  **/
1549 int
1550 asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len,
1551                             const char *name_element, int *start, int *end)
1552 {
1553   asn1_node node, node_to_find;
1554   int result = ASN1_DER_ERROR;
1555
1556   node = element;
1557
1558   if (node == NULL)
1559     return ASN1_ELEMENT_NOT_FOUND;
1560
1561   node_to_find = asn1_find_node (node, name_element);
1562
1563   if (node_to_find == NULL)
1564     return ASN1_ELEMENT_NOT_FOUND;
1565
1566   *start = node_to_find->start;
1567   *end = node_to_find->end;
1568
1569   if (*start == 0 && *end == 0)
1570     {
1571       if (ider == NULL || ider_len == 0)
1572         return ASN1_GENERIC_ERROR;
1573
1574       /* it seems asn1_der_decoding() wasn't called before. Do it now */
1575       result = asn1_der_decoding (&node, ider, ider_len, NULL);
1576       if (result != ASN1_SUCCESS)
1577         {
1578           warn();
1579           return result;
1580         }
1581
1582       node_to_find = asn1_find_node (node, name_element);
1583       if (node_to_find == NULL)
1584         return ASN1_ELEMENT_NOT_FOUND;
1585
1586       *start = node_to_find->start;
1587       *end = node_to_find->end;
1588     }
1589
1590   if (*end < *start)
1591     return ASN1_GENERIC_ERROR;
1592
1593   return ASN1_SUCCESS;
1594 }
1595
1596 /**
1597  * asn1_expand_any_defined_by:
1598  * @definitions: ASN1 definitions
1599  * @element: pointer to an ASN1 structure
1600  *
1601  * Expands every "ANY DEFINED BY" element of a structure created from
1602  * a DER decoding process (asn1_der_decoding function). The element
1603  * ANY must be defined by an OBJECT IDENTIFIER. The type used to
1604  * expand the element ANY is the first one following the definition of
1605  * the actual value of the OBJECT IDENTIFIER.
1606  *
1607  * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
1608  *   some "ANY DEFINED BY" element couldn't be expanded due to a
1609  *   problem in OBJECT_ID -> TYPE association, or other error codes
1610  *   depending on DER decoding.
1611  **/
1612 int
1613 asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
1614 {
1615   char name[2 * ASN1_MAX_NAME_SIZE + 1],
1616     value[ASN1_MAX_NAME_SIZE];
1617   int retCode = ASN1_SUCCESS, result;
1618   int len, len2, len3;
1619   asn1_node p, p2, p3, aux = NULL;
1620   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
1621   const char *definitionsName;
1622
1623   if ((definitions == NULL) || (*element == NULL))
1624     return ASN1_ELEMENT_NOT_FOUND;
1625
1626   definitionsName = definitions->name;
1627
1628   p = *element;
1629   while (p)
1630     {
1631
1632       switch (type_field (p->type))
1633         {
1634         case ASN1_ETYPE_ANY:
1635           if ((p->type & CONST_DEFINED_BY) && (p->value))
1636             {
1637               /* search the "DEF_BY" element */
1638               p2 = p->down;
1639               while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
1640                 p2 = p2->right;
1641
1642               if (!p2)
1643                 {
1644                   retCode = ASN1_ERROR_TYPE_ANY;
1645                   break;
1646                 }
1647
1648               p3 = _asn1_get_up (p);
1649
1650               if (!p3)
1651                 {
1652                   retCode = ASN1_ERROR_TYPE_ANY;
1653                   break;
1654                 }
1655
1656               p3 = p3->down;
1657               while (p3)
1658                 {
1659                   if (!(strcmp (p3->name, p2->name)))
1660                     break;
1661                   p3 = p3->right;
1662                 }
1663
1664               if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
1665                   (p3->value == NULL))
1666                 {
1667
1668                   p3 = _asn1_get_up (p);
1669                   p3 = _asn1_get_up (p3);
1670
1671                   if (!p3)
1672                     {
1673                       retCode = ASN1_ERROR_TYPE_ANY;
1674                       break;
1675                     }
1676
1677                   p3 = p3->down;
1678
1679                   while (p3)
1680                     {
1681                       if (!(strcmp (p3->name, p2->name)))
1682                         break;
1683                       p3 = p3->right;
1684                     }
1685
1686                   if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
1687                       || (p3->value == NULL))
1688                     {
1689                       retCode = ASN1_ERROR_TYPE_ANY;
1690                       break;
1691                     }
1692                 }
1693
1694               /* search the OBJECT_ID into definitions */
1695               p2 = definitions->down;
1696               while (p2)
1697                 {
1698                   if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
1699                       (p2->type & CONST_ASSIGN))
1700                     {
1701                       snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
1702
1703                       len = ASN1_MAX_NAME_SIZE;
1704                       result =
1705                         asn1_read_value (definitions, name, value, &len);
1706
1707                       if ((result == ASN1_SUCCESS)
1708                           && (!_asn1_strcmp (p3->value, value)))
1709                         {
1710                           p2 = p2->right;       /* pointer to the structure to
1711                                                    use for expansion */
1712                           while ((p2) && (p2->type & CONST_ASSIGN))
1713                             p2 = p2->right;
1714
1715                           if (p2)
1716                             {
1717                               snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
1718
1719                               result =
1720                                 asn1_create_element (definitions, name, &aux);
1721                               if (result == ASN1_SUCCESS)
1722                                 {
1723                                   _asn1_cpy_name (aux, p);
1724                                   len2 =
1725                                     asn1_get_length_der (p->value,
1726                                                          p->value_len, &len3);
1727                                   if (len2 < 0)
1728                                     return ASN1_DER_ERROR;
1729
1730                                   result =
1731                                     asn1_der_decoding (&aux, p->value + len3,
1732                                                        len2,
1733                                                        errorDescription);
1734                                   if (result == ASN1_SUCCESS)
1735                                     {
1736
1737                                       _asn1_set_right (aux, p->right);
1738                                       _asn1_set_right (p, aux);
1739
1740                                       result = asn1_delete_structure (&p);
1741                                       if (result == ASN1_SUCCESS)
1742                                         {
1743                                           p = aux;
1744                                           aux = NULL;
1745                                           break;
1746                                         }
1747                                       else
1748                                         {       /* error with asn1_delete_structure */
1749                                           asn1_delete_structure (&aux);
1750                                           retCode = result;
1751                                           break;
1752                                         }
1753                                     }
1754                                   else
1755                                     {   /* error with asn1_der_decoding */
1756                                       retCode = result;
1757                                       break;
1758                                     }
1759                                 }
1760                               else
1761                                 {       /* error with asn1_create_element */
1762                                   retCode = result;
1763                                   break;
1764                                 }
1765                             }
1766                           else
1767                             {   /* error with the pointer to the structure to exapand */
1768                               retCode = ASN1_ERROR_TYPE_ANY;
1769                               break;
1770                             }
1771                         }
1772                     }
1773                   p2 = p2->right;
1774                 }               /* end while */
1775
1776               if (!p2)
1777                 {
1778                   retCode = ASN1_ERROR_TYPE_ANY;
1779                   break;
1780                 }
1781
1782             }
1783           break;
1784         default:
1785           break;
1786         }
1787
1788
1789       if (p->down)
1790         {
1791           p = p->down;
1792         }
1793       else if (p == *element)
1794         {
1795           p = NULL;
1796           break;
1797         }
1798       else if (p->right)
1799         p = p->right;
1800       else
1801         {
1802           while (1)
1803             {
1804               p = _asn1_get_up (p);
1805               if (p == *element)
1806                 {
1807                   p = NULL;
1808                   break;
1809                 }
1810               if (p->right)
1811                 {
1812                   p = p->right;
1813                   break;
1814                 }
1815             }
1816         }
1817     }
1818
1819   return retCode;
1820 }
1821
1822 /**
1823  * asn1_expand_octet_string:
1824  * @definitions: ASN1 definitions
1825  * @element: pointer to an ASN1 structure
1826  * @octetName: name of the OCTECT STRING field to expand.
1827  * @objectName: name of the OBJECT IDENTIFIER field to use to define
1828  *    the type for expansion.
1829  *
1830  * Expands an "OCTET STRING" element of a structure created from a DER
1831  * decoding process (the asn1_der_decoding() function).  The type used
1832  * for expansion is the first one following the definition of the
1833  * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
1834  *
1835  * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
1836  *   if @objectName or @octetName are not correct,
1837  *   %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
1838  *   use for expansion, or other errors depending on DER decoding.
1839  **/
1840 int
1841 asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
1842                           const char *octetName, const char *objectName)
1843 {
1844   char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
1845   int retCode = ASN1_SUCCESS, result;
1846   int len, len2, len3;
1847   asn1_node p2, aux = NULL;
1848   asn1_node octetNode = NULL, objectNode = NULL;
1849   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
1850
1851   if ((definitions == NULL) || (*element == NULL))
1852     return ASN1_ELEMENT_NOT_FOUND;
1853
1854   octetNode = asn1_find_node (*element, octetName);
1855   if (octetNode == NULL)
1856     return ASN1_ELEMENT_NOT_FOUND;
1857   if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
1858     return ASN1_ELEMENT_NOT_FOUND;
1859   if (octetNode->value == NULL)
1860     return ASN1_VALUE_NOT_FOUND;
1861
1862   objectNode = asn1_find_node (*element, objectName);
1863   if (objectNode == NULL)
1864     return ASN1_ELEMENT_NOT_FOUND;
1865
1866   if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
1867     return ASN1_ELEMENT_NOT_FOUND;
1868
1869   if (objectNode->value == NULL)
1870     return ASN1_VALUE_NOT_FOUND;
1871
1872
1873   /* search the OBJECT_ID into definitions */
1874   p2 = definitions->down;
1875   while (p2)
1876     {
1877       if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
1878           (p2->type & CONST_ASSIGN))
1879         {
1880           strcpy (name, definitions->name);
1881           strcat (name, ".");
1882           strcat (name, p2->name);
1883
1884           len = sizeof (value);
1885           result = asn1_read_value (definitions, name, value, &len);
1886
1887           if ((result == ASN1_SUCCESS)
1888               && (!_asn1_strcmp (objectNode->value, value)))
1889             {
1890
1891               p2 = p2->right;   /* pointer to the structure to
1892                                    use for expansion */
1893               while ((p2) && (p2->type & CONST_ASSIGN))
1894                 p2 = p2->right;
1895
1896               if (p2)
1897                 {
1898                   strcpy (name, definitions->name);
1899                   strcat (name, ".");
1900                   strcat (name, p2->name);
1901
1902                   result = asn1_create_element (definitions, name, &aux);
1903                   if (result == ASN1_SUCCESS)
1904                     {
1905                       _asn1_cpy_name (aux, octetNode);
1906                       len2 =
1907                         asn1_get_length_der (octetNode->value,
1908                                              octetNode->value_len, &len3);
1909                       if (len2 < 0)
1910                         return ASN1_DER_ERROR;
1911
1912                       result =
1913                         asn1_der_decoding (&aux, octetNode->value + len3,
1914                                            len2, errorDescription);
1915                       if (result == ASN1_SUCCESS)
1916                         {
1917
1918                           _asn1_set_right (aux, octetNode->right);
1919                           _asn1_set_right (octetNode, aux);
1920
1921                           result = asn1_delete_structure (&octetNode);
1922                           if (result == ASN1_SUCCESS)
1923                             {
1924                               aux = NULL;
1925                               break;
1926                             }
1927                           else
1928                             {   /* error with asn1_delete_structure */
1929                               asn1_delete_structure (&aux);
1930                               retCode = result;
1931                               break;
1932                             }
1933                         }
1934                       else
1935                         {       /* error with asn1_der_decoding */
1936                           retCode = result;
1937                           break;
1938                         }
1939                     }
1940                   else
1941                     {           /* error with asn1_create_element */
1942                       retCode = result;
1943                       break;
1944                     }
1945                 }
1946               else
1947                 {               /* error with the pointer to the structure to exapand */
1948                   retCode = ASN1_VALUE_NOT_VALID;
1949                   break;
1950                 }
1951             }
1952         }
1953
1954       p2 = p2->right;
1955
1956     }
1957
1958   if (!p2)
1959     retCode = ASN1_VALUE_NOT_VALID;
1960
1961   return retCode;
1962 }
1963
1964 /**
1965  * asn1_decode_simple_der:
1966  * @etype: The type of the string to be encoded (ASN1_ETYPE_)
1967  * @der: the encoded string
1968  * @der_len: the bytes of the encoded string
1969  * @str: a pointer to the data
1970  * @str_len: the length of the data
1971  *
1972  * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
1973  * The output is a pointer inside the @der.
1974  *
1975  * Returns: %ASN1_SUCCESS if successful or an error value.
1976  **/
1977 int
1978 asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
1979                         unsigned int der_len, const unsigned char **str,
1980                         unsigned int *str_len)
1981 {
1982   int tag_len, len_len;
1983   const unsigned char *p;
1984   unsigned char class;
1985   unsigned long tag;
1986   long ret;
1987
1988   if (der == NULL || der_len == 0)
1989     return ASN1_VALUE_NOT_VALID;
1990
1991   if (ETYPE_OK (etype) == 0)
1992     return ASN1_VALUE_NOT_VALID;
1993
1994   /* doesn't handle constructed classes */
1995   if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
1996     return ASN1_VALUE_NOT_VALID;
1997
1998   p = der;
1999   ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
2000   if (ret != ASN1_SUCCESS)
2001     return ret;
2002
2003   if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
2004     return ASN1_DER_ERROR;
2005
2006   p += tag_len;
2007   der_len -= tag_len;
2008
2009   ret = asn1_get_length_der (p, der_len, &len_len);
2010   if (ret < 0)
2011     return ASN1_DER_ERROR;
2012
2013   p += len_len;
2014   der_len -= len_len;
2015
2016   *str_len = ret;
2017   *str = p;
2018
2019   return ASN1_SUCCESS;
2020 }