* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
# include <openssl/e_os2.h>
# include <openssl/asn1.h>
# ifdef OPENSSL_BUILD_SHLIBCRYPTO
# define OPENSSL_EXTERN OPENSSL_EXPORT
/* ASN1 template defines, structures and functions */
# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
/* Macros for start and end of ASN1_ITEM definition */
# define ASN1_ITEM_start(itname) \
const ASN1_ITEM itname##_it = {
# define static_ASN1_ITEM_start(itname) \
static const ASN1_ITEM itname##_it = {
# define ASN1_ITEM_end(itname) \
/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)()))
/* Macros for start and end of ASN1_ITEM definition */
# define ASN1_ITEM_start(itname) \
const ASN1_ITEM * itname##_it(void) \
static const ASN1_ITEM local_it = {
# define static_ASN1_ITEM_start(itname) \
static ASN1_ITEM_start(itname)
# define ASN1_ITEM_end(itname) \
/* Macros to aid ASN1 template writing */
# define ASN1_ITEM_TEMPLATE(tname) \
static const ASN1_TEMPLATE tname##_item_tt
# define ASN1_ITEM_TEMPLATE_END(tname) \
# define static_ASN1_ITEM_TEMPLATE_END(tname) \
static_ASN1_ITEM_start(tname) \
/* This is a ASN1 type which just embeds a template */
* This pair helps declare a SEQUENCE. We can do:
* ASN1_SEQUENCE(stname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END(stname)
* This will produce an ASN1_ITEM called stname_it
* for a structure called stname.
* If you want the same structure but a different
* ASN1_SEQUENCE(itname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END_name(stname, itname)
* This will create an item called itname_it using
* a structure called stname.
# define ASN1_SEQUENCE(tname) \
static const ASN1_TEMPLATE tname##_seq_tt[]
# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname)
# define ASN1_SEQUENCE_END_name(stname, tname) \
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define static_ASN1_SEQUENCE_END_name(stname, tname) \
static_ASN1_ITEM_start(tname) \
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define ASN1_NDEF_SEQUENCE(tname) \
# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
ASN1_SEQUENCE_cb(tname, cb)
# define ASN1_SEQUENCE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
# define ASN1_BROKEN_SEQUENCE(tname) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
# define ASN1_SEQUENCE_ref(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \
# define ASN1_SEQUENCE_enc(tname, enc, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
# define ASN1_NDEF_SEQUENCE_END(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define static_ASN1_NDEF_SEQUENCE_END(tname) \
static_ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
# define static_ASN1_BROKEN_SEQUENCE_END(stname) \
static_ASN1_SEQUENCE_END_ref(stname, stname)
# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname)
# define ASN1_SEQUENCE_END_ref(stname, tname) \
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define static_ASN1_SEQUENCE_END_ref(stname, tname) \
static_ASN1_ITEM_start(tname) \
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
* This pair helps declare a CHOICE type. We can do:
* ASN1_CHOICE(chname) = {
* ASN1_CHOICE_END(chname)
* This will produce an ASN1_ITEM called chname_it
* for a structure called chname. The structure
* definition must look like this:
* the name of the selector must be 'type'.
* to use an alternative selector name use the
* ASN1_CHOICE_END_selector() version.
# define ASN1_CHOICE(tname) \
static const ASN1_TEMPLATE tname##_ch_tt[]
# define ASN1_CHOICE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname)
# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type)
# define ASN1_CHOICE_END_selector(stname, tname, selname) \
offsetof(stname,selname) ,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \
static_ASN1_ITEM_start(tname) \
offsetof(stname,selname) ,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
# define ASN1_CHOICE_END_cb(stname, tname, selname) \
offsetof(stname,selname) ,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
/* This helps with the template wrapper form of ASN1_ITEM */
# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
#name, ASN1_ITEM_ref(type) }
/* These help with SEQUENCE or CHOICE components */
/* used to declare other types */
# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
(flags), (tag), offsetof(stname, field),\
#field, ASN1_ITEM_ref(type) }
/* implicit and explicit helper macros */
# define ASN1_IMP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type)
# define ASN1_EXP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type)
/* Any defined by macros: the field used is in the table itself */
# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
/* Embedded simple type */
# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type)
/* OPTIONAL simple type */
# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type)
/* IMPLICIT tagged simple type */
# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED)
/* IMPLICIT tagged OPTIONAL simple type */
# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED)
/* Same as above but EXPLICIT */
# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED)
# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED)
# define ASN1_SEQUENCE_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
/* OPTIONAL SEQUENCE OF */
# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Same as above but for SET OF */
# define ASN1_SET_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
# define ASN1_SET_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
# define ASN1_IMP_SET_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
# define ASN1_EXP_SET_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
/* EXPLICIT using indefinite length constructed form */
# define ASN1_NDEF_EXP(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
/* EXPLICIT OPTIONAL using indefinite length constructed form */
# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
/* Macros for the ASN1_ADB structure */
# define ASN1_ADB(name) \
static const ASN1_ADB_TABLE name##_adbtbl[]
# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
static const ASN1_ADB name##_adb = {\
sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
static const ASN1_ITEM *name##_adb(void) \
static const ASN1_ADB internal_adb = \
sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
return (const ASN1_ITEM *) &internal_adb; \
void dummy_function(void)
# define ADB_ENTRY(val, template) {val, template}
# define ASN1_ADB_TEMPLATE(name) \
static const ASN1_TEMPLATE name##_tt
* This is the ASN1 template structure that defines a wrapper round the
* actual type. It determines the actual position of the field in the value
* structure, various flags such as OPTIONAL and the field name.
struct ASN1_TEMPLATE_st {
unsigned long flags; /* Various flags */
long tag; /* tag, not used if no tagging */
unsigned long offset; /* Offset of this field in structure */
const char *field_name; /* Field name */
ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */
/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
# define ASN1_TEMPLATE_item(t) (t->item_ptr)
# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
typedef struct ASN1_ADB_st ASN1_ADB;
unsigned long flags; /* Various flags */
unsigned long offset; /* Offset of selector field */
int (*adb_cb)(long *psel); /* Application callback */
const ASN1_ADB_TABLE *tbl; /* Table of possible types */
long tblcount; /* Number of entries in tbl */
const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
struct ASN1_ADB_TABLE_st {
long value; /* NID for an object or value for an int */
const ASN1_TEMPLATE tt; /* item for this value */