--- /dev/null
+/* asn1t.h */\r
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL\r
+ * project 2000.\r
+ */\r
+/* ====================================================================\r
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer. \r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in\r
+ * the documentation and/or other materials provided with the\r
+ * distribution.\r
+ *\r
+ * 3. All advertising materials mentioning features or use of this\r
+ * software must display the following acknowledgment:\r
+ * "This product includes software developed by the OpenSSL Project\r
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"\r
+ *\r
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to\r
+ * endorse or promote products derived from this software without\r
+ * prior written permission. For written permission, please contact\r
+ * licensing@OpenSSL.org.\r
+ *\r
+ * 5. Products derived from this software may not be called "OpenSSL"\r
+ * nor may "OpenSSL" appear in their names without prior written\r
+ * permission of the OpenSSL Project.\r
+ *\r
+ * 6. Redistributions of any form whatsoever must retain the following\r
+ * acknowledgment:\r
+ * "This product includes software developed by the OpenSSL Project\r
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\r
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\r
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * ====================================================================\r
+ *\r
+ * This product includes cryptographic software written by Eric Young\r
+ * (eay@cryptsoft.com). This product includes software written by Tim\r
+ * Hudson (tjh@cryptsoft.com).\r
+ *\r
+ */\r
+#ifndef HEADER_ASN1T_H\r
+#define HEADER_ASN1T_H\r
+\r
+#include <stddef.h>\r
+#include <openssl/e_os2.h>\r
+#include <openssl/asn1.h>\r
+\r
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO\r
+# undef OPENSSL_EXTERN\r
+# define OPENSSL_EXTERN OPENSSL_EXPORT\r
+#endif\r
+\r
+/* ASN1 template defines, structures and functions */\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION\r
+\r
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */\r
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))\r
+\r
+\r
+/* Macros for start and end of ASN1_ITEM definition */\r
+\r
+#define ASN1_ITEM_start(itname) \\r
+ OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {\r
+\r
+#define ASN1_ITEM_end(itname) \\r
+ };\r
+\r
+#else\r
+\r
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */\r
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))\r
+\r
+\r
+/* Macros for start and end of ASN1_ITEM definition */\r
+\r
+#define ASN1_ITEM_start(itname) \\r
+ const ASN1_ITEM * itname##_it(void) \\r
+ { \\r
+ static const ASN1_ITEM local_it = { \\r
+\r
+#define ASN1_ITEM_end(itname) \\r
+ }; \\r
+ return &local_it; \\r
+ }\r
+\r
+#endif\r
+\r
+\r
+/* Macros to aid ASN1 template writing */\r
+\r
+#define ASN1_ITEM_TEMPLATE(tname) \\r
+ static const ASN1_TEMPLATE tname##_item_tt \r
+\r
+#define ASN1_ITEM_TEMPLATE_END(tname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_PRIMITIVE,\\r
+ -1,\\r
+ &tname##_item_tt,\\r
+ 0,\\r
+ NULL,\\r
+ 0,\\r
+ #tname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+\r
+/* This is a ASN1 type which just embeds a template */\r
+ \r
+/* This pair helps declare a SEQUENCE. We can do:\r
+ *\r
+ * ASN1_SEQUENCE(stname) = {\r
+ * ... SEQUENCE components ...\r
+ * } ASN1_SEQUENCE_END(stname)\r
+ *\r
+ * This will produce an ASN1_ITEM called stname_it\r
+ * for a structure called stname.\r
+ *\r
+ * If you want the same structure but a different\r
+ * name then use:\r
+ *\r
+ * ASN1_SEQUENCE(itname) = {\r
+ * ... SEQUENCE components ...\r
+ * } ASN1_SEQUENCE_END_name(stname, itname)\r
+ *\r
+ * This will create an item called itname_it using\r
+ * a structure called stname.\r
+ */\r
+\r
+#define ASN1_SEQUENCE(tname) \\r
+ static const ASN1_TEMPLATE tname##_seq_tt[] \r
+\r
+#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)\r
+\r
+#define ASN1_SEQUENCE_END_name(stname, tname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_SEQUENCE,\\r
+ V_ASN1_SEQUENCE,\\r
+ tname##_seq_tt,\\r
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\\r
+ NULL,\\r
+ sizeof(stname),\\r
+ #stname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+#define ASN1_NDEF_SEQUENCE(tname) \\r
+ ASN1_SEQUENCE(tname)\r
+\r
+#define ASN1_SEQUENCE_cb(tname, cb) \\r
+ static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \\r
+ ASN1_SEQUENCE(tname)\r
+\r
+#define ASN1_BROKEN_SEQUENCE(tname) \\r
+ static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \\r
+ ASN1_SEQUENCE(tname)\r
+\r
+#define ASN1_SEQUENCE_ref(tname, cb, lck) \\r
+ static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \\r
+ ASN1_SEQUENCE(tname)\r
+\r
+#define ASN1_SEQUENCE_enc(tname, enc, cb) \\r
+ static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \\r
+ ASN1_SEQUENCE(tname)\r
+\r
+#define ASN1_NDEF_SEQUENCE_END(tname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_NDEF_SEQUENCE,\\r
+ V_ASN1_SEQUENCE,\\r
+ tname##_seq_tt,\\r
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\\r
+ NULL,\\r
+ sizeof(tname),\\r
+ #tname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)\r
+\r
+#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)\r
+\r
+#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)\r
+\r
+#define ASN1_SEQUENCE_END_ref(stname, tname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_SEQUENCE,\\r
+ V_ASN1_SEQUENCE,\\r
+ tname##_seq_tt,\\r
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\\r
+ &tname##_aux,\\r
+ sizeof(stname),\\r
+ #stname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+\r
+/* This pair helps declare a CHOICE type. We can do:\r
+ *\r
+ * ASN1_CHOICE(chname) = {\r
+ * ... CHOICE options ...\r
+ * ASN1_CHOICE_END(chname)\r
+ *\r
+ * This will produce an ASN1_ITEM called chname_it\r
+ * for a structure called chname. The structure\r
+ * definition must look like this:\r
+ * typedef struct {\r
+ * int type;\r
+ * union {\r
+ * ASN1_SOMETHING *opt1;\r
+ * ASN1_SOMEOTHER *opt2;\r
+ * } value;\r
+ * } chname;\r
+ * \r
+ * the name of the selector must be 'type'.\r
+ * to use an alternative selector name use the\r
+ * ASN1_CHOICE_END_selector() version.\r
+ */\r
+\r
+#define ASN1_CHOICE(tname) \\r
+ static const ASN1_TEMPLATE tname##_ch_tt[] \r
+\r
+#define ASN1_CHOICE_cb(tname, cb) \\r
+ static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \\r
+ ASN1_CHOICE(tname)\r
+\r
+#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)\r
+\r
+#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)\r
+\r
+#define ASN1_CHOICE_END_selector(stname, tname, selname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_CHOICE,\\r
+ offsetof(stname,selname) ,\\r
+ tname##_ch_tt,\\r
+ sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\\r
+ NULL,\\r
+ sizeof(stname),\\r
+ #stname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+#define ASN1_CHOICE_END_cb(stname, tname, selname) \\r
+ ;\\r
+ ASN1_ITEM_start(tname) \\r
+ ASN1_ITYPE_CHOICE,\\r
+ offsetof(stname,selname) ,\\r
+ tname##_ch_tt,\\r
+ sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\\r
+ &tname##_aux,\\r
+ sizeof(stname),\\r
+ #stname \\r
+ ASN1_ITEM_end(tname)\r
+\r
+/* This helps with the template wrapper form of ASN1_ITEM */\r
+\r
+#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \\r
+ (flags), (tag), 0,\\r
+ #name, ASN1_ITEM_ref(type) }\r
+\r
+/* These help with SEQUENCE or CHOICE components */\r
+\r
+/* used to declare other types */\r
+\r
+#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \\r
+ (flags), (tag), offsetof(stname, field),\\r
+ #field, ASN1_ITEM_ref(type) }\r
+\r
+/* used when the structure is combined with the parent */\r
+\r
+#define ASN1_EX_COMBINE(flags, tag, type) { \\r
+ (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }\r
+\r
+/* implicit and explicit helper macros */\r
+\r
+#define ASN1_IMP_EX(stname, field, type, tag, ex) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)\r
+\r
+#define ASN1_EXP_EX(stname, field, type, tag, ex) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)\r
+\r
+/* Any defined by macros: the field used is in the table itself */\r
+\r
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION\r
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }\r
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }\r
+#else\r
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }\r
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }\r
+#endif\r
+/* Plain simple type */\r
+#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)\r
+\r
+/* OPTIONAL simple type */\r
+#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)\r
+\r
+/* IMPLICIT tagged simple type */\r
+#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)\r
+\r
+/* IMPLICIT tagged OPTIONAL simple type */\r
+#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)\r
+\r
+/* Same as above but EXPLICIT */\r
+\r
+#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)\r
+#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)\r
+\r
+/* SEQUENCE OF type */\r
+#define ASN1_SEQUENCE_OF(stname, field, type) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)\r
+\r
+/* OPTIONAL SEQUENCE OF */\r
+#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)\r
+\r
+/* Same as above but for SET OF */\r
+\r
+#define ASN1_SET_OF(stname, field, type) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)\r
+\r
+#define ASN1_SET_OF_OPT(stname, field, type) \\r
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)\r
+\r
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */\r
+\r
+#define ASN1_IMP_SET_OF(stname, field, type, tag) \\r
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)\r
+\r
+#define ASN1_EXP_SET_OF(stname, field, type, tag) \\r
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)\r
+\r
+#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \\r
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)\r
+\r
+#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \\r
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)\r
+\r
+#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \\r
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)\r
+\r
+#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \\r
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)\r
+\r
+#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \\r
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)\r
+\r
+#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \\r
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)\r
+\r
+/* EXPLICIT OPTIONAL using indefinite length constructed form */\r
+#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \\r
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)\r
+\r
+/* Macros for the ASN1_ADB structure */\r
+\r
+#define ASN1_ADB(name) \\r
+ static const ASN1_ADB_TABLE name##_adbtbl[] \r
+\r
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION\r
+\r
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \\r
+ ;\\r
+ static const ASN1_ADB name##_adb = {\\r
+ flags,\\r
+ offsetof(name, field),\\r
+ app_table,\\r
+ name##_adbtbl,\\r
+ sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\\r
+ def,\\r
+ none\\r
+ }\r
+\r
+#else\r
+\r
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \\r
+ ;\\r
+ static const ASN1_ITEM *name##_adb(void) \\r
+ { \\r
+ static const ASN1_ADB internal_adb = \\r
+ {\\r
+ flags,\\r
+ offsetof(name, field),\\r
+ app_table,\\r
+ name##_adbtbl,\\r
+ sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\\r
+ def,\\r
+ none\\r
+ }; \\r
+ return (const ASN1_ITEM *) &internal_adb; \\r
+ } \\r
+ void dummy_function(void)\r
+\r
+#endif\r
+\r
+#define ADB_ENTRY(val, template) {val, template}\r
+\r
+#define ASN1_ADB_TEMPLATE(name) \\r
+ static const ASN1_TEMPLATE name##_tt \r
+\r
+/* This is the ASN1 template structure that defines\r
+ * a wrapper round the actual type. It determines the\r
+ * actual position of the field in the value structure,\r
+ * various flags such as OPTIONAL and the field name.\r
+ */\r
+\r
+struct ASN1_TEMPLATE_st {\r
+unsigned long flags; /* Various flags */\r
+long tag; /* tag, not used if no tagging */\r
+unsigned long offset; /* Offset of this field in structure */\r
+#ifndef NO_ASN1_FIELD_NAMES\r
+const char *field_name; /* Field name */\r
+#endif\r
+ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */\r
+};\r
+\r
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */\r
+\r
+#define ASN1_TEMPLATE_item(t) (t->item_ptr)\r
+#define ASN1_TEMPLATE_adb(t) (t->item_ptr)\r
+\r
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;\r
+typedef struct ASN1_ADB_st ASN1_ADB;\r
+\r
+struct ASN1_ADB_st {\r
+ unsigned long flags; /* Various flags */\r
+ unsigned long offset; /* Offset of selector field */\r
+ STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */\r
+ const ASN1_ADB_TABLE *tbl; /* Table of possible types */\r
+ long tblcount; /* Number of entries in tbl */\r
+ const ASN1_TEMPLATE *default_tt; /* Type to use if no match */\r
+ const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */\r
+};\r
+\r
+struct ASN1_ADB_TABLE_st {\r
+ long value; /* NID for an object or value for an int */\r
+ const ASN1_TEMPLATE tt; /* item for this value */\r
+};\r
+\r
+/* template flags */\r
+\r
+/* Field is optional */\r
+#define ASN1_TFLG_OPTIONAL (0x1)\r
+\r
+/* Field is a SET OF */\r
+#define ASN1_TFLG_SET_OF (0x1 << 1)\r
+\r
+/* Field is a SEQUENCE OF */\r
+#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)\r
+\r
+/* Special case: this refers to a SET OF that\r
+ * will be sorted into DER order when encoded *and*\r
+ * the corresponding STACK will be modified to match\r
+ * the new order.\r
+ */\r
+#define ASN1_TFLG_SET_ORDER (0x3 << 1)\r
+\r
+/* Mask for SET OF or SEQUENCE OF */\r
+#define ASN1_TFLG_SK_MASK (0x3 << 1)\r
+\r
+/* These flags mean the tag should be taken from the\r
+ * tag field. If EXPLICIT then the underlying type\r
+ * is used for the inner tag.\r
+ */\r
+\r
+/* IMPLICIT tagging */\r
+#define ASN1_TFLG_IMPTAG (0x1 << 3)\r
+\r
+\r
+/* EXPLICIT tagging, inner tag from underlying type */\r
+#define ASN1_TFLG_EXPTAG (0x2 << 3)\r
+\r
+#define ASN1_TFLG_TAG_MASK (0x3 << 3)\r
+\r
+/* context specific IMPLICIT */\r
+#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT\r
+\r
+/* context specific EXPLICIT */\r
+#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT\r
+\r
+/* If tagging is in force these determine the\r
+ * type of tag to use. Otherwise the tag is\r
+ * determined by the underlying type. These \r
+ * values reflect the actual octet format.\r
+ */\r
+\r
+/* Universal tag */ \r
+#define ASN1_TFLG_UNIVERSAL (0x0<<6)\r
+/* Application tag */ \r
+#define ASN1_TFLG_APPLICATION (0x1<<6)\r
+/* Context specific tag */ \r
+#define ASN1_TFLG_CONTEXT (0x2<<6)\r
+/* Private tag */ \r
+#define ASN1_TFLG_PRIVATE (0x3<<6)\r
+\r
+#define ASN1_TFLG_TAG_CLASS (0x3<<6)\r
+\r
+/* These are for ANY DEFINED BY type. In this case\r
+ * the 'item' field points to an ASN1_ADB structure\r
+ * which contains a table of values to decode the\r
+ * relevant type\r
+ */\r
+\r
+#define ASN1_TFLG_ADB_MASK (0x3<<8)\r
+\r
+#define ASN1_TFLG_ADB_OID (0x1<<8)\r
+\r
+#define ASN1_TFLG_ADB_INT (0x1<<9)\r
+\r
+/* This flag means a parent structure is passed\r
+ * instead of the field: this is useful is a\r
+ * SEQUENCE is being combined with a CHOICE for\r
+ * example. Since this means the structure and\r
+ * item name will differ we need to use the\r
+ * ASN1_CHOICE_END_name() macro for example.\r
+ */\r
+\r
+#define ASN1_TFLG_COMBINE (0x1<<10)\r
+\r
+/* This flag when present in a SEQUENCE OF, SET OF\r
+ * or EXPLICIT causes indefinite length constructed\r
+ * encoding to be used if required.\r
+ */\r
+\r
+#define ASN1_TFLG_NDEF (0x1<<11)\r
+\r
+/* This is the actual ASN1 item itself */\r
+\r
+struct ASN1_ITEM_st {\r
+char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */\r
+long utype; /* underlying type */\r
+const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */\r
+long tcount; /* Number of templates if SEQUENCE or CHOICE */\r
+const void *funcs; /* functions that handle this type */\r
+long size; /* Structure size (usually)*/\r
+#ifndef NO_ASN1_FIELD_NAMES\r
+const char *sname; /* Structure name */\r
+#endif\r
+};\r
+\r
+/* These are values for the itype field and\r
+ * determine how the type is interpreted.\r
+ *\r
+ * For PRIMITIVE types the underlying type\r
+ * determines the behaviour if items is NULL.\r
+ *\r
+ * Otherwise templates must contain a single \r
+ * template and the type is treated in the\r
+ * same way as the type specified in the template.\r
+ *\r
+ * For SEQUENCE types the templates field points\r
+ * to the members, the size field is the\r
+ * structure size.\r
+ *\r
+ * For CHOICE types the templates field points\r
+ * to each possible member (typically a union)\r
+ * and the 'size' field is the offset of the\r
+ * selector.\r
+ *\r
+ * The 'funcs' field is used for application\r
+ * specific functions. \r
+ *\r
+ * For COMPAT types the funcs field gives a\r
+ * set of functions that handle this type, this\r
+ * supports the old d2i, i2d convention.\r
+ *\r
+ * The EXTERN type uses a new style d2i/i2d.\r
+ * The new style should be used where possible\r
+ * because it avoids things like the d2i IMPLICIT\r
+ * hack.\r
+ *\r
+ * MSTRING is a multiple string type, it is used\r
+ * for a CHOICE of character strings where the\r
+ * actual strings all occupy an ASN1_STRING\r
+ * structure. In this case the 'utype' field\r
+ * has a special meaning, it is used as a mask\r
+ * of acceptable types using the B_ASN1 constants.\r
+ *\r
+ * NDEF_SEQUENCE is the same as SEQUENCE except\r
+ * that it will use indefinite length constructed\r
+ * encoding if requested.\r
+ *\r
+ */\r
+\r
+#define ASN1_ITYPE_PRIMITIVE 0x0\r
+\r
+#define ASN1_ITYPE_SEQUENCE 0x1\r
+\r
+#define ASN1_ITYPE_CHOICE 0x2\r
+\r
+#define ASN1_ITYPE_COMPAT 0x3\r
+\r
+#define ASN1_ITYPE_EXTERN 0x4\r
+\r
+#define ASN1_ITYPE_MSTRING 0x5\r
+\r
+#define ASN1_ITYPE_NDEF_SEQUENCE 0x6\r
+\r
+/* Cache for ASN1 tag and length, so we\r
+ * don't keep re-reading it for things\r
+ * like CHOICE\r
+ */\r
+\r
+struct ASN1_TLC_st{\r
+ char valid; /* Values below are valid */\r
+ int ret; /* return value */\r
+ long plen; /* length */\r
+ int ptag; /* class value */\r
+ int pclass; /* class value */\r
+ int hdrlen; /* header length */\r
+};\r
+\r
+/* Typedefs for ASN1 function pointers */\r
+\r
+typedef ASN1_VALUE * ASN1_new_func(void);\r
+typedef void ASN1_free_func(ASN1_VALUE *a);\r
+typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);\r
+typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);\r
+\r
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,\r
+ int tag, int aclass, char opt, ASN1_TLC *ctx);\r
+\r
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);\r
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+\r
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);\r
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);\r
+\r
+typedef struct ASN1_COMPAT_FUNCS_st {\r
+ ASN1_new_func *asn1_new;\r
+ ASN1_free_func *asn1_free;\r
+ ASN1_d2i_func *asn1_d2i;\r
+ ASN1_i2d_func *asn1_i2d;\r
+} ASN1_COMPAT_FUNCS;\r
+\r
+typedef struct ASN1_EXTERN_FUNCS_st {\r
+ void *app_data;\r
+ ASN1_ex_new_func *asn1_ex_new;\r
+ ASN1_ex_free_func *asn1_ex_free;\r
+ ASN1_ex_free_func *asn1_ex_clear;\r
+ ASN1_ex_d2i *asn1_ex_d2i;\r
+ ASN1_ex_i2d *asn1_ex_i2d;\r
+} ASN1_EXTERN_FUNCS;\r
+\r
+typedef struct ASN1_PRIMITIVE_FUNCS_st {\r
+ void *app_data;\r
+ unsigned long flags;\r
+ ASN1_ex_new_func *prim_new;\r
+ ASN1_ex_free_func *prim_free;\r
+ ASN1_ex_free_func *prim_clear;\r
+ ASN1_primitive_c2i *prim_c2i;\r
+ ASN1_primitive_i2c *prim_i2c;\r
+} ASN1_PRIMITIVE_FUNCS;\r
+\r
+/* This is the ASN1_AUX structure: it handles various\r
+ * miscellaneous requirements. For example the use of\r
+ * reference counts and an informational callback.\r
+ *\r
+ * The "informational callback" is called at various\r
+ * points during the ASN1 encoding and decoding. It can\r
+ * be used to provide minor customisation of the structures\r
+ * used. This is most useful where the supplied routines\r
+ * *almost* do the right thing but need some extra help\r
+ * at a few points. If the callback returns zero then\r
+ * it is assumed a fatal error has occurred and the \r
+ * main operation should be abandoned.\r
+ *\r
+ * If major changes in the default behaviour are required\r
+ * then an external type is more appropriate.\r
+ */\r
+\r
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);\r
+\r
+typedef struct ASN1_AUX_st {\r
+ void *app_data;\r
+ int flags;\r
+ int ref_offset; /* Offset of reference value */\r
+ int ref_lock; /* Lock type to use */\r
+ ASN1_aux_cb *asn1_cb;\r
+ int enc_offset; /* Offset of ASN1_ENCODING structure */\r
+} ASN1_AUX;\r
+\r
+/* Flags in ASN1_AUX */\r
+\r
+/* Use a reference count */\r
+#define ASN1_AFLG_REFCOUNT 1\r
+/* Save the encoding of structure (useful for signatures) */\r
+#define ASN1_AFLG_ENCODING 2\r
+/* The Sequence length is invalid */\r
+#define ASN1_AFLG_BROKEN 4\r
+\r
+/* operation values for asn1_cb */\r
+\r
+#define ASN1_OP_NEW_PRE 0\r
+#define ASN1_OP_NEW_POST 1\r
+#define ASN1_OP_FREE_PRE 2\r
+#define ASN1_OP_FREE_POST 3\r
+#define ASN1_OP_D2I_PRE 4\r
+#define ASN1_OP_D2I_POST 5\r
+#define ASN1_OP_I2D_PRE 6\r
+#define ASN1_OP_I2D_POST 7\r
+\r
+/* Macro to implement a primitive type */\r
+#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)\r
+#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \\r
+ ASN1_ITEM_start(itname) \\r
+ ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \\r
+ ASN1_ITEM_end(itname)\r
+\r
+/* Macro to implement a multi string type */\r
+#define IMPLEMENT_ASN1_MSTRING(itname, mask) \\r
+ ASN1_ITEM_start(itname) \\r
+ ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \\r
+ ASN1_ITEM_end(itname)\r
+\r
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */\r
+\r
+#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)\r
+\r
+#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \\r
+ static const ASN1_COMPAT_FUNCS sname##_ff = { \\r
+ (ASN1_new_func *)sname##_new, \\r
+ (ASN1_free_func *)sname##_free, \\r
+ (ASN1_d2i_func *)d2i_##sname, \\r
+ (ASN1_i2d_func *)i2d_##sname, \\r
+ }; \\r
+ ASN1_ITEM_start(sname) \\r
+ ASN1_ITYPE_COMPAT, \\r
+ tag, \\r
+ NULL, \\r
+ 0, \\r
+ &sname##_ff, \\r
+ 0, \\r
+ #sname \\r
+ ASN1_ITEM_end(sname)\r
+\r
+#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \\r
+ ASN1_ITEM_start(sname) \\r
+ ASN1_ITYPE_EXTERN, \\r
+ tag, \\r
+ NULL, \\r
+ 0, \\r
+ &fptrs, \\r
+ 0, \\r
+ #sname \\r
+ ASN1_ITEM_end(sname)\r
+\r
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \\r
+ IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)\r
+\r
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \\r
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)\r
+\r
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \\r
+ stname *fname##_new(void) \\r
+ { \\r
+ return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \\r
+ } \\r
+ void fname##_free(stname *a) \\r
+ { \\r
+ ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \\r
+ }\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \\r
+ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \\r
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)\r
+\r
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \\r
+ stname *d2i_##fname(stname **a, const unsigned char **in, long len) \\r
+ { \\r
+ return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\\r
+ } \\r
+ int i2d_##fname(stname *a, unsigned char **out) \\r
+ { \\r
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\\r
+ } \r
+\r
+#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \\r
+ int i2d_##stname##_NDEF(stname *a, unsigned char **out) \\r
+ { \\r
+ return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\\r
+ } \r
+\r
+/* This includes evil casts to remove const: they will go away when full\r
+ * ASN1 constification is done.\r
+ */\r
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \\r
+ stname *d2i_##fname(stname **a, const unsigned char **in, long len) \\r
+ { \\r
+ return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\\r
+ } \\r
+ int i2d_##fname(const stname *a, unsigned char **out) \\r
+ { \\r
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\\r
+ } \r
+\r
+#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \\r
+ stname * stname##_dup(stname *x) \\r
+ { \\r
+ return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \\r
+ }\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \\r
+ IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)\r
+\r
+#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \\r
+ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \\r
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)\r
+\r
+/* external definitions for primitive types */\r
+\r
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)\r
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)\r
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)\r
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)\r
+DECLARE_ASN1_ITEM(CBIGNUM)\r
+DECLARE_ASN1_ITEM(BIGNUM)\r
+DECLARE_ASN1_ITEM(LONG)\r
+DECLARE_ASN1_ITEM(ZLONG)\r
+\r
+DECLARE_STACK_OF(ASN1_VALUE)\r
+\r
+/* Functions used internally by the ASN1 code */\r
+\r
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);\r
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+\r
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);\r
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);\r
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,\r
+ int tag, int aclass, char opt, ASN1_TLC *ctx);\r
+\r
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);\r
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);\r
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+\r
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);\r
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);\r
+\r
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);\r
+\r
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);\r
+\r
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);\r
+\r
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);\r
+\r
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);\r
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif\r