Added SILC_ASN1_ANY_PRIMITIVE to encode/decode any pre-encoded
[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.  For SILC_ASN1_TAG_ANY_PRIMITIVE
300        the class is changed only if flags dictate it. */
301     if (ber_class == SILC_BER_CLASS_UNIVERSAL) {
302       if (type == SILC_ASN1_TAG_ANY_PRIMITIVE) {
303         if (opts & SILC_ASN1_IMPLICIT ||
304             opts & SILC_ASN1_EXPLICIT)
305           ber_class = SILC_BER_CLASS_CONTEXT;
306       } else {
307         if (tag != type ||
308             opts & SILC_ASN1_IMPLICIT ||
309             opts & SILC_ASN1_EXPLICIT)
310           ber_class = SILC_BER_CLASS_CONTEXT;
311       }
312     }
313
314     /* Now decode a BER encoded block from the source buffer.  It must be
315        exactly the same user is expecting. */
316     ret = silc_ber_decode(src, &rclass, &renc, (SilcUInt32 *)&rtag, &rdata,
317                           &rdata_len, &rindef, &len);
318     if (!ret) {
319       SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
320       return FALSE;
321     }
322
323     /* Now verify that the decoded BER is the one user wanted to get.  If
324        requested type is OPTIONAL, then ignore all the sanity tests.  The
325        while() loop is for re-considering OPTIONAL types without parsing
326        new BER object.  For CHOICE (tag) all the choice considerations are
327        also done within the while(). */
328     while (1) {
329
330       /* If type is CHOICE then at least one type must match before next
331          SILC_ASN1_END is reached.  The considerations act interally as
332          having OPTIONAL flag set, except that at the end one must have
333          been found. */
334       if (type == SILC_ASN1_TAG_CHOICE) {
335         choice = TRUE;
336         SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
337         opts |= SILC_ASN1_OPTIONAL;
338         found = FALSE;
339       }
340
341 #ifdef SILC_DEBUG
342       SILC_LOG_DEBUG(
343         ("%04d: %sDecode %s [%d] %s %s %s %s", depth, sp[0] ? sp : "",
344          silc_asn1_tag_name(type), rtag,
345          rclass == SILC_BER_CLASS_UNIVERSAL   ? "univ" :
346          rclass == SILC_BER_CLASS_APPLICATION ? "appl" :
347          rclass == SILC_BER_CLASS_CONTEXT     ? "cont" : "priv",
348          renc == SILC_BER_ENC_PRIMITIVE ? "primit" : "constr",
349          rindef ? "indef" : "defin",
350          choice ? "choice" : opts & SILC_ASN1_OPTIONAL ? "option" : ""));
351 #endif /* SILC_DEBUG */
352
353       if (type != SILC_ASN1_TAG_ANY && tag != rtag) {
354         if (!(opts & SILC_ASN1_OPTIONAL)) {
355           SILC_LOG_DEBUG(("Invalid ASN.1 tag %u, expected %u", rtag, tag));
356           return FALSE;
357         }
358         if (!choice)
359           found = FALSE;
360
361       } else if (ber_class != rclass) {
362         if (!(opts & SILC_ASN1_OPTIONAL)) {
363           SILC_LOG_DEBUG(("Invalid ASN.1 class %d, expected %d",
364                           rclass, ber_class));
365           return FALSE;
366         }
367         if (!choice)
368           found = FALSE;
369
370       } else if (!(opts & SILC_ASN1_EXPLICIT) && indef != rindef) {
371         SILC_LOG_DEBUG(("Invalid ASN.1 length encoding %s, expected %s",
372                         rindef ? "indefinite" : "definite",
373                         indef ? "indefinite" : "definite"));
374         return FALSE;
375
376       } else if (rindef && renc == SILC_BER_ENC_PRIMITIVE) {
377         SILC_LOG_DEBUG(("Invalid length encoding for primitive type"));
378         return FALSE;
379
380       } else {
381         found = TRUE;
382       }
383
384       /* If tagging is explicit we have additional sequence we need to decode
385          before we decode the actual underlaying type. */
386       if (opts & SILC_ASN1_EXPLICIT) {
387         silc_buffer_pull(src, len);
388         len = 0;
389
390         primitive = (type != SILC_ASN1_TAG_SEQUENCE &&
391                      type != SILC_ASN1_TAG_SET &&
392                      type != SILC_ASN1_TAG_ANY);
393         opts &= ~SILC_ASN1_EXPLICIT;
394
395         ret = silc_asn1_decoder(asn1, stack1, type, type,
396                                 SILC_BER_CLASS_UNIVERSAL, opts, src,
397                                 depth + 1, primitive);
398         if (!ret)
399           goto fail;
400         if (primitive) {
401           primitive = FALSE;
402           goto cont;
403         }
404         goto ok;
405       }
406
407       /* Decode by the type user expects the data to be. */
408       switch (type) {
409
410       case SILC_ASN1_TAG_ANY:
411         {
412           /* ANY is another ASN.1 node.  We return the raw BER buffer as
413              the node */
414           SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, node);
415
416           *node = silc_buffer_srealloc_size(stack1, *node, len + rdata_len);
417           silc_buffer_put(*node, rdata - len, rdata_len + len);
418           break;
419         }
420
421       case SILC_ASN1_TAG_ANY_PRIMITIVE:
422         {
423           /* ANY_PRIMITIVE returns the raw data blob of any primitive type. */
424           SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, prim);
425
426           *prim = silc_buffer_srealloc_size(stack1, *prim, rdata_len);
427           silc_buffer_put(*prim, rdata, rdata_len);
428           break;
429         }
430
431       case SILC_ASN1_TAG_SEQUENCE:
432       case SILC_ASN1_TAG_SET:
433         {
434           /* SEQUENCE/SET is a sequence of types. */
435           silc_buffer_pull(src, len);
436           len = 0;
437
438           /* Get type, tag and options for the first argument in recursion */
439           SILC_ASN1_ARGS(asn1, rtype, rtag, rclass, ropts);
440
441           /* Decode the sequence recursively */
442           ret = silc_asn1_decoder(asn1, stack1, rtype, rtag, rclass,
443                                   ropts, src, depth + 1, FALSE);
444           if (!ret)
445             goto fail;
446           break;
447         }
448
449       case SILC_ASN1_TAG_INTEGER:
450       case SILC_ASN1_TAG_ENUM:
451         {
452           /* Integer/enum value. */
453           SilcMPInt z;
454           SILC_ASN1_VAD(asn1, opts, SilcMPInt, intval);
455
456           if (rdata_len < 1) {
457             SILC_LOG_DEBUG(("Malformed integer value"));
458             SILC_ASN1_VA_FREE(opts, intval);
459             ret = FALSE;
460             goto fail;
461           }
462
463           silc_mp_sinit(asn1->stack1, *intval);
464
465           /* Check whether the integer is positive or negative */
466           if (rdata[0] & 0x80) {
467             /* Negative integer stored in 1s complement.*/
468             for (i = 0; i < rdata_len; i++) {
469               silc_mp_mul_2exp(*intval, *intval, 8);
470               silc_mp_add_ui(*intval, *intval, ~rdata[i] & 0xff);
471             }
472
473             /* 2s complement and change sign */
474             silc_mp_init(&z);
475             silc_mp_set(&z, 0);
476             silc_mp_add_ui(*intval, *intval, 1);
477             silc_mp_sub(*intval, &z, *intval);
478             silc_mp_uninit(&z);
479           } else {
480             /* Positive */
481             silc_mp_bin2mp((unsigned char *)rdata, rdata_len, *intval);
482           }
483
484           break;
485         }
486
487       case SILC_ASN1_TAG_OID:
488         {
489           /* Object identifier */
490           SilcBufferStruct tmpb;
491           char tmpstr[24];
492           SilcUInt32 oid;
493           SILC_ASN1_VAD_CHAR(asn1, opts, char, oidstr);
494
495           if (rdata_len < 1) {
496             SILC_LOG_DEBUG(("Malformed object identifier value"));
497             ret = FALSE;
498             goto fail;
499           }
500
501           /* Set two OID values */
502           memset(&tmpb, 0, sizeof(tmpb));
503           memset(tmpstr, 0, sizeof(tmpstr));
504           snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
505                    (unsigned long)(rdata[0] & 0xff) / 40,
506                    (unsigned long)(rdata[0] & 0xff) % 40);
507           silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
508
509           /* Set rest of the OID values, each octet having 7 bits of the
510              OID value with bit 8 set.  An octet not having bit 8 set
511              means end of that OID value. */
512           for (i = 1; i < rdata_len; i++) {
513             oid = 0;
514             while (rdata[i] & 0x80) {
515               oid <<= 7;
516               oid |= rdata[i++] & 0x7f;
517               if (i >= rdata_len) {
518                 SILC_LOG_DEBUG(("Malformed object identifier value"));
519                 break;
520               }
521             }
522             oid <<= 7;
523             oid |= rdata[i];
524
525             memset(tmpstr, 0, sizeof(tmpstr));
526             snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
527             silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
528           }
529           *oidstr = tmpb.head;
530
531           break;
532         }
533
534       case SILC_ASN1_TAG_BOOLEAN:
535         {
536           /* Decode boolean (TRUE/FALSE) value */
537           SILC_ASN1_VAD(asn1, opts, SilcBool, val);
538
539           if (rdata_len != 1) {
540             SILC_LOG_DEBUG(("Malformed boolean value"));
541             SILC_ASN1_VA_FREE(opts, val);
542             ret = FALSE;
543             goto fail;
544           }
545
546           *(*val) = (rdata[0] == 0xff ? TRUE : FALSE);
547           break;
548         }
549
550       case SILC_ASN1_TAG_BIT_STRING:
551         {
552           /* Bit string contains data with exact bit length of the data */
553           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, d, d_len);
554
555           if (rdata_len < 2) {
556             SILC_LOG_DEBUG(("Malformed bit string value"));
557             ret = FALSE;
558             goto fail;
559           }
560
561           *d = silc_smemdup(stack1, rdata + 1, rdata_len - 1);
562           *d_len = (rdata_len - 1) * 8;
563           break;
564         }
565
566       case SILC_ASN1_TAG_NULL:
567         {
568           /* Decode empty BER block */
569           if (rdata_len != 0) {
570             SILC_LOG_DEBUG(("Malformed null value"));
571             goto fail;
572           }
573           break;
574         }
575
576       case SILC_ASN1_TAG_UTC_TIME:
577         {
578           /* Universal encoded time string */
579           SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
580
581           if (rdata_len < 1) {
582             SILC_LOG_DEBUG(("Malformed UTC time value"));
583             ret = FALSE;
584             goto fail;
585           }
586
587           /* Parse the time string */
588           if (!silc_time_universal(rdata, *t)) {
589             SILC_LOG_DEBUG(("Malformed UTC time value"));
590             ret = FALSE;
591             goto fail;
592           }
593
594           break;
595         }
596
597       case SILC_ASN1_TAG_GENERALIZED_TIME:
598         {
599           /* Generalized encoded time string */
600           SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
601
602           if (rdata_len < 1) {
603             SILC_LOG_DEBUG(("Malformed generalized time value"));
604             ret = FALSE;
605             goto fail;
606           }
607
608           /* Parse the time string */
609           if (!silc_time_generalized(rdata, *t)) {
610             SILC_LOG_DEBUG(("Malformed generalized time value"));
611             ret = FALSE;
612             goto fail;
613           }
614
615           break;
616         }
617
618       case SILC_ASN1_TAG_UTF8_STRING:
619         {
620           /* UTF-8 encoded string */
621           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
622
623           if (!silc_utf8_valid(rdata, rdata_len)) {
624             SILC_LOG_DEBUG(("Malformed UTF-8 string value"));
625             ret = FALSE;
626             goto fail;
627           }
628
629           *s = silc_smemdup(stack1, rdata, rdata_len);
630           *s_len = rdata_len;
631           break;
632         }
633
634       case SILC_ASN1_TAG_OCTET_STRING:
635         {
636           /* Octet string.  We take it as 8-bit ASCII */
637           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
638           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
639           break;
640         }
641
642       case SILC_ASN1_TAG_NUMERIC_STRING:
643         {
644           /* Numerical (digit) string */
645           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
646           SILC_ASN1_DECODE_STRING(SILC_STRING_NUMERICAL, s, s_len);
647           break;
648         }
649
650       case SILC_ASN1_TAG_PRINTABLE_STRING:
651         {
652           /* Printable string */
653           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
654           SILC_ASN1_DECODE_STRING(SILC_STRING_PRINTABLE, s, s_len);
655           break;
656         }
657
658       case SILC_ASN1_TAG_TELETEX_STRING:
659         {
660           /* Teletex (T61) string */
661           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
662           SILC_ASN1_DECODE_STRING(SILC_STRING_TELETEX, s, s_len);
663           break;
664         }
665
666       case SILC_ASN1_TAG_IA5_STRING:
667         {
668           /* US ASCII string */
669           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
670           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
671           break;
672         }
673
674       case SILC_ASN1_TAG_VISIBLE_STRING:
675         {
676           /* Visible string */
677           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
678           SILC_ASN1_DECODE_STRING(SILC_STRING_VISIBLE, s, s_len);
679           break;
680         }
681
682       case SILC_ASN1_TAG_UNIVERSAL_STRING:
683         {
684           /* Universal (UCS-4) string */
685           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
686           SILC_ASN1_DECODE_STRING(SILC_STRING_UNIVERSAL, s, s_len);
687           break;
688         }
689
690       case SILC_ASN1_TAG_UNRESTRICTED_STRING:
691       case SILC_ASN1_TAG_GENERAL_STRING:
692         {
693           /* Handle now unrestricted and general as 8-bit ascii, which
694              probably isn't correct. */
695           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
696           SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
697           break;
698         }
699
700       case SILC_ASN1_TAG_BMP_STRING:
701         {
702           /* BMP (UCS-2) string */
703           SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
704           SILC_ASN1_DECODE_STRING(SILC_STRING_BMP, s, s_len);
705           break;
706         }
707
708       case SILC_ASN1_TAG_ODE:
709       case SILC_ASN1_TAG_ETI:
710       case SILC_ASN1_TAG_REAL:
711       case SILC_ASN1_TAG_EMBEDDED:
712       case SILC_ASN1_TAG_ROI:
713       case SILC_ASN1_TAG_VIDEOTEX_STRING:
714       case SILC_ASN1_TAG_GRAPHIC_STRING:
715         {
716           SILC_NOT_IMPLEMENTED("Unsupported ASN.1 tag");
717           ret = FALSE;
718           goto fail;
719           break;
720         }
721
722       default:
723         SILC_LOG_DEBUG(("Invalid ASN.1 tag `%d'. Cannot decode ASN.1.",
724                         type));
725         ret = FALSE;
726         goto fail;
727         break;
728       }
729
730     cont:
731       /* Pull the current data from source which reveals next BER object */
732       if (found && len + rdata_len)
733         silc_buffer_pull(src, len + rdata_len);
734       if (primitive) {
735         ret = TRUE;
736         goto ok;
737       }
738
739       /* Get next type, tag and options */
740       rtype = type;
741       SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
742       if (type == SILC_ASN1_END) {
743         if (choice) {
744           if (!found) {
745             /* No choices were found, error */
746             SILC_LOG_DEBUG(("Invalid ASN.1 choice: no choices present"));
747             ret = FALSE;
748             goto fail;
749           }
750
751           /* Take next type and new BER object, choices are over */
752           choice = FALSE;
753           SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
754           if (type == SILC_ASN1_END) {
755             ret = TRUE;
756             goto ok;
757           }
758           break;
759         }
760
761         /* SEQUENCE/SET end */
762         ret = TRUE;
763         goto ok;
764       }
765
766       if (choice) {
767         /* Even if the choice was found we must go through rest of
768            the choices. */
769         if (found && len) {
770           SILC_LOG_DEBUG(("Found choice %s type", silc_asn1_tag_name(rtype)));
771           rdata_len = len = 0;
772         }
773         opts |= SILC_ASN1_OPTIONAL;
774         continue;
775       }
776
777       /* Optional type not present, check next one for match */
778       if (!found)
779         continue;
780
781       break;
782     }
783   }
784
785  fail:
786   SILC_LOG_DEBUG(("Error decoding type %d (depth %d)", type, depth));
787
788  ok:
789   if (ptr)
790     len = src->data - ptr;
791   else
792     len = src->data - src->head;
793   silc_buffer_push(src, len);
794
795   return ret;
796 }
797
798 SilcBool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...)
799 {
800   SilcAsn1Tag type, tag;
801   SilcAsn1Options opts;
802   SilcBerClass ber_class;
803   SilcStackFrame frame1, frame2;
804   SilcStack stack1 = NULL, stack2 = NULL;
805   SilcBool ret;
806
807   if (!asn1)
808     return FALSE;
809
810   va_start(asn1->ap, src);
811
812   /* Get the first arguments and call the decoder. */
813   SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
814   if (!type) {
815     va_end(asn1->ap);
816     asn1->ap = NULL;
817     return FALSE;
818   }
819
820   /* Handle internal options for decoder. */
821   if (type == SILC_ASN1_TAG_OPTS) {
822     SilcUInt32 o = va_arg(asn1->ap, SilcUInt32);
823
824     if (o & SILC_ASN1_ALLOC) {
825       /* User wants to alloate everything.  Set the stacks to NULL so
826          that stack aware calls revert to normal allocation routines. */
827       stack1 = asn1->stack1;
828       stack2 = asn1->stack2;
829       asn1->stack1 = NULL;
830       asn1->stack2 = NULL;
831     }
832
833     if (o & SILC_ASN1_ACCUMUL) {
834       /* If accumul flag is not set yet, then push the stacks. */
835       if (!asn1->accumul) {
836         silc_stack_push(asn1->stack1, NULL);
837         silc_stack_push(asn1->stack2, NULL);
838         asn1->accumul = 1;
839       }
840     }
841
842     /* Take again the arguments */
843     SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
844   } else {
845     /* No flags set, all flags will be reset. */
846
847     /* If accumul flag is set now pop the stack so that all accumulated
848        memory becomes free again. */
849     if (asn1->accumul) {
850       silc_stack_pop(asn1->stack1);
851       silc_stack_pop(asn1->stack2);
852       asn1->accumul = 0;
853     }
854   }
855
856   /* Push stacks for normal allocation from stack */
857   if (!asn1->accumul) {
858     silc_stack_push(asn1->stack1, &frame1);
859     silc_stack_push(asn1->stack2, &frame2);
860   }
861
862   /* Start decoding */
863   ret = silc_asn1_decoder(asn1, asn1->stack1, type, tag, ber_class,
864                           opts, src, 0, FALSE);
865
866   /* Pop stacks to free normal allocations from stack. They remain valid
867      for every second call to this function. */
868   if (!asn1->accumul) {
869     silc_stack_pop(asn1->stack1);
870     silc_stack_pop(asn1->stack2);
871
872     /* Switch the asn1->stack1 and asn1->stack2.  This way next call to
873        this function does not invalidate these results.  Every second call
874        invalidates the results of every second previous results. */
875     if (asn1->stack1 && asn1->stack2) {
876       stack1 = asn1->stack1;
877       asn1->stack1 = asn1->stack2;
878       asn1->stack2 = stack1;
879     }
880   }
881
882   if (stack1 && stack2 && !asn1->stack1 && !asn1->stack2) {
883     /* SILC_ASN1_ALLOC flag was set, restore the stacks. */
884     asn1->stack1 = stack1;
885     asn1->stack2 = stack2;
886   }
887
888   va_end(asn1->ap);
889   asn1->ap = NULL;
890
891   return ret;
892 }