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