New SILC PKCS API, enabling support for other public keys/certs.
[silc.git] / lib / silcasn1 / silcasn1_decode.c
1 /*
2
3   silcasn1_decode.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2003 - 2006 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silc.h"
21 #include "silcasn1.h"
22 #include "silcber.h"
23
24 /************************** ASN.1 Decoder routines **************************/
25
26 /* Internal SEQUENCE OF and SET OF decoder.  This is used only when decoding
27    these two special tags.  Other normal ASN.1 decoding is done in the
28    silc_asn1_decoder function.  This parses the sequence of types and returns
29    them as raw BER buffers in an array of SilcBuffers. */
30
31 static SilcBool silc_asn1_decoder_sof(SilcAsn1 asn1, SilcBuffer src)
32 {
33   SilcBool ret = FALSE;
34   SilcList types;
35   SilcAsn1Tag type;
36   SilcBuffer *retb;
37   SilcUInt32 *retc;
38   SilcAsn1Tag rtag;
39   const unsigned char *rdata;
40   SilcUInt32 rdata_len, len = 0;
41   SilcBool found = FALSE, rindef;
42
43   struct SilcAsn1SofStruct {
44     SilcAsn1Tag type;
45     struct SilcAsn1SofStruct *next;
46   } *t = NULL;
47
48   SILC_LOG_DEBUG(("Decoding sequence of types"));
49
50   silc_list_init(types, struct SilcAsn1SofStruct, next);
51
52   /* Take the return arguments */
53   retb = va_arg(asn1->ap, SilcBuffer *);
54   retc = va_arg(asn1->ap, SilcUInt32 *);
55   *retb = NULL;
56   *retc = 0;
57
58   /* Get the sequence type(s).  If the type is CHOICE tag then the sequence
59      may include multiple different types.  All types are considered
60      separately.  If CHOICE is not given then only single type is expected. */
61   type = va_arg(asn1->ap, SilcUInt32);
62   assert(type != SILC_ASN1_END);
63
64   if (type == SILC_ASN1_TAG_CHOICE) {
65     /* The sequence may consist of the following types. */
66     type = va_arg(asn1->ap, SilcUInt32);
67     assert(type != SILC_ASN1_END);
68     while (type != SILC_ASN1_END) {
69       t = silc_smalloc(asn1->stack1, sizeof(*t));
70       if (!t)
71         goto out;
72       t->type = type;
73       silc_list_add(types, t);
74
75       SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
76                       silc_asn1_tag_name(type), type));
77
78       type = va_arg(asn1->ap, SilcUInt32);
79     }
80   } else {
81     /* The sequence consists of this type. */
82     t = silc_smalloc(asn1->stack1, sizeof(*t));
83     if (!t)
84       goto out;
85     t->type = type;
86     silc_list_add(types, t);
87
88     SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
89                     silc_asn1_tag_name(type), type));
90   }
91
92   /* END marker for the sequence */
93   type = va_arg(asn1->ap, SilcUInt32);
94   assert(type == SILC_ASN1_END);
95
96   /* Decode the SEQUENCE or SET */
97   ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
98                         &rdata_len, &rindef, &len);
99   if (!ret) {
100     SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
101     goto out;
102   }
103   if (rtag != SILC_ASN1_TAG_SEQUENCE && rtag != SILC_ASN1_TAG_SET) {
104     SILC_LOG_DEBUG(("Invalid sequence of/set of"));
105     goto out;
106   }
107   silc_buffer_pull(src, len);
108
109   while (silc_buffer_len(src)) {
110     /* Decode the BER data. */
111     ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
112                           &rdata_len, &rindef, &len);
113     if (!ret) {
114       SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
115       goto out;
116     }
117
118     /* Now check the type(s) that it is supposed to be */
119     found = FALSE;
120     silc_list_start(types);
121     while ((t = silc_list_get(types)) != SILC_LIST_END) {
122       if (t->type != rtag)
123         continue;
124
125       *retb = silc_srealloc(asn1->stack1, sizeof(**retb) * (*retc), *retb,
126                             sizeof(**retb) * (*retc + 1));
127       if (*retb == NULL)
128         goto out;
129
130       SILC_LOG_DEBUG(("Decode %s [%d] from sequence of types",
131                       silc_asn1_tag_name(rtag), rtag));
132
133       /* Data is duplicated only if SILC_ASN1_ALLOC flag is set */
134       if (!asn1->stack1)
135         rdata = silc_memdup(rdata - len, rdata_len + len);
136       else
137         rdata = rdata - len;
138       rdata_len += len;
139
140       /* Save the data */
141       silc_buffer_set(&(*retb)[*retc], (unsigned char *)rdata, rdata_len);
142       (*retc)++;
143       found = TRUE;
144       break;
145     }
146
147     /* If type was not found we consider it the end of the sequence */
148     if (found == FALSE)
149       break;
150
151     if (rdata_len)
152       silc_buffer_pull(src, rdata_len);
153   }
154
155   SILC_LOG_DEBUG(("Decoded %d types", *retc));
156   ret = TRUE;
157
158  out:
159   if (!asn1->stack1) {
160     silc_list_start(types);
161     while ((t = silc_list_get(types)) != SILC_LIST_END)
162       silc_free(t);
163   }
164
165   return ret;
166 }
167
168 /* Macro for decoder to get argument for a type.  If OPTIONAL option is
169    set then the argument is a pointer to the type pointer.  The `type'
170    must be a non-pointer type, eg. int, SilcBufferStruct. */
171 #define SILC_ASN1_VAD(asn1, opts, type, name)                   \
172   type **name;                                                  \
173   if ((opts) & SILC_ASN1_OPTIONAL && !choice) {                 \
174     name = va_arg(asn1->ap, type **);                           \
175     if (!found) {                                               \
176       if (name)                                                 \
177         *name = NULL;                                           \
178       break;                                                    \
179     }                                                           \
180     if (name == NULL)                                           \
181       break;                                                    \
182     *name = silc_scalloc(asn1->stack1, 1, sizeof(**name));      \
183     if (*name == NULL)                                          \
184       break;                                                    \
185   } else {                                                      \
186     type *name ## tmp = va_arg(asn1->ap, type *);               \
187     if (choice && found && !len)                                \
188       break;                                                    \
189     if (name ## tmp == NULL)                                    \
190       break;                                                    \
191     name = &name ## tmp;                                        \
192   }
193
194 /* Same as SILC_ASN1_VAD but for unsigned char and SilcUInt32 */
195 #define SILC_ASN1_VAD_UCHAR(asn1, opts, type, name, namelen)    \
196   type **name = va_arg(asn1->ap, type **);                      \
197   SilcUInt32 *namelen = va_arg(asn1->ap, SilcUInt32 *);         \
198   if (choice && found && !len)                                  \
199     break;                                                      \
200   if (!found) {                                                 \
201     if (name)                                                   \
202       *name = NULL;                                             \
203     break;                                                      \
204   }                                                             \
205   if (name == NULL)                                             \
206     break;
207
208 /* Same as SILC_ASN1_VAD but for char only */
209 #define SILC_ASN1_VAD_CHAR(asn1, opts, type, name)      \
210   type **name = va_arg(asn1->ap, type **);              \
211   if (choice && found && !len)                          \
212     break;                                              \
213   if (!found) {                                         \
214     if (name)                                           \
215       *name = NULL;                                     \
216     break;                                              \
217   }                                                     \
218   if (name == NULL)                                     \
219     break;
220
221 #define SILC_ASN1_VA_FREE(opts, name)           \
222   if ((opts) & SILC_ASN1_OPTIONAL)              \
223     silc_free(*name);
224
225 /* Decodes string to UTF-8 string which is our internal representation
226    of any string. */
227 #define SILC_ASN1_DECODE_STRING(enc, s, s_len)                  \
228   *s_len = silc_utf8_encoded_len(rdata, rdata_len, (enc));      \
229   if (*s_len == 0) {                                            \
230     SILC_LOG_DEBUG(("Malformed %d string value", (enc)));       \
231     ret = FALSE;                                                \
232     goto fail;                                                  \
233   }                                                             \
234   *s = silc_smalloc_ua(stack1, *s_len + 1);                     \
235   if (*s) {                                                     \
236     silc_utf8_encode(rdata, rdata_len, (enc), *s, *s_len);      \
237     (*s)[*s_len] = '\0';                                        \
238   }
239
240
241 /* Internal ASN.1 decoder.  The `type', `tag' and `opts' are the first
242    arguments (either very first or first for recursion) for a type.
243    The `depth' includes the current depth of recursion. */
244
245 static SilcBool
246 silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
247                   SilcAsn1Tag tag, SilcBerClass ber_class,
248                   SilcAsn1Options opts, SilcBuffer src, SilcUInt32 depth,
249                   SilcBool primitive)
250 {
251   unsigned char *ptr = src->data;
252   SilcAsn1Tag rtype, rtag;
253   SilcAsn1Options ropts;
254   SilcBerClass rclass;
255   SilcBerEncoding renc;
256   SilcUInt32 len = 0;
257   SilcBool ret, indef, rindef, found = FALSE, choice = FALSE;
258   const unsigned char *rdata;
259   SilcUInt32 rdata_len;
260   int i;
261
262 #ifdef SILC_DEBUG
263   char sp[SILC_ASN1_RECURSION_DEPTH + 1];
264   memset(sp, 0, sizeof(sp));
265   if (depth)
266     memset(sp, 32, depth);
267 #endif /* SILC_DEBUG */
268
269   if (depth >= SILC_ASN1_RECURSION_DEPTH) {
270     SILC_LOG_DEBUG(("Maximum recursion depth reached"));
271     return FALSE;
272   }
273
274   while (1) {
275
276     /* If requested type is SEQUENCE OF or SET OF then we decode the sequence
277        of types separately in an own decoder which returns array of buffers. */
278     if (type == SILC_ASN1_TAG_SEQUENCE_OF) {
279       /* Decode the sequence */
280       if (!silc_asn1_decoder_sof(asn1, src)) {
281         SILC_LOG_DEBUG(("Error decoding SEQUENCE OF"));
282         ret = FALSE;
283         goto fail;
284       }
285
286       /* Continue with rest of the decodings if any */
287       SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
288       if (type == SILC_ASN1_END) {
289         ret = TRUE;
290         goto ok;
291       }
292     }
293
294     /* Get length encoding */
295     indef = (opts & SILC_ASN1_INDEFINITE ? TRUE : FALSE);
296
297     /* By default UNIVERSAL is implied unless the following conditions
298        are met when CONTEXT will apply.  For SILC_ASN1_TAG_ANY_PRIMITIVE
299        the class is changed only if flags dictate it. */
300     if (ber_class == SILC_BER_CLASS_UNIVERSAL) {
301       if (type == SILC_ASN1_TAG_ANY_PRIMITIVE) {
302         if (opts & SILC_ASN1_IMPLICIT ||
303             opts & SILC_ASN1_EXPLICIT)
304           ber_class = SILC_BER_CLASS_CONTEXT;
305       } else {
306         if (tag != type ||
307             opts & SILC_ASN1_IMPLICIT ||
308             opts & SILC_ASN1_EXPLICIT)
309           ber_class = SILC_BER_CLASS_CONTEXT;
310       }
311     }
312
313     /* Now decode a BER encoded block from the source buffer.  It must be
314        exactly the same user is expecting. */
315     ret = silc_ber_decode(src, &rclass, &renc, (SilcUInt32 *)&rtag, &rdata,
316                           &rdata_len, &rindef, &len);
317     if (!ret) {
318       SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
319       return FALSE;
320     }
321
322     /* Now verify that the decoded BER is the one user wanted to get.  If
323        requested type is OPTIONAL, then ignore all the sanity tests.  The
324        while() loop is for re-considering OPTIONAL types without parsing
325        new BER object.  For CHOICE (tag) all the choice considerations are
326        also done within the while(). */
327     while (1) {
328
329       /* If type is CHOICE then at least one type must match before next
330          SILC_ASN1_END is reached.  The considerations act interally as
331          having OPTIONAL flag set, except that at the end one must have
332          been found. */
333       if (type == SILC_ASN1_TAG_CHOICE) {
334         choice = TRUE;
335         SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
336         opts |= SILC_ASN1_OPTIONAL;
337         found = FALSE;
338       }
339
340 #ifdef SILC_DEBUG
341       SILC_LOG_DEBUG(
342         ("%04d: %sDecode %s [%d] %s %s %s %s", depth, sp[0] ? sp : "",
343          silc_asn1_tag_name(type), rtag,
344          rclass == SILC_BER_CLASS_UNIVERSAL   ? "univ" :
345          rclass == SILC_BER_CLASS_APPLICATION ? "appl" :
346          rclass == SILC_BER_CLASS_CONTEXT     ? "cont" : "priv",
347          renc == SILC_BER_ENC_PRIMITIVE ? "primit" : "constr",
348          rindef ? "indef" : "defin",
349          choice ? "choice" : opts & SILC_ASN1_OPTIONAL ? "option" : ""));
350 #endif /* SILC_DEBUG */
351
352       if (type != SILC_ASN1_TAG_ANY && tag != rtag) {
353         if (!(opts & SILC_ASN1_OPTIONAL)) {
354           SILC_LOG_DEBUG(("Invalid ASN.1 tag %u, expected %u", rtag, tag));
355           return FALSE;
356         }
357         if (!choice)
358           found = FALSE;
359
360       } else if (ber_class != rclass) {
361         if (!(opts & SILC_ASN1_OPTIONAL)) {
362           SILC_LOG_DEBUG(("Invalid ASN.1 class %d, expected %d",
363                           rclass, ber_class));
364           return FALSE;
365         }
366         if (!choice)
367           found = FALSE;
368
369       } else if (!(opts & SILC_ASN1_EXPLICIT) && indef != rindef) {
370         SILC_LOG_DEBUG(("Invalid ASN.1 length encoding %s, expected %s",
371                         rindef ? "indefinite" : "definite",
372                         indef ? "indefinite" : "definite"));
373         return FALSE;
374
375       } else if (rindef && renc == SILC_BER_ENC_PRIMITIVE) {
376         SILC_LOG_DEBUG(("Invalid length encoding for primitive type"));
377         return FALSE;
378
379       } else {
380         found = TRUE;
381       }
382
383       /* If tagging is explicit we have additional sequence we need to decode
384          before we decode the actual underlaying type. */
385       if (opts & SILC_ASN1_EXPLICIT) {
386         silc_buffer_pull(src, len);
387         len = 0;
388
389         primitive = (type != SILC_ASN1_TAG_SEQUENCE &&
390                      type != SILC_ASN1_TAG_SET &&
391                      type != SILC_ASN1_TAG_ANY);
392         opts &= ~SILC_ASN1_EXPLICIT;
393
394         ret = silc_asn1_decoder(asn1, stack1, type, type,
395                                 SILC_BER_CLASS_UNIVERSAL, opts, src,
396                                 depth + 1, primitive);
397         if (!ret)
398           goto fail;
399         if (primitive) {
400           primitive = FALSE;
401           goto cont;
402         }
403         goto ok;
404       }
405
406       /* Decode by the type user expects the data to be. */
407       switch (type) {
408
409       case SILC_ASN1_TAG_ANY:
410         {
411           /* ANY is another ASN.1 node.  We return the raw BER buffer as
412              the node */
413           SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, node);
414
415           *node = silc_buffer_srealloc_size(stack1, *node, len + rdata_len);
416           silc_buffer_put(*node, rdata - len, rdata_len + len);
417           break;
418         }
419
420       case SILC_ASN1_TAG_ANY_PRIMITIVE:
421         {
422           /* ANY_PRIMITIVE returns the raw data blob of any primitive type. */
423           SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, prim);
424
425           *prim = silc_buffer_srealloc_size(stack1, *prim, rdata_len);
426           silc_buffer_put(*prim, rdata, rdata_len);
427           break;
428         }
429
430       case SILC_ASN1_TAG_SEQUENCE:
431       case SILC_ASN1_TAG_SET:
432         {
433           /* SEQUENCE/SET is a sequence of types. */
434           silc_buffer_pull(src, len);
435           len = 0;
436
437           /* Get type, tag and options for the first argument in recursion */
438           SILC_ASN1_ARGS(asn1, rtype, rtag, rclass, ropts);
439
440           /* Decode the sequence recursively */
441           ret = silc_asn1_decoder(asn1, stack1, rtype, rtag, rclass,
442                                   ropts, src, depth + 1, FALSE);
443           if (!ret)
444             goto fail;
445           break;
446         }
447
448       case SILC_ASN1_TAG_INTEGER:
449       case SILC_ASN1_TAG_ENUM:
450         {
451           /* Integer/enum value. */
452           SilcMPInt z;
453           SILC_ASN1_VAD(asn1, opts, SilcMPInt, intval);
454
455           if (rdata_len < 1) {
456             SILC_LOG_DEBUG(("Malformed integer value"));
457             SILC_ASN1_VA_FREE(opts, intval);
458             ret = FALSE;
459             goto fail;
460           }
461
462           silc_mp_sinit(asn1->stack1, *intval);
463
464           /* Check whether the integer is positive or negative */
465           if (rdata[0] & 0x80) {
466             /* Negative integer stored in 1s complement.*/
467             for (i = 0; i < rdata_len; i++) {
468               silc_mp_mul_2exp(*intval, *intval, 8);
469               silc_mp_add_ui(*intval, *intval, ~rdata[i] & 0xff);
470             }
471
472             /* 2s complement and change sign */
473             silc_mp_init(&z);
474             silc_mp_set_ui(&z, 0);
475             silc_mp_add_ui(*intval, *intval, 1);
476             silc_mp_sub(*intval, &z, *intval);
477             silc_mp_uninit(&z);
478           } else {
479             /* Positive */
480             silc_mp_bin2mp((unsigned char *)rdata, rdata_len, *intval);
481           }
482
483           break;
484         }
485
486       case SILC_ASN1_TAG_OID:
487         {
488           /* Object identifier */
489           SilcBufferStruct tmpb;
490           char tmpstr[24];
491           SilcUInt32 oid;
492           SILC_ASN1_VAD_CHAR(asn1, opts, char, oidstr);
493
494           if (rdata_len < 1) {
495             SILC_LOG_DEBUG(("Malformed object identifier value"));
496             ret = FALSE;
497             goto fail;
498           }
499
500           /* Set two OID values */
501           memset(&tmpb, 0, sizeof(tmpb));
502           memset(tmpstr, 0, sizeof(tmpstr));
503           snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
504                    (unsigned long)(rdata[0] & 0xff) / 40,
505                    (unsigned long)(rdata[0] & 0xff) % 40);
506           silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
507
508           /* Set rest of the OID values, each octet having 7 bits of the
509              OID value with bit 8 set.  An octet not having bit 8 set
510              means end of that OID value. */
511           for (i = 1; i < rdata_len; i++) {
512             oid = 0;
513             while (rdata[i] & 0x80) {
514               oid <<= 7;
515               oid |= rdata[i++] & 0x7f;
516               if (i >= rdata_len) {
517                 SILC_LOG_DEBUG(("Malformed object identifier value"));
518                 break;
519               }
520             }
521             oid <<= 7;
522             oid |= rdata[i];
523
524             memset(tmpstr, 0, sizeof(tmpstr));
525             snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
526             silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
527           }
528           *oidstr = tmpb.head;
529
530           break;
531         }
532
533       case SILC_ASN1_TAG_BOOLEAN:
534         {
535           /* Decode boolean (TRUE/FALSE) value */
536           SILC_ASN1_VAD(asn1, opts, SilcBool, val);
537
538           if (rdata_len != 1) {
539             SILC_LOG_DEBUG(("Malformed boolean value"));
540             SILC_ASN1_VA_FREE(opts, val);
541             ret = FALSE;
542             goto fail;
543           }
544
545           *(*val) = (rdata[0] == 0xff ? TRUE : FALSE);
546           break;
547         }
548
549       case SILC_ASN1_TAG_BIT_STRING:
550         {
551           /* Bit string contains data with exact bit length of the data */
552           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, d, d_len);
553
554           if (rdata_len < 2) {
555             SILC_LOG_DEBUG(("Malformed bit string value"));
556             ret = FALSE;
557             goto fail;
558           }
559
560           *d = silc_smemdup(stack1, rdata + 1, rdata_len - 1);
561           *d_len = (rdata_len - 1) * 8;
562           break;
563         }
564
565       case SILC_ASN1_TAG_NULL:
566         {
567           /* Decode empty BER block */
568           if (rdata_len != 0) {
569             SILC_LOG_DEBUG(("Malformed null value"));
570             goto fail;
571           }
572           break;
573         }
574
575       case SILC_ASN1_TAG_UTC_TIME:
576         {
577           /* Universal encoded time string */
578           SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
579
580           if (rdata_len < 1) {
581             SILC_LOG_DEBUG(("Malformed UTC time value"));
582             ret = FALSE;
583             goto fail;
584           }
585
586           /* Parse the time string */
587           if (!silc_time_universal(rdata, *t)) {
588             SILC_LOG_DEBUG(("Malformed UTC time value"));
589             ret = FALSE;
590             goto fail;
591           }
592
593           break;
594         }
595
596       case SILC_ASN1_TAG_GENERALIZED_TIME:
597         {
598           /* Generalized encoded time string */
599           SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
600
601           if (rdata_len < 1) {
602             SILC_LOG_DEBUG(("Malformed generalized time value"));
603             ret = FALSE;
604             goto fail;
605           }
606
607           /* Parse the time string */
608           if (!silc_time_generalized(rdata, *t)) {
609             SILC_LOG_DEBUG(("Malformed generalized time value"));
610             ret = FALSE;
611             goto fail;
612           }
613
614           break;
615         }
616
617       case SILC_ASN1_TAG_UTF8_STRING:
618         {
619           /* UTF-8 encoded string */
620           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
621
622           if (!silc_utf8_valid(rdata, rdata_len)) {
623             SILC_LOG_DEBUG(("Malformed UTF-8 string value"));
624             ret = FALSE;
625             goto fail;
626           }
627
628           *s = silc_smemdup(stack1, rdata, rdata_len);
629           *s_len = rdata_len;
630           break;
631         }
632
633       case SILC_ASN1_TAG_OCTET_STRING:
634         {
635           /* Octet string.  We take it as 8-bit ASCII */
636           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
637           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
638           break;
639         }
640
641       case SILC_ASN1_TAG_NUMERIC_STRING:
642         {
643           /* Numerical (digit) string */
644           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
645           SILC_ASN1_DECODE_STRING(SILC_STRING_NUMERICAL, s, s_len);
646           break;
647         }
648
649       case SILC_ASN1_TAG_PRINTABLE_STRING:
650         {
651           /* Printable string */
652           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
653           SILC_ASN1_DECODE_STRING(SILC_STRING_PRINTABLE, s, s_len);
654           break;
655         }
656
657       case SILC_ASN1_TAG_TELETEX_STRING:
658         {
659           /* Teletex (T61) string */
660           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
661           SILC_ASN1_DECODE_STRING(SILC_STRING_TELETEX, s, s_len);
662           break;
663         }
664
665       case SILC_ASN1_TAG_IA5_STRING:
666         {
667           /* US ASCII string */
668           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
669           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
670           break;
671         }
672
673       case SILC_ASN1_TAG_VISIBLE_STRING:
674         {
675           /* Visible string */
676           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
677           SILC_ASN1_DECODE_STRING(SILC_STRING_VISIBLE, s, s_len);
678           break;
679         }
680
681       case SILC_ASN1_TAG_UNIVERSAL_STRING:
682         {
683           /* Universal (UCS-4) string */
684           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
685           SILC_ASN1_DECODE_STRING(SILC_STRING_UNIVERSAL, s, s_len);
686           break;
687         }
688
689       case SILC_ASN1_TAG_UNRESTRICTED_STRING:
690       case SILC_ASN1_TAG_GENERAL_STRING:
691         {
692           /* Handle now unrestricted and general as 8-bit ascii, which
693              probably isn't correct. */
694           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
695           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
696           break;
697         }
698
699       case SILC_ASN1_TAG_BMP_STRING:
700         {
701           /* BMP (UCS-2) string */
702           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
703           SILC_ASN1_DECODE_STRING(SILC_STRING_BMP, s, s_len);
704           break;
705         }
706
707       case SILC_ASN1_TAG_ODE:
708       case SILC_ASN1_TAG_ETI:
709       case SILC_ASN1_TAG_REAL:
710       case SILC_ASN1_TAG_EMBEDDED:
711       case SILC_ASN1_TAG_ROI:
712       case SILC_ASN1_TAG_VIDEOTEX_STRING:
713       case SILC_ASN1_TAG_GRAPHIC_STRING:
714         {
715           SILC_NOT_IMPLEMENTED("Unsupported ASN.1 tag");
716           ret = FALSE;
717           goto fail;
718           break;
719         }
720
721       default:
722         SILC_LOG_DEBUG(("Invalid ASN.1 tag `%d'. Cannot decode ASN.1.",
723                         type));
724         ret = FALSE;
725         goto fail;
726         break;
727       }
728
729     cont:
730       /* Pull the current data from source which reveals next BER object */
731       if (found && len + rdata_len)
732         silc_buffer_pull(src, len + rdata_len);
733       if (primitive) {
734         ret = TRUE;
735         goto ok;
736       }
737
738       /* Get next type, tag and options */
739       rtype = type;
740       SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
741       if (type == SILC_ASN1_END) {
742         if (choice) {
743           if (!found) {
744             /* No choices were found, error */
745             SILC_LOG_DEBUG(("Invalid ASN.1 choice: no choices present"));
746             ret = FALSE;
747             goto fail;
748           }
749
750           /* Take next type and new BER object, choices are over */
751           choice = FALSE;
752           SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
753           if (type == SILC_ASN1_END) {
754             ret = TRUE;
755             goto ok;
756           }
757           break;
758         }
759
760         /* SEQUENCE/SET end */
761         ret = TRUE;
762         goto ok;
763       }
764
765       if (choice) {
766         /* Even if the choice was found we must go through rest of
767            the choices. */
768         if (found && len) {
769           SILC_LOG_DEBUG(("Found choice %s type", silc_asn1_tag_name(rtype)));
770           rdata_len = len = 0;
771         }
772         opts |= SILC_ASN1_OPTIONAL;
773         continue;
774       }
775
776       /* Optional type not present, check next one for match */
777       if (!found)
778         continue;
779
780       break;
781     }
782   }
783
784  fail:
785   SILC_LOG_DEBUG(("Error decoding type %d (depth %d)", type, depth));
786
787  ok:
788   if (ptr)
789     len = src->data - ptr;
790   else
791     len = src->data - src->head;
792   silc_buffer_push(src, len);
793
794   return ret;
795 }
796
797 SilcBool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...)
798 {
799   SilcAsn1Tag type, tag;
800   SilcAsn1Options opts;
801   SilcBerClass ber_class;
802   SilcStackFrame frame1, frame2;
803   SilcStack stack1 = NULL, stack2 = NULL;
804   SilcBool ret;
805
806   if (!asn1)
807     return FALSE;
808
809   va_start(asn1->ap, src);
810
811   /* Get the first arguments and call the decoder. */
812   SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
813   if (!type) {
814     va_end(asn1->ap);
815     asn1->ap = NULL;
816     return FALSE;
817   }
818
819   /* Handle internal options for decoder. */
820   if (type == SILC_ASN1_TAG_OPTS) {
821     SilcUInt32 o = va_arg(asn1->ap, SilcUInt32);
822
823     if (o & SILC_ASN1_ALLOC) {
824       /* User wants to alloate everything.  Set the stacks to NULL so
825          that stack aware calls revert to normal allocation routines. */
826       stack1 = asn1->stack1;
827       stack2 = asn1->stack2;
828       asn1->stack1 = NULL;
829       asn1->stack2 = NULL;
830     }
831
832     if (o & SILC_ASN1_ACCUMUL) {
833       /* If accumul flag is not set yet, then push the stacks. */
834       if (!asn1->accumul) {
835         silc_stack_push(asn1->stack1, NULL);
836         silc_stack_push(asn1->stack2, NULL);
837         asn1->accumul = 1;
838       }
839     }
840
841     /* Take again the arguments */
842     SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
843   } else {
844     /* No flags set, all flags will be reset. */
845
846     /* If accumul flag is set now pop the stack so that all accumulated
847        memory becomes free again. */
848     if (asn1->accumul) {
849       silc_stack_pop(asn1->stack1);
850       silc_stack_pop(asn1->stack2);
851       asn1->accumul = 0;
852     }
853   }
854
855   /* Push stacks for normal allocation from stack */
856   if (!asn1->accumul) {
857     silc_stack_push(asn1->stack1, &frame1);
858     silc_stack_push(asn1->stack2, &frame2);
859   }
860
861   /* Start decoding */
862   ret = silc_asn1_decoder(asn1, asn1->stack1, type, tag, ber_class,
863                           opts, src, 0, FALSE);
864
865   /* Pop stacks to free normal allocations from stack. They remain valid
866      for every second call to this function. */
867   if (!asn1->accumul) {
868     silc_stack_pop(asn1->stack1);
869     silc_stack_pop(asn1->stack2);
870
871     /* Switch the asn1->stack1 and asn1->stack2.  This way next call to
872        this function does not invalidate these results.  Every second call
873        invalidates the results of every second previous results. */
874     if (asn1->stack1 && asn1->stack2) {
875       stack1 = asn1->stack1;
876       asn1->stack1 = asn1->stack2;
877       asn1->stack2 = stack1;
878     }
879   }
880
881   if (stack1 && stack2 && !asn1->stack1 && !asn1->stack2) {
882     /* SILC_ASN1_ALLOC flag was set, restore the stacks. */
883     asn1->stack1 = stack1;
884     asn1->stack2 = stack2;
885   }
886
887   va_end(asn1->ap);
888   asn1->ap = NULL;
889
890   return ret;
891 }