Initial code commit for Toolkit 1.1.
[silc.git] / lib / silcasn1 / silcasn1_i.h
diff --git a/lib/silcasn1/silcasn1_i.h b/lib/silcasn1/silcasn1_i.h
new file mode 100644 (file)
index 0000000..67fb4d0
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+
+  silcasn1_i.h
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2003 - 2005 Pekka Riikonen
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+#ifndef SILCASN1_I_H
+#define SILCASN1_I_H
+
+#ifndef SILCASN1_H
+#error "Do not include this header directly"
+#endif
+
+/* ASN.1 context */
+struct SilcAsn1Object {
+  va_list ap;                  /* List of ASN.1 types given as argument */
+  SilcStack stack1;            /* Stack for encoder */
+  SilcStack stack2;            /* Internal stack for encoding/decoding */
+  unsigned int accumul  : 1;   /* Accumulate memory from stack for result */
+};
+
+/* The maximum depth for recursion in encoder and decoder. */
+#define SILC_ASN1_RECURSION_DEPTH 512
+
+/* Implementation specific special tags.  Range is 0x7000 - 0x7fff. */
+#define SILC_ASN1_TAG_ANY          0x7000   /* SILC_ASN1_ANY given  */
+#define SILC_ASN1_TAG_FUNC         0x7001   /* Callback encoder/decoder */
+#define SILC_ASN1_TAG_OPTS         0x7002   /* SILC_ASN1_OPTS given */
+#define SILC_ASN1_TAG_CHOICE       0x7003   /* SILC_ASN1_CHOICE given */
+#define SILC_ASN1_TAG_SEQUENCE_OF  0x7004   /* SILC_ASN1_SEQUENCE_OF given */
+
+/* Helper macros for adding the arguments to encoder and decoder. */
+
+/* The arguments to silc_asn1_encode and silc_asn1_decode are constructed
+   as follows:
+
+   The first argument for type is a 32 bit integer where first 15-bits are
+   reserved for the type.  If the bit 16 is set then type and tag are same
+   and next argument is NOT the tag number.  If bit 16 is not set then
+   next argument is a 32 bit tag number.  This then also means that the type
+   is either implicitly or explicitly tagged.  The second 16-bits of the
+   first 32-bits argument is reserved for options.
+
+   Any argument that follow the type and optional tag number argument are
+   type specific arguments.
+
+   The SILC_ASN1_Ux macros set the bit 16, since the type and tag are same,
+   and also options are set to zero (0).
+
+   The SILC_ASN1_Tx macros does not set bit 16, but separate tag argument is
+   provided.  Options may or may not be zero, and they are put at the high
+   16-bits part of the first 32-bit argument.
+*/
+
+#define SILC_ASN1_U0(type) \
+  SILC_ASN1_TAG_ ## type | 0x8000
+#define SILC_ASN1_U1(type, x) \
+  SILC_ASN1_TAG_ ## type | 0x8000, (x)
+#define SILC_ASN1_U2(type, x, xl) \
+  SILC_ASN1_TAG_ ## type | 0x8000, (x), (xl)
+
+#define SILC_ASN1_T0(type, o, t) \
+  SILC_ASN1_TAG_ ## type | (o) << 16, (t)
+#define SILC_ASN1_T1(type, o, t, x) \
+  SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x)
+#define SILC_ASN1_T2(type, o, t, x, xl) \
+  SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x), (xl)
+
+/* Macro to retreive type, options and tag.  The ret_type will include
+   the actual type, ret_class the BER class from options, ret_opts the
+   options (without the class), and ret_tag the tag. */
+#define SILC_ASN1_ARGS(asn1, ret_type, ret_tag, ret_class, ret_opts)   \
+  ret_type = va_arg(asn1->ap, SilcUInt32);                             \
+  ret_tag = ret_class = ret_opts = 0;                                  \
+  if (ret_type != SILC_ASN1_END &&                                     \
+      ret_type != SILC_ASN1_TAG_OPTS) {                                        \
+    if (ret_type & 0x8000)                                             \
+      ret_tag = (ret_type & 0xffff) & ~0x8000;                         \
+    else                                                               \
+      ret_tag = va_arg(asn1->ap, SilcUInt32);                          \
+    ret_class = ret_type >> 16 & 0xf;                                  \
+    ret_opts = ret_type >> 16 & ~0xf;                                  \
+    if (ret_class)                                                     \
+      ret_class--;                                                     \
+    ret_type = (ret_type & 0xffff) & ~0x8000;                          \
+  }
+
+#ifdef SILC_DIST_INPLACE
+/* Internal functions */
+
+/* Returns string representation of a tag */
+const char *silc_asn1_tag_name(SilcAsn1Tag tag);
+
+/* Dumps the ASN.1 data block into standard output (stdout). */
+bool silc_asn1_dump(SilcAsn1 asn1, SilcBuffer src);
+#endif /* SILC_DIST_INPLACE */
+
+#endif /* SILCASN1_I_H */