Initial code commit for Toolkit 1.1.
[silc.git] / lib / silcasn1 / silcasn1_i.h
1 /*
2
3   silcasn1_i.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 #ifndef SILCASN1_I_H
21 #define SILCASN1_I_H
22
23 #ifndef SILCASN1_H
24 #error "Do not include this header directly"
25 #endif
26
27 /* ASN.1 context */
28 struct SilcAsn1Object {
29   va_list ap;                   /* List of ASN.1 types given as argument */
30   SilcStack stack1;             /* Stack for encoder */
31   SilcStack stack2;             /* Internal stack for encoding/decoding */
32   unsigned int accumul  : 1;    /* Accumulate memory from stack for result */
33 };
34
35 /* The maximum depth for recursion in encoder and decoder. */
36 #define SILC_ASN1_RECURSION_DEPTH 512
37
38 /* Implementation specific special tags.  Range is 0x7000 - 0x7fff. */
39 #define SILC_ASN1_TAG_ANY          0x7000   /* SILC_ASN1_ANY given  */
40 #define SILC_ASN1_TAG_FUNC         0x7001   /* Callback encoder/decoder */
41 #define SILC_ASN1_TAG_OPTS         0x7002   /* SILC_ASN1_OPTS given */
42 #define SILC_ASN1_TAG_CHOICE       0x7003   /* SILC_ASN1_CHOICE given */
43 #define SILC_ASN1_TAG_SEQUENCE_OF  0x7004   /* SILC_ASN1_SEQUENCE_OF given */
44
45 /* Helper macros for adding the arguments to encoder and decoder. */
46
47 /* The arguments to silc_asn1_encode and silc_asn1_decode are constructed
48    as follows:
49
50    The first argument for type is a 32 bit integer where first 15-bits are
51    reserved for the type.  If the bit 16 is set then type and tag are same
52    and next argument is NOT the tag number.  If bit 16 is not set then
53    next argument is a 32 bit tag number.  This then also means that the type
54    is either implicitly or explicitly tagged.  The second 16-bits of the
55    first 32-bits argument is reserved for options.
56
57    Any argument that follow the type and optional tag number argument are
58    type specific arguments.
59
60    The SILC_ASN1_Ux macros set the bit 16, since the type and tag are same,
61    and also options are set to zero (0).
62
63    The SILC_ASN1_Tx macros does not set bit 16, but separate tag argument is
64    provided.  Options may or may not be zero, and they are put at the high
65    16-bits part of the first 32-bit argument.
66 */
67
68 #define SILC_ASN1_U0(type) \
69   SILC_ASN1_TAG_ ## type | 0x8000
70 #define SILC_ASN1_U1(type, x) \
71   SILC_ASN1_TAG_ ## type | 0x8000, (x)
72 #define SILC_ASN1_U2(type, x, xl) \
73   SILC_ASN1_TAG_ ## type | 0x8000, (x), (xl)
74
75 #define SILC_ASN1_T0(type, o, t) \
76   SILC_ASN1_TAG_ ## type | (o) << 16, (t)
77 #define SILC_ASN1_T1(type, o, t, x) \
78   SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x)
79 #define SILC_ASN1_T2(type, o, t, x, xl) \
80   SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x), (xl)
81
82 /* Macro to retreive type, options and tag.  The ret_type will include
83    the actual type, ret_class the BER class from options, ret_opts the
84    options (without the class), and ret_tag the tag. */
85 #define SILC_ASN1_ARGS(asn1, ret_type, ret_tag, ret_class, ret_opts)    \
86   ret_type = va_arg(asn1->ap, SilcUInt32);                              \
87   ret_tag = ret_class = ret_opts = 0;                                   \
88   if (ret_type != SILC_ASN1_END &&                                      \
89       ret_type != SILC_ASN1_TAG_OPTS) {                                 \
90     if (ret_type & 0x8000)                                              \
91       ret_tag = (ret_type & 0xffff) & ~0x8000;                          \
92     else                                                                \
93       ret_tag = va_arg(asn1->ap, SilcUInt32);                           \
94     ret_class = ret_type >> 16 & 0xf;                                   \
95     ret_opts = ret_type >> 16 & ~0xf;                                   \
96     if (ret_class)                                                      \
97       ret_class--;                                                      \
98     ret_type = (ret_type & 0xffff) & ~0x8000;                           \
99   }
100
101 #ifdef SILC_DIST_INPLACE
102 /* Internal functions */
103
104 /* Returns string representation of a tag */
105 const char *silc_asn1_tag_name(SilcAsn1Tag tag);
106
107 /* Dumps the ASN.1 data block into standard output (stdout). */
108 bool silc_asn1_dump(SilcAsn1 asn1, SilcBuffer src);
109 #endif /* SILC_DIST_INPLACE */
110
111 #endif /* SILCASN1_I_H */