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