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