Initial code commit for Toolkit 1.1.
[silc.git] / lib / silcasn1 / silcasn1.h
1 /*
2
3   silcasn1.h
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 /****h* silcasn1/ASN.1 Interface
21  *
22  * DESCRIPTION
23  *
24  * Efficient Abstract Syntax Notation One (ASN.1) implementation.  This
25  * interface provides simple and efficient ASN.1 encoder and decoder.
26  * The encoder directly encodes BER encoded data blocks from variable
27  * argument list of ASN.1 types.  Multiple trees can be encoded at once
28  * and multiple nodes can be encoded into the tree at once.  By default
29  * encoder does not allocate any memory during encoding but a pre-allocated
30  * SilcStack is used as memory.
31  *
32  * The decoder directly decodes BER encoded data blocks into the correct
33  * types dictated by the variable argument list of ASN.1 types.  By
34  * default decoder does not allocate any memory during decoding but a
35  * pre-allocated SilcStack is used as memory.
36  *
37  * The encoding and decoding interface is simple.  silc_asn1_encode is used
38  * encode and silc_asn1_decode to decode.  The actual ASN.1 is defined
39  * as variable argument list to the function.  Various macros can be used
40  * to encode and decode different ASN.1 types.  All types may also be used
41  * to encode and decode with various options (such as implicit and explicit
42  * tagging and defining specific class option).
43  *
44  * The implementation supports all the common ASN.1 types.  This
45  * implementation does not support advanced ASN.1 features like macros.
46  *
47  * References: ITU-T X.680 - X.693
48  * http://www.itu.int/ITU-T/studygroups/com17/languages/
49  *
50  ***/
51
52 #ifndef SILCASN1_H
53 #define SILCASN1_H
54
55 /****s* silcasn1/SilcASN1API/SilcAsn1
56  *
57  * NAME
58  *
59  *    typedef struct SilcAsn1Object *SilcAsn1;
60  *
61  * DESCRIPTION
62  *
63  *    This context is the actual ASN.1 encoder/decoder and is allocated
64  *    by silc_asn1_alloc and given as argument to all silc_asn1_*
65  *    functions.  It is freed by the silc_asn1_free function.  It is
66  *    also possible to use pre-allocated ASN.1 context by using the
67  *    SilcAsn1Struct instead of SilcAsn1.
68  *
69  ***/
70 typedef struct SilcAsn1Object *SilcAsn1;
71
72 /****s* silcasn1/SilcASN1API/SilcAsn1Struct
73  *
74  * NAME
75  *
76  *    typedef struct SilcAsn1Object SilcAsn1Struct;
77  *
78  * DESCRIPTION
79  *
80  *    This context is the actual ASN.1 encoder/decoder and can be
81  *    used as pre-allocated ASN.1 context instead of SilcAsn1 context.
82  *    This context is initialized with silc_asn1_init and uninitialized
83  *    with silc_asn1_uninit.
84  *
85  ***/
86 typedef struct SilcAsn1Object SilcAsn1Struct;
87
88 /****d* silcasn1/SilcASN1API/SilcAsn1Options
89  *
90  * NAME
91  *
92  *    typedef enum { ... } SilcAsn1Options;
93  *
94  * DESCRIPTION
95  *
96  *    Options for ASN.1 encoder and decoder.  The ASN.1 options can be
97  *    given to the SILC_ASN1_*_T macros and/or SILC_ASN1_OPTS macro.
98  *
99  * NOTES
100  *
101  *    The SILC_ASN1_ALLOC and SILC_ASN1_ACCUMUL flags can be given only
102  *    with SILC_ASN1_OPTS macro.  Other options can be given with various
103  *    SILC_ASN1_*_T macros.
104  *
105  * SOURCE
106  */
107 typedef enum {
108   /* Default. If only this is set then defaults are implied. */
109   SILC_ASN1_DEFAULT      = 0x0000,
110
111   /* Class options.  User does not need to set these unless specificly
112      wanted to do so.  If SILC_ASN1_DEFAULT is set the SILC_ASN1_CONTEXT is
113      implied if any of the tag options are set.  Otherwise SILC_ASN1_UNIVERSAL
114      is implied. Only one of these can bet set at once. */
115   SILC_ASN1_UNIVERSAL    = 0x0001,       /* Universal class (default) */
116   SILC_ASN1_APP          = 0x0002,       /* Application specific class */
117   SILC_ASN1_CONTEXT      = 0x0003,       /* Context specific class */
118   SILC_ASN1_PRIVATE      = 0x0004,       /* Private class */
119
120   /* Tag options (bitmask) */
121   SILC_ASN1_IMPLICIT     = 0x0010,       /* Tag is implicit (default) */
122   SILC_ASN1_EXPLICIT     = 0x0020,       /* Tag is explicit */
123   SILC_ASN1_DEFINITE     = 0x0040,       /* Length is definite (default) */
124   SILC_ASN1_INDEFINITE   = 0x0080,       /* Length is indefinite */
125
126   /* Decoding options (bitmask) */
127   SILC_ASN1_OPTIONAL     = 0x0100,       /* Zero or more may be found.  The
128                                             argument must be pointer to the
129                                             type pointer so that NULL can be
130                                             returned if type is not found. */
131
132   /* ASN.1 encoder/decoder options (bitmask).  These can be given
133      only with SILC_ASN1_OPTS macro at the start of encoding/decoding. */
134   SILC_ASN1_ALLOC        = 0x0400,       /* Dynamically allocate results */
135   SILC_ASN1_ACCUMUL      = 0x0800,       /* Accumulate memory for results,
136                                             next call to silc_asn1_decode
137                                             will not cancel old results. */
138 } SilcAsn1Options;
139 /***/
140
141 /****d* silcasn1/SilcASN1API/SilcAsn1Tag
142  *
143  * NAME
144  *
145  *    typedef enum { ... } SilcAsn1Tag;
146  *
147  * DESCRIPTION
148  *
149  *    Universal ASN.1 tags.  Usually these tags are given automatically
150  *    to the silc_asn1_encode and silc_asn1_decode by using the various
151  *    macros (such as SILC_ASN1_BOOLEAN).  Some macros may take the tag
152  *    as additional argument.
153  *
154  * SOURCE
155  */
156 typedef enum {
157   SILC_ASN1_TAG_BOOLEAN               = 1,  /* SILC_ASN1_BOOLEAN */
158   SILC_ASN1_TAG_INTEGER               = 2,  /* SILC_ASN1_INT */
159   SILC_ASN1_TAG_BIT_STRING            = 3,  /* SILC_ASN1_BIT_STRING */
160   SILC_ASN1_TAG_OCTET_STRING          = 4,  /* SILC_ASN1_OCTET_STRING */
161   SILC_ASN1_TAG_NULL                  = 5,  /* SILC_ASN1_NULL */
162   SILC_ASN1_TAG_OID                   = 6,  /* SILC_ASN1_OID */
163   SILC_ASN1_TAG_ODE                   = 7,  /* not supported */
164   SILC_ASN1_TAG_ETI                   = 8,  /* not supported */
165   SILC_ASN1_TAG_REAL                  = 9,  /* not supported */
166   SILC_ASN1_TAG_ENUM                  = 10, /* SILC_ASN1_ENUM */
167   SILC_ASN1_TAG_EMBEDDED              = 11, /* not supported */
168   SILC_ASN1_TAG_UTF8_STRING           = 12, /* SILC_ASN1_UTF8_STRING */
169   SILC_ASN1_TAG_ROI                   = 13, /* not supported */
170   SILC_ASN1_TAG_SEQUENCE              = 16, /* SILC_ASN1_SEQUENCE */
171   SILC_ASN1_TAG_SET                   = 17, /* SILC_ASN1_SET */
172   SILC_ASN1_TAG_NUMERIC_STRING        = 18, /* SILC_ASN1_NUMERIC_STRING */
173   SILC_ASN1_TAG_PRINTABLE_STRING      = 19, /* SILC_ASN1_PRINTABLE_STRING */
174   SILC_ASN1_TAG_TELETEX_STRING        = 20, /* SILC_ASN1_TELETEX_STRING */
175   SILC_ASN1_TAG_VIDEOTEX_STRING       = 21, /* not supported */
176   SILC_ASN1_TAG_IA5_STRING            = 22, /* SILC_ASN1_IA5_STRING */
177   SILC_ASN1_TAG_UTC_TIME              = 23, /* SILC_ASN1_UTC_TIME */
178   SILC_ASN1_TAG_GENERALIZED_TIME      = 24, /* SILC_ASN1_GENERAL_STRING */
179   SILC_ASN1_TAG_GRAPHIC_STRING        = 25, /* not supported */
180   SILC_ASN1_TAG_VISIBLE_STRING        = 26, /* SILC_ASN1_VISIBLE_STRING */
181   SILC_ASN1_TAG_GENERAL_STRING        = 27, /* SILC_ASN1_GENERAL_STRING */
182   SILC_ASN1_TAG_UNIVERSAL_STRING      = 28, /* SILC_ASN1_UNIVERSAL_STRING */
183   SILC_ASN1_TAG_UNRESTRICTED_STRING   = 29, /* SILC_ASN1_UNRESTRICTED_STRING */
184   SILC_ASN1_TAG_BMP_STRING            = 30, /* SILC_ASN1_BMP_STRING */
185 } SilcAsn1Tag;
186 /***/
187
188 #include "silcasn1_i.h"
189
190 /****f* silcasn1/SilcASN1API/silc_asn1_alloc
191  *
192  * SYNOPSIS
193  *
194  *    SilcAsn1 silc_asn1_alloc(void);
195  *
196  * DESCRIPTION
197  *
198  *    Allocates and initializes ASN.1 encoder/decoder and returns SilcAsn1
199  *    context or NULL on error.  This context can be used with both
200  *    silc_asn1_encode and silc_asn1_decode functions.
201  *
202  *    Usually SilcAsn1 is allocated when encoder or decoder is needed,
203  *    however it is also possible to allocate long-lasting SilcAsn1 and
204  *    use that every time ASN.1 routines are needed.  Application could
205  *    for example allocate one SilcAsn1 and use that for all ASN.1 encoding
206  *    and decoding.
207  *
208  *    When this context is freed with silc_asn1_free all memory will be
209  *    freed, and all encoded ASN.1 buffers becomes invalid.  Also all
210  *    data that is returned by silc_asn1_decode function becomes invalid.
211  *
212  ***/
213 SilcAsn1 silc_asn1_alloc(void);
214
215 /****f* silcasn1/SilcASN1API/silc_asn1_free
216  *
217  * SYNOPSIS
218  *
219  *    void silc_asn1_free(SilcAsn1 asn1);
220  *
221  * DESCRIPTION
222  *
223  *    Frees the SilcAsn1 context and all allocated memory.  All encoded
224  *    buffers and all decoded buffers with this context becomes invalid
225  *    after this call.
226  *
227  ***/
228 void silc_asn1_free(SilcAsn1 asn1);
229
230 /****f* silcasn1/SilcASN1API/silc_asn1_init
231  *
232  * SYNOPSIS
233  *
234  *    bool silc_asn1_init(SilcAsn1 asn1);
235  *
236  * DESCRIPTION
237  *
238  *    Initializes a pre-allocated SilcAsn1 context.  This call is
239  *    equivalent to silc_asn1_alloc except that this takes the pre-allocated
240  *    context as argument.
241  *
242  * EXAMPLE
243  *
244  *    SilcAsn1Struct asn1;
245  *    if (!silc_asn1_init(&asn1))
246  *      error;
247  *
248  ***/
249 bool silc_asn1_init(SilcAsn1 asn1);
250
251 /****f* silcasn1/SilcASN1API/silc_asn1_uninit
252  *
253  * SYNOPSIS
254  *
255  *    void silc_asn1_uninit(SilcAsn1 asn1);
256  *
257  * DESCRIPTION
258  *
259  *    Uninitializes a pre-allocated SilcAsn1 context.  Use this function
260  *    instead of silc_asn1_free if you used silc_asn1_init.
261  *
262  ***/
263 void silc_asn1_uninit(SilcAsn1 asn1);
264
265 /****f* silcasn1/SilcASN1API/silc_asn1_encode
266  *
267  * SYNOPSIS
268  *
269  *    bool silc_asn1_encode(SilcAsn1 asn1, SilcBuffer dest, ...);
270  *
271  * DESCRIPTION
272  *
273  *    Encodes ASN.1 encoded buffer into `dest', from variable argument
274  *    list of ASN.1 types.  The variable argument list forms the ASN.1
275  *    trees and nodes that are encoded into the `dest'.  By default, the
276  *    memory for `dest' is allocated from the `asn1', and the buffer becomes
277  *    invalid either by calling silc_asn1_free, silc_asn1_uninit, or when
278  *    silc_asn1_encode is called for the next time.
279  *
280  *    If the SILC_ASN1_OPTS macro with SILC_ASN1_ALLOC option is given then
281  *    the `dest' is dynamically allocated and caller must free it by itself.
282  *    Alternatively if SILC_ASN1_ACCUMUL is given then memory is accumulated
283  *    from `asn1' for `dest' and it is freed only when silc_asn1_free or
284  *    silc_asn1_uninit is called.  Next call to silc_asn1_encode will not
285  *    cancel the previous result, but will accumulate more memory for new
286  *    result.
287  *
288  *    The variable argument list is constructed by using various
289  *    macros, for example SILC_ASN1_SEQUENCE, etc.  The variable argument
290  *    list must always be ended with SILC_ASN1_END type.
291  *
292  *    If encoding is successful this returns TRUE, FALSE on error.
293  *
294  * EXAMPLE
295  *
296  *    silc_asn1_encode(asn1, buf,
297  *                     SILC_ASN1_SEQUENCE,
298  *                       SILC_ASN1_BOOLEAN(bool_val),
299  *                       SILC_ASN1_OCTET_STRING(string, string_len),
300  *                       SILC_ASN1_SEQUENCE_T(0, 2),
301  *                         SILC_ASN1_BOOLEAN_T(SILC_ASN1_EXPLICIT, 100, foo),
302  *                       SILC_ASN1_END,
303  *                       SILC_ASN1_OCTET_STRING_T(0, 1, string2, string2_len),
304  *                     SILC_ASN1_END, SILC_ASN1_END);
305  *
306  *    Creates ASN.1 tree that looks something like:
307  *
308  *    buf ::= SEQUENCE {
309  *      bool_val      BOOLEAN,
310  *      string        OCTET-STRING,
311  *               [2]  SEQUENCE {
312  *                      foo   [100] EXPLICIT BOOLEAN }
313  *      string2  [1]  OCTET-STRING }
314  *
315  ***/
316 bool silc_asn1_encode(SilcAsn1 asn1, SilcBuffer dest, ...);
317
318 /****f* silcasn1/SilcASN1API/silc_asn1_decode
319  *
320  * SYNOPSIS
321  *
322  *    bool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...);
323  *
324  * DESCRIPTION
325  *
326  *    Decodes the ASN.1 encoded buffer `src' by the ASN.1 types sent
327  *    as argument.  The ASN.1 types sent as argument must be found from
328  *    the `src' for this function to decode successfully.
329  *
330  *    The memory allocated for the results are allocated from `asn1' and
331  *    they become invalid if `asn1' becomes invalid.  Next (second) call
332  *    to this function does NOT invalidate the previous results.  However,
333  *    third call to this function does invalidate the results of the first
334  *    call but not second.  On the other hand, fourth call invalidates
335  *    the results of the second call but not third, fifth call invalidates
336  *    the results of the third call but not fourth, and so on.  This allows
337  *    efficient decoding, when silc_asn1_decode must be called multiple times
338  *    to decode all data, without new memory allocations.  However, caller
339  *    must be cautios and understand that the every second call invalidates
340  *    the results of every second previous results.
341  *
342  *    If the SILC_ASN1_OPTS macro with SILC_ASN1_ALLOC option is given then
343  *    all results are dynamically allocated and caller must free them by
344  *    itself. Alternatively if SILC_ASN1_ACCUMUL is given then memory is
345  *    accumulated from `asn1' for results and they are freed only when the
346  *    silc_asn1_free or silc_asn1_uninit is called.  Next calls to the
347  *    silc_asn1_decode will NOT invalidate the old results, but will
348  *    accumulate more memory for new results.  If the SILC_ASN1_OPTS is not
349  *    given at all then the default allocation method (decribed above)
350  *    applies.
351  *
352  *    If caller needs to store the results even after `asn1' becomes invalid
353  *    then call must either use SILC_ASN1_ALLOC option or duplicate the
354  *    results by itself.
355  *
356  * EXAMPLE
357  *
358  *    bool bool_val, foo;
359  *    unsigned char *string, string2;
360  *    SilcUInt32 string_len, string2_len;
361  *
362  *    silc_asn1_decode(asn1, tree,
363  *                     SILC_ASN1_SEQUENCE,
364  *                       SILC_ASN1_BOOLEAN(&bool_val),
365  *                       SILC_ASN1_OCTET_STRING(&string, &string_len),
366  *                       SILC_ASN1_SEQUENCE_T(0, 2),
367  *                         SILC_ASN1_BOOLEAN_T(SILC_ASN1_EXPLICIT, 100, &foo),
368  *                       SILC_ASN1_END,
369  *                       SILC_ASN1_OCTET_STRING_T(0, 1, &str2, &str2_len),
370  *                     SILC_ASN1_END, SILC_ASN1_END);
371  *
372  ***/
373 bool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...);
374
375 /****f* silcasn1/SilcASN1API/SILC_ASN1_OPTS
376  *
377  * SYNOPSIS
378  *
379  *    SILC_ASN1_OPTS(opts)
380  *
381  * DESCRIPTION
382  *
383  *    The `opts' is SilcAsn1Options.  This macro can be used to set
384  *    options for silc_asn1_encode and silc_asn1_decode functions.
385  *
386  * NOTES
387  *
388  *    Only the SILC_ASN1_ALLOC and SILC_ASN1_ACCUMUL flags may be
389  *    set with this macro.
390  *
391  *    This macro must be the first macro in the variable argument list
392  *    in the function.
393  *
394  * EXAMPLE
395  *
396  *    silc_asn1_decode(asn1, tree,
397  *                     SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
398  *                     SILC_ASN1_SEQUENCE,
399  *                       SILC_ASN1_BOOLEAN(&bool_val),
400  *                       SILC_ASN1_OCTET_STRING(&string, &string_len),
401  *                     SILC_ASN1_END, SILC_ASN1_END);
402  *
403  ***/
404 #define SILC_ASN1_OPTS(opts) SILC_ASN1_TAG_OPTS, (opts)
405
406 /****f* silcasn1/SilcASN1API/SILC_ASN1_ANY
407  *
408  * SYNOPSIS
409  *
410  *    Encoding:
411  *    SILC_ASN1_ANY(buffer)
412  *    SILC_ASN1_ANY_T(opts, tag, buffer)
413  *
414  *    Decoding:
415  *    SILC_ASN1_ANY(&buffer)
416  *    SILC_ASN1_ANY_T(opts, tag, &buffer)
417  *
418  * DESCRIPTION
419  *
420  *    Macro used to encode or decode another ASN.1 node.  The buffer type
421  *    is SilcBuffer.  This macro can be used for example to split large
422  *    tree into multiple nodes, and then decoding the nodes separately from
423  *    the buffers.
424  *
425  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
426  *
427  * EXAMPLE
428  *
429  *    // Encode node of two boolean values
430  *    silc_asn1_encode(asn1, node,
431  *                     SILC_ASN1_BOOLEAN(val1),
432  *                     SILC_ASN1_BOOLEAN(val2),
433  *                     SILC_ASN1_END);
434  *
435  *    // Encode tree with the node
436  *    silc_asn1_encode(asn1, tree,
437  *                     SILC_ASN1_SEQUENCE_T(SILC_ASN1_PRIVATE, 101),
438  *                       SILC_ASN1_ANY(node),
439  *                       SILC_ASN1_BOOLEAN(boolval),
440  *                     SILC_ASN1_END, SILC_ASN1_END);
441  *
442  ***/
443 #define SILC_ASN1_ANY(x) SILC_ASN1_U1(ANY, x)
444 #define SILC_ASN1_ANY_T(o, t, x) SILC_ASN1_T1(ANY, o, t, x)
445
446 /****f* silcasn1/SilcASN1API/SILC_ASN1_SEQUENCE
447  *
448  * SYNOPSIS
449  *
450  *    Encoding:
451  *    SILC_ASN1_SEQUENCE
452  *    SILC_ASN1_SEQUENCE_T(opts, tag)
453  *
454  *    Decoding:
455  *    SILC_ASN1_SEQUENCE
456  *    SILC_ASN1_SEQUENCE_T(opts, tag)
457  *
458  * DESCRIPTION
459  *
460  *    Macro used to encode or decode sequence.  The sequence must be
461  *    terminated with SILC_ASN1_END.
462  *
463  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
464  *
465  * EXAMPLE
466  *
467  *    silc_asn1_encode(asn1, tree,
468  *                     SILC_ASN1_SEQUENCE,
469  *                       SILC_ASN1_ANY(node),
470  *                       SILC_ASN1_BOOLEAN(boolval),
471  *                     SILC_ASN1_END, SILC_ASN1_END);
472  *
473  ***/
474 #define SILC_ASN1_SEQUENCE SILC_ASN1_U0(SEQUENCE)
475 #define SILC_ASN1_SEQUENCE_T(o, t) SILC_ASN1_T0(SEQUENCE, o, t)
476
477 /****f* silcasn1/SilcASN1API/SILC_ASN1_SET
478  *
479  * SYNOPSIS
480  *
481  *    Encoding:
482  *    SILC_ASN1_SET
483  *    SILC_ASN1_SET_T(opts, tag)
484  *
485  *    Decoding:
486  *    SILC_ASN1_SET
487  *    SILC_ASN1_SET_T(opts, tag)
488  *
489  * DESCRIPTION
490  *
491  *    Macro used to encode or decode set.  The set must be terminated
492  *    with SILC_ASN1_END.
493  *
494  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
495  *
496  * EXAMPLE
497  *
498  *    silc_asn1_encode(asn1, tree,
499  *                     SILC_ASN1_SET_T(SILC_ASN1_EXPLICIT, 0),
500  *                       SILC_ASN1_BOOLEAN(boolval),
501  *                     SILC_ASN1_END, SILC_ASN1_END);
502  *
503  ***/
504 #define SILC_ASN1_SET SILC_ASN1_U0(SET)
505 #define SILC_ASN1_SET_T(o, t) SILC_ASN1_T0(SET, o, t)
506
507 /****f* silcasn1/SilcASN1API/SILC_ASN1_SEQUENCE_OF
508  *
509  * SYNOPSIS
510  *
511  *    Decoding:
512  *    SILC_ASN1_SEQUENCE_OF(bufarray, numbufs)
513  *
514  * DESCRIPTION
515  *
516  *    Macro used to decode sequence of specified type.  This returns
517  *    an array of SilcBuffers and number of buffers in the array.  The
518  *    SILC_ASN1_CHOICE macro may also be used with this macro.
519  *
520  * NOTES
521  *
522  *    This macro must be used either with SILC_ASN1_ALLOC or SILC_ASN1_ACCUMUL
523  *    flags.  Do not use this macro without flags.
524  *
525  * EXAMPLE
526  *
527  *     SilcBuffer bufs;
528  *     SilcUInt32 count;
529  *
530  *     // Decode sequence of sequences.  Each returned buffer in the array
531  *     // is a sequence.
532  *     silc_asn1_decode(asn1, exts,
533  *                      SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
534  *                      SILC_ASN1_SEQUENCE_OF(&bufs, &count),
535  *                        SILC_ASN1_TAG_SEQUENCE,
536  *                      SILC_ASN1_END, SILC_ASN1_END);
537  *
538  ***/
539 #define SILC_ASN1_SEQUENCE_OF(x, c) SILC_ASN1_U2(SEQUENCE_OF, x, c)
540
541 /****f* silcasn1/SilcASN1API/SILC_ASN1_SET_OF
542  *
543  * SYNOPSIS
544  *
545  *    Decoding:
546  *    SILC_ASN1_SET_OF(bufarray, numbufs)
547  *
548  * DESCRIPTION
549  *
550  *    Macro used to decode set of specified type.  This returns
551  *    an array of SilcBuffers and number of buffers in the array.  The
552  *    SILC_ASN1_CHOICE macro may also be used with this macro.
553  *
554  * NOTES
555  *
556  *    This macro must be used either with SILC_ASN1_ALLOC or SILC_ASN1_ACCUMUL
557  *    flags.  Do not use this macro without flags.
558  *
559  * EXAMPLE
560  *
561  *     // Decode set of sequences.  Each returned buffer in the array
562  *     // is a sequence.
563  *     silc_asn1_decode(asn1, exts,
564  *                      SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
565  *                      SILC_ASN1_SET_OF(&bufs, &count),
566  *                        SILC_ASN1_TAG_SEQUENCE,
567  *                      SILC_ASN1_END, SILC_ASN1_END);
568  *
569  ***/
570 #define SILC_ASN1_SET_OF(x, c) SILC_ASN1_U2(SEQUENCE_OF, x, c)
571
572 /****f* silcasn1/SilcASN1API/SILC_ASN1_CHOICE
573  *
574  * SYNOPSIS
575  *
576  *    Decoding:
577  *    SILC_ASN1_CHOICE
578  *
579  * DESCRIPTION
580  *
581  *    Macro used to specify choices in decoding.  The choice list must
582  *    be terminated with SILC_ASN1_END.  There is no limit how many choices
583  *    can be specified in the list.
584  *
585  * EXAMPLE
586  *
587  *    // Decode timeval that is either UTC or generalized time
588  *    silc_asn1_decode(asn1, tree,
589  *                     SILC_ASN1_SEQUENCE,
590  *                       SILC_ASN1_CHOICE,
591  *                         SILC_ASN1_UTC_TIME(&timeval),
592  *                         SILC_ASN1_GEN_TIME(&timeval),
593  *                       SILC_ASN1_END,
594  *                     SILC_ASN1_END, SILC_ASN1_END);
595  *
596  ***/
597 #define SILC_ASN1_CHOICE SILC_ASN1_U0(CHOICE)
598
599 /****f* silcasn1/SilcASN1API/SILC_ASN1_BOOLEAN
600  *
601  * SYNOPSIS
602  *
603  *    Encoding:
604  *    SILC_ASN1_BOOLEAN(bool)
605  *    SILC_ASN1_BOOLEAN_T(opts, tag, bool)
606  *
607  *    Decoding:
608  *    SILC_ASN1_BOOLEAN(&bool)
609  *    SILC_ASN1_BOOLEAN_T(opts, tag, &bool)
610  *
611  * DESCRIPTION
612  *
613  *    Macro used to encode or decode boolean value.  Type boolean type
614  *    is bool.
615  *
616  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
617  *
618  ***/
619 #define SILC_ASN1_BOOLEAN(x) SILC_ASN1_U1(BOOLEAN, x)
620 #define SILC_ASN1_BOOLEAN_T(o, t, x) SILC_ASN1_T1(BOOLEAN, o, t, x)
621
622 /****f* silcasn1/SilcASN1API/SILC_ASN1_INT
623  *
624  * SYNOPSIS
625  *
626  *    Encoding:
627  *    SILC_ASN1_INT(integer)
628  *    SILC_ASN1_INT_T(opts, tag, integer)
629  *
630  *    Decoding:
631  *    SILC_ASN1_INT(&integer)
632  *    SILC_ASN1_INT_T(opts, tag, &integer);
633  *
634  * DESCRIPTION
635  *
636  *    Macro used to encode or decode multiple precision integer.  The
637  *    integer type is SilcMPInt.
638  *
639  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
640  *
641  ***/
642 #define SILC_ASN1_INT(x) SILC_ASN1_U1(INTEGER, x)
643 #define SILC_ASN1_INT_T(o, t, x) SILC_ASN1_T1(INTEGER, o, t, x)
644
645 /****f* silcasn1/SilcASN1API/SILC_ASN1_ENUM
646  *
647  * SYNOPSIS
648  *
649  *    Encoding:
650  *    SILC_ASN1_ENUM(enum)
651  *    SILC_ASN1_ENUM_T(opts, tag, enum)
652  *
653  *    Decoding:
654  *    SILC_ASN1_ENUM(&enum)
655  *    SILC_ASN1_ENUM_T(opts, tag, &enum);
656  *
657  * DESCRIPTION
658  *
659  *    Macro used to encode or decode enumeration value.  The enumeration
660  *    type is SilcMPInt.
661  *
662  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
663  *
664  ***/
665 #define SILC_ASN1_ENUM(x) SILC_ASN1_U1(ENUM, x)
666 #define SILC_ASN1_ENUM_T(o, t, x) SILC_ASN1_T1(ENUM, o, t, x)
667
668 /****f* silcasn1/SilcASN1API/SILC_ASN1_BIT_STRING
669  *
670  * SYNOPSIS
671  *
672  *    Encoding:
673  *    SILC_ASN1_BIT_STRING(str, str_len)
674  *    SILC_ASN1_BIT_STRING_T(opts, tag, str, str_len)
675  *
676  *    Decoding:
677  *    SILC_ASN1_BIT_STRING(&str, &str_len)
678  *    SILC_ASN1_BIT_STRING_T(opts, tag, &str, &str_len)
679  *
680  * DESCRIPTION
681  *
682  *    Macro used to encode or decode bit string.  The string length in
683  *    encoding must be in bits (bytes * 8).  The decoded length is in
684  *    bits as well.  The string type is unsigned char and string length
685  *    SilcUInt32.
686  *
687  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
688  *
689  ***/
690 #define SILC_ASN1_BIT_STRING(x, xl) SILC_ASN1_U2(BIT_STRING, x, xl)
691 #define SILC_ASN1_BIT_STRING_T(o, t, x, xl) SILC_ASN1_T2(BIT_STRING, o, t, x, xl)
692
693 /****f* silcasn1/SilcASN1API/SILC_ASN1_NULL
694  *
695  * SYNOPSIS
696  *
697  *    Encoding:
698  *    SILC_ASN1_NULL
699  *    SILC_ASN1_NULL_T(opts, tag)
700  *
701  *    Decoding:
702  *    SILC_ASN1_NULL
703  *    SILC_ASN1_NULL_T(opts, tag)
704  *
705  * DESCRIPTION
706  *
707  *    Macro used to encode or decode null value.
708  *
709  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
710  *
711  ***/
712 #define SILC_ASN1_NULL SILC_ASN1_U0(NULL)
713 #define SILC_ASN1_NULL_T(o, t) SILC_ASN1_T0(NULL, 0, t)
714
715 /****f* silcasn1/SilcASN1API/SILC_ASN1_OID
716  *
717  * SYNOPSIS
718  *
719  *    Encoding:
720  *    SILC_ASN1_OID(oid)
721  *    SILC_ASN1_OID_T(opts, tag, oid)
722  *
723  *    Decoding:
724  *    SILC_ASN1_OID(&oid)
725  *    SILC_ASN1_OID_T(opts, tag, &oid)
726  *
727  * DESCRIPTION
728  *
729  *    Macro used to encode or decode OID string.  The OID string type
730  *    is NULL terminated char.  Its length can be determinted with strlen().
731  *
732  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
733  *
734  ***/
735 #define SILC_ASN1_OID(x) SILC_ASN1_U1(OID, x)
736 #define SILC_ASN1_OID_T(o, t, x) SILC_ASN1_UT(OID, o, t, x)
737
738 /****f* silcasn1/SilcASN1API/SILC_ASN1_OCTET_STRING
739  *
740  * SYNOPSIS
741  *
742  *    Encoding:
743  *    SILC_ASN1_OCTET_STRING(str, str_len)
744  *    SILC_ASN1_OCTET_STRING_T(opts, tag, str, str_len)
745  *
746  *    Decoding:
747  *    SILC_ASN1_OCTET_STRING(&str, &str_len)
748  *    SILC_ASN1_OCTET_STRING_T(opts, tag, &str, &str_len)
749  *
750  * DESCRIPTION
751  *
752  *    Macro used to encode or decode octet string.  The string type is
753  *    unsigned char and string length SilcUInt32.
754  *
755  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
756  *
757  * NOTES
758  *
759  *    The string must be in UTF-8 encoding when encoding.  The decoded
760  *    string will be in UTF-8 encoding.  The actual data is encoded to
761  *    or decoded from 8-bit ASCII.
762  *
763  ***/
764 #define SILC_ASN1_OCTET_STRING(x, xl) SILC_ASN1_U2(OCTET_STRING, x, xl)
765 #define SILC_ASN1_OCTET_STRING_T(o, t, x, xl) SILC_ASN1_T2(OCTET_STRING, o, t, x, xl)
766
767 /****f* silcasn1/SilcASN1API/SILC_ASN1_UTF8_STRING
768  *
769  * SYNOPSIS
770  *
771  *    Encoding:
772  *    SILC_ASN1_UTF8_STRING(str, str_len)
773  *    SILC_ASN1_UTF8_STRING_T(opts, tag, str, str_len)
774  *
775  *    Decoding:
776  *    SILC_ASN1_UTF8_STRING(&str, &str_len)
777  *    SILC_ASN1_UTF8_STRING_T(opts, tag, &str, &str_len)
778  *
779  * DESCRIPTION
780  *
781  *    Macro used to encode or decode UTF-8 string.  The string type is
782  *    unsigned char and string length SilcUInt32.
783  *
784  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
785  *
786  * NOTES
787  *
788  *    The string must be in UTF-8 encoding when encoding.  The decoded
789  *    string will be in UTF-8 encoding.  The data is also encoded to
790  *    or decoded from UTF-8.
791  *
792  ***/
793 #define SILC_ASN1_UTF8_STRING(x, xl) SILC_ASN1_U2(UTF8_STRING, x, xl)
794 #define SILC_ASN1_UTF8_STRING_T(o, t, x, xl) SILC_ASN1_T2(UTF8_STRING, o, t, x, xl)
795
796 /****f* silcasn1/SilcASN1API/SILC_ASN1_NUMERIC_STRING
797  *
798  * SYNOPSIS
799  *
800  *    Encoding:
801  *    SILC_ASN1_NUMERIC_STRING(str, str_len)
802  *    SILC_ASN1_NUMERIC_STRING_T(opts, tag, str, str_len)
803  *
804  *    Decoding:
805  *    SILC_ASN1_NUMERIC_STRING(&str, &str_len)
806  *    SILC_ASN1_NUMERIC_STRING_T(opts, tag, &str, &str_len)
807  *
808  * DESCRIPTION
809  *
810  *    Macro used to encode or decode numerical string.  The string type is
811  *    unsigned char and string length SilcUInt32.
812  *
813  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
814  *
815  * NOTES
816  *
817  *    The string must be in UTF-8 encoding when encoding.  The decoded
818  *    string will be in UTF-8 encoding.  The actual data is encoded to
819  *    or decoded from numerical.
820  *
821  ***/
822 #define SILC_ASN1_NUMERIC_STRING(x, xl) SILC_ASN1_U2(NUMERIC_STRING, x, xl)
823 #define SILC_ASN1_NUMERIC_STRING_T(o, t, x, xl) SILC_ASN1_T2(NUMERIC_STRING, o, t, x, xl)
824
825 /****f* silcasn1/SilcASN1API/SILC_ASN1_PRINTABLE_STRING
826  *
827  * SYNOPSIS
828  *
829  *    Encoding:
830  *    SILC_ASN1_PRINTABLE_STRING(str, str_len)
831  *    SILC_ASN1_PRINTABLE_STRING_T(opts, tag, str, str_len)
832  *
833  *    Decoding:
834  *    SILC_ASN1_PRINTABLE_STRING(&str, &str_len)
835  *    SILC_ASN1_PRINTABLE_STRING_T(opts, tag, &str, &str_len)
836  *
837  * DESCRIPTION
838  *
839  *    Macro used to encode or decode printable string.  The string type is
840  *    unsigned char and string length SilcUInt32.
841  *
842  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
843  *
844  * NOTES
845  *
846  *    The string must be in UTF-8 encoding when encoding.  The decoded
847  *    string will be in UTF-8 encoding.  The actual data is encoded to
848  *    or decoded from printable.
849  *
850  ***/
851 #define SILC_ASN1_PRINTABLE_STRING(x, xl) SILC_ASN1_U2(PRINTABLE_STRING, x, xl)
852 #define SILC_ASN1_PRINTABLE_STRING_T(o, t, x, xl) SILC_ASN1_T2(PRINTABLE_STRING, o, t, x, xl)
853
854 /****f* silcasn1/SilcASN1API/SILC_ASN1_TELETEX_STRING
855  *
856  * SYNOPSIS
857  *
858  *    Encoding:
859  *    SILC_ASN1_TELETEX_STRING(str, str_len)
860  *    SILC_ASN1_TELETEX_STRING_T(opts, tag, str, str_len)
861  *
862  *    Decoding:
863  *    SILC_ASN1_TELETEX_STRING(&str, &str_len)
864  *    SILC_ASN1_TELETEX_STRING_T(opts, tag, &str, &str_len)
865  *
866  * DESCRIPTION
867  *
868  *    Macro used to encode or decode teletex (T61) string.  The string type is
869  *    unsigned char and string length SilcUInt32.
870  *
871  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
872  *
873  * NOTES
874  *
875  *    The string must be in UTF-8 encoding when encoding.  The decoded
876  *    string will be in UTF-8 encoding.  The actual data is encoded to
877  *    or decoded from teletex (T61).
878  *
879  ***/
880 #define SILC_ASN1_TELETEX_STRING(x, xl) SILC_ASN1_U2(TELETEX_STRING, x, xl)
881 #define SILC_ASN1_TELETEX_STRING_T(o, t, x, xl) SILC_ASN1_T2(TELETEX_STRING, o, t, x, xl)
882
883 /****f* silcasn1/SilcASN1API/SILC_ASN1_IA5_STRING
884  *
885  * SYNOPSIS
886  *
887  *    Encoding:
888  *    SILC_ASN1_IA5_STRING(str, str_len)
889  *    SILC_ASN1_IA5_STRING_T(opts, tag, str, str_len)
890  *
891  *    Decoding:
892  *    SILC_ASN1_IA5_STRING(&str, &str_len)
893  *    SILC_ASN1_IA5_STRING_T(opts, tag, &str, &str_len)
894  *
895  * DESCRIPTION
896  *
897  *    Macro used to encode or decode US ASCII (IA5) string.  The string type
898  *    is unsigned char and string length SilcUInt32.
899  *
900  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
901  *
902  * NOTES
903  *
904  *    The string must be in UTF-8 encoding when encoding.  The decoded
905  *    string will be in UTF-8 encoding.  The actual data is encoded to
906  *    or decoded from US ASCII (IA5).
907  *
908  ***/
909 #define SILC_ASN1_IA5_STRING(x, xl) SILC_ASN1_U2(IA5_STRING, x, xl)
910 #define SILC_ASN1_IA5_STRING_T(o, t, x, xl) SILC_ASN1_T2(IA5_STRING, o, t, x, xl)
911
912 /****f* silcasn1/SilcASN1API/SILC_ASN1_VISIBLE_STRING
913  *
914  * SYNOPSIS
915  *
916  *    Encoding:
917  *    SILC_ASN1_VISIBLE_STRING(str, str_len)
918  *    SILC_ASN1_VISIBLE_STRING_T(opts, tag, str, str_len)
919  *
920  *    Decoding:
921  *    SILC_ASN1_VISIBLE_STRING(&str, &str_len)
922  *    SILC_ASN1_VISIBLE_STRING_T(opts, tag, &str, &str_len)
923  *
924  * DESCRIPTION
925  *
926  *    Macro used to encode or decode visible string.  The string type is
927  *    unsigned char and string length SilcUInt32.
928  *
929  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
930  *
931  * NOTES
932  *
933  *    The string must be in UTF-8 encoding when encoding.  The decoded
934  *    string will be in UTF-8 encoding.  The actual data is encoded to
935  *    or decoded from visible.
936  *
937  ***/
938 #define SILC_ASN1_VISIBLE_STRING(x, xl) SILC_ASN1_U2(VISIBLE_STRING, x, xl)
939 #define SILC_ASN1_VISIBLE_STRING_T(o, t, x, xl) SILC_ASN1_T2(VISIBLE_STRING, o, t, x, xl)
940
941 /****f* silcasn1/SilcASN1API/SILC_ASN1_UNIVERSAL_STRING
942  *
943  * SYNOPSIS
944  *
945  *    Encoding:
946  *    SILC_ASN1_UNIVERSAL_STRING(str, str_len)
947  *    SILC_ASN1_UNIVERSAL_STRING_T(opts, tag, str, str_len)
948  *
949  *    Decoding:
950  *    SILC_ASN1_UNIVERSAL_STRING(&str, &str_len)
951  *    SILC_ASN1_UNIVERSAL_STRING_T(opts, tag, &str, &str_len)
952  *
953  * DESCRIPTION
954  *
955  *    Macro used to encode or decode universal (UCS-4) string.  The string
956  *    type is unsigned char and string length SilcUInt32.
957  *
958  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
959  *
960  * NOTES
961  *
962  *    The string must be in UTF-8 encoding when encoding.  The decoded
963  *    string will be in UTF-8 encoding.  The actual data is encoded to
964  *    or decoded from universal (UCS-4).
965  *
966  ***/
967 #define SILC_ASN1_UNIVERSAL_STRING(x, xl) SILC_ASN1_U2(UNIVERSAL_STRING, x, xl)
968 #define SILC_ASN1_UNIVERSAL_STRING_T(o, t, x, xl) SILC_ASN1_T2(UNIVERSAL_STRING, o, t, x, xl)
969
970 /****f* silcasn1/SilcASN1API/SILC_ASN1_BMP_STRING
971  *
972  * SYNOPSIS
973  *
974  *    Encoding:
975  *    SILC_ASN1_BMP_STRING(str, str_len)
976  *    SILC_ASN1_BMP_STRING_T(opts, tag, str, str_len)
977  *
978  *    Decoding:
979  *    SILC_ASN1_BMP_STRING(&str, &str_len)
980  *    SILC_ASN1_BMP_STRING_T(opts, tag, &str, &str_len)
981  *
982  * DESCRIPTION
983  *
984  *    Macro used to encode or decode BMP (UCS-2) string.  The string type is
985  *    unsigned char and string length SilcUInt32.
986  *
987  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
988  *
989  * NOTES
990  *
991  *    The string must be in UTF-8 encoding when encoding.  The decoded
992  *    string will be in UTF-8 encoding.  The actual data is encoded to
993  *    or decoded from BMP (UCS-2)
994  *
995  ***/
996 #define SILC_ASN1_BMP_STRING(x, xl) SILC_ASN1_U2(BMP_STRING, x, xl)
997 #define SILC_ASN1_BMP_STRING_T(o, t, x, xl) SILC_ASN1_T2(BMP_STRING, o, t, x, xl)
998
999 /****f* silcasn1/SilcASN1API/SILC_ASN1_UNRESTRICTED_STRING
1000  *
1001  * SYNOPSIS
1002  *
1003  *    Encoding:
1004  *    SILC_ASN1_UNRESTRICTED_STRING(str, str_len)
1005  *    SILC_ASN1_UNRESTRICTED_STRING_T(opts, tag, str, str_len)
1006  *
1007  *    Decoding:
1008  *    SILC_ASN1_UNRESTRICTED_STRING(&str, &str_len)
1009  *    SILC_ASN1_UNRESTRICTED_STRING_T(opts, tag, &str, &str_len)
1010  *
1011  * DESCRIPTION
1012  *
1013  *    Macro used to encode or decode unrestricted string.  The string type is
1014  *    unsigned char and string length SilcUInt32.
1015  *
1016  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
1017  *
1018  * NOTES
1019  *
1020  *    The string must be in UTF-8 encoding when encoding.  The decoded
1021  *    string will be in UTF-8 encoding.  The actual data is encoded to
1022  *    or decoded from unrestricted.  NOTE: this implementation use 8-bit ASCII.
1023  *
1024  ***/
1025 #define SILC_ASN1_UNRESTRICTED_STRING(x, xl) SILC_ASN1_U2(UNRESTRICTED_STRING, x, xl)
1026 #define SILC_ASN1_UNRESTRICTED_STRING_T(o, t, x, xl) SILC_ASN1_T2(UNRESTRICTED_STRING, o, t, x, xl)
1027
1028 /****f* silcasn1/SilcASN1API/SILC_ASN1_GENERAL_STRING
1029  *
1030  * SYNOPSIS
1031  *
1032  *    Encoding:
1033  *    SILC_ASN1_GENERAL_STRING(str, str_len)
1034  *    SILC_ASN1_GENERAL_STRING_T(opts, tag, str, str_len)
1035  *
1036  *    Decoding:
1037  *    SILC_ASN1_GENERAL_STRING(&str, &str_len)
1038  *    SILC_ASN1_GENERAL_STRING_T(opts, tag, &str, &str_len)
1039  *
1040  * DESCRIPTION
1041  *
1042  *    Macro used to encode or decode general string.  The string type is
1043  *    unsigned char and string length SilcUInt32.
1044  *
1045  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
1046  *
1047  * NOTES
1048  *
1049  *    The string must be in UTF-8 encoding when encoding.  The decoded
1050  *    string will be in UTF-8 encoding.  The actual data is encoded to
1051  *    or decoded from general.  NOTE: this implementation use 8-bit ASCII.
1052  *
1053  ***/
1054 #define SILC_ASN1_GENERAL_STRING(x, xl) SILC_ASN1_U2(GENERAL_STRING, x, xl)
1055 #define SILC_ASN1_GENERAL_STRING_T(o, t, x, xl) SILC_ASN1_T2(GENERAL_STRING, o, t, x, xl)
1056
1057 /****f* silcasn1/SilcASN1API/SILC_ASN1_UTC_TIME
1058  *
1059  * SYNOPSIS
1060  *
1061  *    Encoding:
1062  *    SILC_ASN1_UTC_TIME(timeval)
1063  *    SILC_ASN1_UTC_TIME_T(opts, tag, timeval)
1064  *
1065  *    Decoding:
1066  *    SILC_ASN1_UTC_TIME(&str, &timeval)
1067  *    SILC_ASN1_UTC_TIME_T(opts, tag, &timeval)
1068  *
1069  * DESCRIPTION
1070  *
1071  *    Macro used to encode or decode universal (UTC) time value.  The
1072  *    time value type is SilcTime.
1073  *
1074  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
1075  *
1076  ***/
1077 #define SILC_ASN1_UTC_TIME(x) SILC_ASN1_U1(UTC_TIME, x)
1078 #define SILC_ASN1_UTC_TIME_T(o, t, x) SILC_ASN1_T1(UTC_TIME, o, t, x)
1079
1080 /****f* silcasn1/SilcASN1API/SILC_ASN1_GEN_TIME
1081  *
1082  * SYNOPSIS
1083  *
1084  *    Encoding:
1085  *    SILC_ASN1_GEN_TIME(timeval)
1086  *    SILC_ASN1_GEN_TIME_T(opts, tag, timeval)
1087  *
1088  *    Decoding:
1089  *    SILC_ASN1_GEN_TIME(&str, &timeval)
1090  *    SILC_ASN1_GEN_TIME_T(opts, tag, &timeval)
1091  *
1092  * DESCRIPTION
1093  *
1094  *    Macro used to encode or decode generalized time value.  The
1095  *    time value type is SilcTime.
1096  *
1097  *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
1098  *
1099  ***/
1100 #define SILC_ASN1_GEN_TIME(x) SILC_ASN1_U1(GENERALIZED_TIME, x)
1101 #define SILC_ASN1_GEN_TIME_T(o, t, x) SILC_ASN1_T1(GENERALIZED_TIME, o, t, x)
1102
1103 /****f* silcasn1/SilcASN1API/SILC_ASN1_END
1104  *
1105  * SYNOPSIS
1106  *
1107  *    SILC_ASN1_END
1108  *
1109  * DESCRIPTION
1110  *
1111  *    The SILC_ASN1_END is used to terminate the variable argument list in
1112  *    silc_asn1_encode and silc_asn1_decode functions.  It is also used to
1113  *    terminate SILC_ASN1_SEQUENCE, SILC_ASN1_SEQUENCE_T, SILC_ASN1_SET,
1114  *    SILC_ASN1_SET_T, SILC_ASN1_SEQUENCE_OF, SILC_ASN1_SET_OF and
1115  *    SILC_ASN1_CHOICE macros.
1116  *
1117  ***/
1118 #define SILC_ASN1_END 0
1119
1120 #endif /* SILCASN1_H */