1109998Smarkm/* asn1t.h */
2280297Sjkim/*
3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4280297Sjkim * 2000.
5109998Smarkm */
6109998Smarkm/* ====================================================================
7238405Sjkim * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
8109998Smarkm *
9109998Smarkm * Redistribution and use in source and binary forms, with or without
10109998Smarkm * modification, are permitted provided that the following conditions
11109998Smarkm * are met:
12109998Smarkm *
13109998Smarkm * 1. Redistributions of source code must retain the above copyright
14280297Sjkim *    notice, this list of conditions and the following disclaimer.
15109998Smarkm *
16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
17109998Smarkm *    notice, this list of conditions and the following disclaimer in
18109998Smarkm *    the documentation and/or other materials provided with the
19109998Smarkm *    distribution.
20109998Smarkm *
21109998Smarkm * 3. All advertising materials mentioning features or use of this
22109998Smarkm *    software must display the following acknowledgment:
23109998Smarkm *    "This product includes software developed by the OpenSSL Project
24109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25109998Smarkm *
26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27109998Smarkm *    endorse or promote products derived from this software without
28109998Smarkm *    prior written permission. For written permission, please contact
29109998Smarkm *    licensing@OpenSSL.org.
30109998Smarkm *
31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
32109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
33109998Smarkm *    permission of the OpenSSL Project.
34109998Smarkm *
35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
36109998Smarkm *    acknowledgment:
37109998Smarkm *    "This product includes software developed by the OpenSSL Project
38109998Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39109998Smarkm *
40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
52109998Smarkm * ====================================================================
53109998Smarkm *
54109998Smarkm * This product includes cryptographic software written by Eric Young
55109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
56109998Smarkm * Hudson (tjh@cryptsoft.com).
57109998Smarkm *
58109998Smarkm */
59109998Smarkm#ifndef HEADER_ASN1T_H
60280297Sjkim# define HEADER_ASN1T_H
61109998Smarkm
62280297Sjkim# include <stddef.h>
63280297Sjkim# include <openssl/e_os2.h>
64280297Sjkim# include <openssl/asn1.h>
65109998Smarkm
66280297Sjkim# ifdef OPENSSL_BUILD_SHLIBCRYPTO
67280297Sjkim#  undef OPENSSL_EXTERN
68280297Sjkim#  define OPENSSL_EXTERN OPENSSL_EXPORT
69280297Sjkim# endif
70109998Smarkm
71109998Smarkm/* ASN1 template defines, structures and functions */
72109998Smarkm
73109998Smarkm#ifdef  __cplusplus
74109998Smarkmextern "C" {
75109998Smarkm#endif
76109998Smarkm
77280297Sjkim# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
78109998Smarkm
79109998Smarkm/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
80280297Sjkim#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
81109998Smarkm
82109998Smarkm/* Macros for start and end of ASN1_ITEM definition */
83109998Smarkm
84280297Sjkim#  define ASN1_ITEM_start(itname) \
85280297Sjkim        OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
86109998Smarkm
87280297Sjkim#  define ASN1_ITEM_end(itname) \
88280297Sjkim                };
89109998Smarkm
90280297Sjkim# else
91109998Smarkm
92109998Smarkm/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
93280297Sjkim#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
94109998Smarkm
95109998Smarkm/* Macros for start and end of ASN1_ITEM definition */
96109998Smarkm
97280297Sjkim#  define ASN1_ITEM_start(itname) \
98280297Sjkim        const ASN1_ITEM * itname##_it(void) \
99280297Sjkim        { \
100280297Sjkim                static const ASN1_ITEM local_it = {
101109998Smarkm
102280297Sjkim#  define ASN1_ITEM_end(itname) \
103280297Sjkim                }; \
104280297Sjkim        return &local_it; \
105280297Sjkim        }
106109998Smarkm
107280297Sjkim# endif
108109998Smarkm
109109998Smarkm/* Macros to aid ASN1 template writing */
110109998Smarkm
111280297Sjkim# define ASN1_ITEM_TEMPLATE(tname) \
112280297Sjkim        static const ASN1_TEMPLATE tname##_item_tt
113109998Smarkm
114280297Sjkim# define ASN1_ITEM_TEMPLATE_END(tname) \
115280297Sjkim        ;\
116280297Sjkim        ASN1_ITEM_start(tname) \
117280297Sjkim                ASN1_ITYPE_PRIMITIVE,\
118280297Sjkim                -1,\
119280297Sjkim                &tname##_item_tt,\
120280297Sjkim                0,\
121280297Sjkim                NULL,\
122280297Sjkim                0,\
123280297Sjkim                #tname \
124280297Sjkim        ASN1_ITEM_end(tname)
125109998Smarkm
126280297Sjkim/* This is a ASN1 type which just embeds a template */
127109998Smarkm
128280297Sjkim/*-
129280297Sjkim * This pair helps declare a SEQUENCE. We can do:
130109998Smarkm *
131280297Sjkim *      ASN1_SEQUENCE(stname) = {
132280297Sjkim *              ... SEQUENCE components ...
133280297Sjkim *      } ASN1_SEQUENCE_END(stname)
134109998Smarkm *
135280297Sjkim *      This will produce an ASN1_ITEM called stname_it
136280297Sjkim *      for a structure called stname.
137109998Smarkm *
138280297Sjkim *      If you want the same structure but a different
139280297Sjkim *      name then use:
140109998Smarkm *
141280297Sjkim *      ASN1_SEQUENCE(itname) = {
142280297Sjkim *              ... SEQUENCE components ...
143280297Sjkim *      } ASN1_SEQUENCE_END_name(stname, itname)
144109998Smarkm *
145280297Sjkim *      This will create an item called itname_it using
146280297Sjkim *      a structure called stname.
147109998Smarkm */
148109998Smarkm
149280297Sjkim# define ASN1_SEQUENCE(tname) \
150280297Sjkim        static const ASN1_TEMPLATE tname##_seq_tt[]
151109998Smarkm
152280297Sjkim# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
153109998Smarkm
154280297Sjkim# define ASN1_SEQUENCE_END_name(stname, tname) \
155280297Sjkim        ;\
156280297Sjkim        ASN1_ITEM_start(tname) \
157280297Sjkim                ASN1_ITYPE_SEQUENCE,\
158280297Sjkim                V_ASN1_SEQUENCE,\
159280297Sjkim                tname##_seq_tt,\
160280297Sjkim                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
161280297Sjkim                NULL,\
162280297Sjkim                sizeof(stname),\
163280297Sjkim                #stname \
164280297Sjkim        ASN1_ITEM_end(tname)
165109998Smarkm
166280297Sjkim# define ASN1_NDEF_SEQUENCE(tname) \
167280297Sjkim        ASN1_SEQUENCE(tname)
168160814Ssimon
169280297Sjkim# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
170280297Sjkim        ASN1_SEQUENCE_cb(tname, cb)
171194206Ssimon
172280297Sjkim# define ASN1_SEQUENCE_cb(tname, cb) \
173280297Sjkim        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
174280297Sjkim        ASN1_SEQUENCE(tname)
175109998Smarkm
176280297Sjkim# define ASN1_BROKEN_SEQUENCE(tname) \
177280297Sjkim        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
178280297Sjkim        ASN1_SEQUENCE(tname)
179109998Smarkm
180280297Sjkim# define ASN1_SEQUENCE_ref(tname, cb, lck) \
181280297Sjkim        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
182280297Sjkim        ASN1_SEQUENCE(tname)
183109998Smarkm
184280297Sjkim# define ASN1_SEQUENCE_enc(tname, enc, cb) \
185280297Sjkim        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
186280297Sjkim        ASN1_SEQUENCE(tname)
187109998Smarkm
188280297Sjkim# define ASN1_NDEF_SEQUENCE_END(tname) \
189280297Sjkim        ;\
190280297Sjkim        ASN1_ITEM_start(tname) \
191280297Sjkim                ASN1_ITYPE_NDEF_SEQUENCE,\
192280297Sjkim                V_ASN1_SEQUENCE,\
193280297Sjkim                tname##_seq_tt,\
194280297Sjkim                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
195280297Sjkim                NULL,\
196280297Sjkim                sizeof(tname),\
197280297Sjkim                #tname \
198280297Sjkim        ASN1_ITEM_end(tname)
199160814Ssimon
200280297Sjkim# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
201109998Smarkm
202280297Sjkim# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
203109998Smarkm
204280297Sjkim# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
205109998Smarkm
206280297Sjkim# define ASN1_SEQUENCE_END_ref(stname, tname) \
207280297Sjkim        ;\
208280297Sjkim        ASN1_ITEM_start(tname) \
209280297Sjkim                ASN1_ITYPE_SEQUENCE,\
210280297Sjkim                V_ASN1_SEQUENCE,\
211280297Sjkim                tname##_seq_tt,\
212280297Sjkim                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
213280297Sjkim                &tname##_aux,\
214280297Sjkim                sizeof(stname),\
215280297Sjkim                #stname \
216280297Sjkim        ASN1_ITEM_end(tname)
217109998Smarkm
218280297Sjkim# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
219280297Sjkim        ;\
220280297Sjkim        ASN1_ITEM_start(tname) \
221280297Sjkim                ASN1_ITYPE_NDEF_SEQUENCE,\
222280297Sjkim                V_ASN1_SEQUENCE,\
223280297Sjkim                tname##_seq_tt,\
224280297Sjkim                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
225280297Sjkim                &tname##_aux,\
226280297Sjkim                sizeof(stname),\
227280297Sjkim                #stname \
228280297Sjkim        ASN1_ITEM_end(tname)
229109998Smarkm
230280297Sjkim/*-
231280297Sjkim * This pair helps declare a CHOICE type. We can do:
232109998Smarkm *
233280297Sjkim *      ASN1_CHOICE(chname) = {
234280297Sjkim *              ... CHOICE options ...
235280297Sjkim *      ASN1_CHOICE_END(chname)
236109998Smarkm *
237280297Sjkim *      This will produce an ASN1_ITEM called chname_it
238280297Sjkim *      for a structure called chname. The structure
239280297Sjkim *      definition must look like this:
240280297Sjkim *      typedef struct {
241280297Sjkim *              int type;
242280297Sjkim *              union {
243280297Sjkim *                      ASN1_SOMETHING *opt1;
244280297Sjkim *                      ASN1_SOMEOTHER *opt2;
245280297Sjkim *              } value;
246280297Sjkim *      } chname;
247280297Sjkim *
248280297Sjkim *      the name of the selector must be 'type'.
249280297Sjkim *      to use an alternative selector name use the
250109998Smarkm *      ASN1_CHOICE_END_selector() version.
251109998Smarkm */
252109998Smarkm
253280297Sjkim# define ASN1_CHOICE(tname) \
254280297Sjkim        static const ASN1_TEMPLATE tname##_ch_tt[]
255109998Smarkm
256280297Sjkim# define ASN1_CHOICE_cb(tname, cb) \
257280297Sjkim        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
258280297Sjkim        ASN1_CHOICE(tname)
259109998Smarkm
260280297Sjkim# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
261109998Smarkm
262280297Sjkim# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
263109998Smarkm
264280297Sjkim# define ASN1_CHOICE_END_selector(stname, tname, selname) \
265280297Sjkim        ;\
266280297Sjkim        ASN1_ITEM_start(tname) \
267280297Sjkim                ASN1_ITYPE_CHOICE,\
268280297Sjkim                offsetof(stname,selname) ,\
269280297Sjkim                tname##_ch_tt,\
270280297Sjkim                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
271280297Sjkim                NULL,\
272280297Sjkim                sizeof(stname),\
273280297Sjkim                #stname \
274280297Sjkim        ASN1_ITEM_end(tname)
275109998Smarkm
276280297Sjkim# define ASN1_CHOICE_END_cb(stname, tname, selname) \
277280297Sjkim        ;\
278280297Sjkim        ASN1_ITEM_start(tname) \
279280297Sjkim                ASN1_ITYPE_CHOICE,\
280280297Sjkim                offsetof(stname,selname) ,\
281280297Sjkim                tname##_ch_tt,\
282280297Sjkim                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
283280297Sjkim                &tname##_aux,\
284280297Sjkim                sizeof(stname),\
285280297Sjkim                #stname \
286280297Sjkim        ASN1_ITEM_end(tname)
287109998Smarkm
288109998Smarkm/* This helps with the template wrapper form of ASN1_ITEM */
289109998Smarkm
290280297Sjkim# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
291280297Sjkim        (flags), (tag), 0,\
292280297Sjkim        #name, ASN1_ITEM_ref(type) }
293109998Smarkm
294109998Smarkm/* These help with SEQUENCE or CHOICE components */
295109998Smarkm
296109998Smarkm/* used to declare other types */
297109998Smarkm
298280297Sjkim# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
299280297Sjkim        (flags), (tag), offsetof(stname, field),\
300280297Sjkim        #field, ASN1_ITEM_ref(type) }
301109998Smarkm
302109998Smarkm/* used when the structure is combined with the parent */
303109998Smarkm
304280297Sjkim# define ASN1_EX_COMBINE(flags, tag, type) { \
305280297Sjkim        (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
306109998Smarkm
307109998Smarkm/* implicit and explicit helper macros */
308109998Smarkm
309280297Sjkim# define ASN1_IMP_EX(stname, field, type, tag, ex) \
310280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
311109998Smarkm
312280297Sjkim# define ASN1_EXP_EX(stname, field, type, tag, ex) \
313280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
314109998Smarkm
315109998Smarkm/* Any defined by macros: the field used is in the table itself */
316109998Smarkm
317280297Sjkim# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
318280297Sjkim#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
319280297Sjkim#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
320280297Sjkim# else
321280297Sjkim#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
322280297Sjkim#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
323280297Sjkim# endif
324109998Smarkm/* Plain simple type */
325280297Sjkim# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
326109998Smarkm
327109998Smarkm/* OPTIONAL simple type */
328280297Sjkim# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
329109998Smarkm
330109998Smarkm/* IMPLICIT tagged simple type */
331280297Sjkim# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
332109998Smarkm
333109998Smarkm/* IMPLICIT tagged OPTIONAL simple type */
334280297Sjkim# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
335109998Smarkm
336109998Smarkm/* Same as above but EXPLICIT */
337109998Smarkm
338280297Sjkim# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
339280297Sjkim# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
340109998Smarkm
341109998Smarkm/* SEQUENCE OF type */
342280297Sjkim# define ASN1_SEQUENCE_OF(stname, field, type) \
343280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
344109998Smarkm
345109998Smarkm/* OPTIONAL SEQUENCE OF */
346280297Sjkim# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
347280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
348109998Smarkm
349109998Smarkm/* Same as above but for SET OF */
350109998Smarkm
351280297Sjkim# define ASN1_SET_OF(stname, field, type) \
352280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
353109998Smarkm
354280297Sjkim# define ASN1_SET_OF_OPT(stname, field, type) \
355280297Sjkim                ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
356109998Smarkm
357109998Smarkm/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
358109998Smarkm
359280297Sjkim# define ASN1_IMP_SET_OF(stname, field, type, tag) \
360280297Sjkim                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
361109998Smarkm
362280297Sjkim# define ASN1_EXP_SET_OF(stname, field, type, tag) \
363280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
364109998Smarkm
365280297Sjkim# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
366280297Sjkim                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
367109998Smarkm
368280297Sjkim# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
369280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
370109998Smarkm
371280297Sjkim# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
372280297Sjkim                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
373109998Smarkm
374280297Sjkim# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
375280297Sjkim                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
376109998Smarkm
377280297Sjkim# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
378280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
379109998Smarkm
380280297Sjkim# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
381280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
382109998Smarkm
383194206Ssimon/* EXPLICIT using indefinite length constructed form */
384280297Sjkim# define ASN1_NDEF_EXP(stname, field, type, tag) \
385280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
386194206Ssimon
387160814Ssimon/* EXPLICIT OPTIONAL using indefinite length constructed form */
388280297Sjkim# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
389280297Sjkim                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
390160814Ssimon
391109998Smarkm/* Macros for the ASN1_ADB structure */
392109998Smarkm
393280297Sjkim# define ASN1_ADB(name) \
394280297Sjkim        static const ASN1_ADB_TABLE name##_adbtbl[]
395109998Smarkm
396280297Sjkim# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
397109998Smarkm
398280297Sjkim#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
399280297Sjkim        ;\
400280297Sjkim        static const ASN1_ADB name##_adb = {\
401280297Sjkim                flags,\
402280297Sjkim                offsetof(name, field),\
403280297Sjkim                app_table,\
404280297Sjkim                name##_adbtbl,\
405280297Sjkim                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
406280297Sjkim                def,\
407280297Sjkim                none\
408280297Sjkim        }
409109998Smarkm
410280297Sjkim# else
411109998Smarkm
412280297Sjkim#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
413280297Sjkim        ;\
414280297Sjkim        static const ASN1_ITEM *name##_adb(void) \
415280297Sjkim        { \
416280297Sjkim        static const ASN1_ADB internal_adb = \
417280297Sjkim                {\
418280297Sjkim                flags,\
419280297Sjkim                offsetof(name, field),\
420280297Sjkim                app_table,\
421280297Sjkim                name##_adbtbl,\
422280297Sjkim                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
423280297Sjkim                def,\
424280297Sjkim                none\
425280297Sjkim                }; \
426280297Sjkim                return (const ASN1_ITEM *) &internal_adb; \
427280297Sjkim        } \
428280297Sjkim        void dummy_function(void)
429109998Smarkm
430280297Sjkim# endif
431109998Smarkm
432280297Sjkim# define ADB_ENTRY(val, template) {val, template}
433109998Smarkm
434280297Sjkim# define ASN1_ADB_TEMPLATE(name) \
435280297Sjkim        static const ASN1_TEMPLATE name##_tt
436109998Smarkm
437280297Sjkim/*
438280297Sjkim * This is the ASN1 template structure that defines a wrapper round the
439280297Sjkim * actual type. It determines the actual position of the field in the value
440280297Sjkim * structure, various flags such as OPTIONAL and the field name.
441109998Smarkm */
442109998Smarkm
443109998Smarkmstruct ASN1_TEMPLATE_st {
444280297Sjkim    unsigned long flags;        /* Various flags */
445280297Sjkim    long tag;                   /* tag, not used if no tagging */
446280297Sjkim    unsigned long offset;       /* Offset of this field in structure */
447280297Sjkim# ifndef NO_ASN1_FIELD_NAMES
448280297Sjkim    const char *field_name;     /* Field name */
449280297Sjkim# endif
450280297Sjkim    ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
451109998Smarkm};
452109998Smarkm
453109998Smarkm/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
454109998Smarkm
455280297Sjkim# define ASN1_TEMPLATE_item(t) (t->item_ptr)
456280297Sjkim# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
457109998Smarkm
458109998Smarkmtypedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
459109998Smarkmtypedef struct ASN1_ADB_st ASN1_ADB;
460109998Smarkm
461109998Smarkmstruct ASN1_ADB_st {
462280297Sjkim    unsigned long flags;        /* Various flags */
463280297Sjkim    unsigned long offset;       /* Offset of selector field */
464280297Sjkim    STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
465280297Sjkim    const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
466280297Sjkim    long tblcount;              /* Number of entries in tbl */
467280297Sjkim    const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
468280297Sjkim    const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
469109998Smarkm};
470109998Smarkm
471109998Smarkmstruct ASN1_ADB_TABLE_st {
472280297Sjkim    long value;                 /* NID for an object or value for an int */
473280297Sjkim    const ASN1_TEMPLATE tt;     /* item for this value */
474109998Smarkm};
475109998Smarkm
476109998Smarkm/* template flags */
477109998Smarkm
478109998Smarkm/* Field is optional */
479280297Sjkim# define ASN1_TFLG_OPTIONAL      (0x1)
480109998Smarkm
481109998Smarkm/* Field is a SET OF */
482280297Sjkim# define ASN1_TFLG_SET_OF        (0x1 << 1)
483109998Smarkm
484109998Smarkm/* Field is a SEQUENCE OF */
485280297Sjkim# define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)
486109998Smarkm
487280297Sjkim/*
488280297Sjkim * Special case: this refers to a SET OF that will be sorted into DER order
489280297Sjkim * when encoded *and* the corresponding STACK will be modified to match the
490280297Sjkim * new order.
491109998Smarkm */
492280297Sjkim# define ASN1_TFLG_SET_ORDER     (0x3 << 1)
493109998Smarkm
494109998Smarkm/* Mask for SET OF or SEQUENCE OF */
495280297Sjkim# define ASN1_TFLG_SK_MASK       (0x3 << 1)
496109998Smarkm
497280297Sjkim/*
498280297Sjkim * These flags mean the tag should be taken from the tag field. If EXPLICIT
499280297Sjkim * then the underlying type is used for the inner tag.
500109998Smarkm */
501109998Smarkm
502109998Smarkm/* IMPLICIT tagging */
503280297Sjkim# define ASN1_TFLG_IMPTAG        (0x1 << 3)
504109998Smarkm
505109998Smarkm/* EXPLICIT tagging, inner tag from underlying type */
506280297Sjkim# define ASN1_TFLG_EXPTAG        (0x2 << 3)
507109998Smarkm
508280297Sjkim# define ASN1_TFLG_TAG_MASK      (0x3 << 3)
509109998Smarkm
510109998Smarkm/* context specific IMPLICIT */
511280297Sjkim# define ASN1_TFLG_IMPLICIT      ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
512109998Smarkm
513109998Smarkm/* context specific EXPLICIT */
514280297Sjkim# define ASN1_TFLG_EXPLICIT      ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
515109998Smarkm
516280297Sjkim/*
517280297Sjkim * If tagging is in force these determine the type of tag to use. Otherwise
518280297Sjkim * the tag is determined by the underlying type. These values reflect the
519280297Sjkim * actual octet format.
520109998Smarkm */
521109998Smarkm
522280297Sjkim/* Universal tag */
523280297Sjkim# define ASN1_TFLG_UNIVERSAL     (0x0<<6)
524280297Sjkim/* Application tag */
525280297Sjkim# define ASN1_TFLG_APPLICATION   (0x1<<6)
526280297Sjkim/* Context specific tag */
527280297Sjkim# define ASN1_TFLG_CONTEXT       (0x2<<6)
528280297Sjkim/* Private tag */
529280297Sjkim# define ASN1_TFLG_PRIVATE       (0x3<<6)
530109998Smarkm
531280297Sjkim# define ASN1_TFLG_TAG_CLASS     (0x3<<6)
532109998Smarkm
533280297Sjkim/*
534280297Sjkim * These are for ANY DEFINED BY type. In this case the 'item' field points to
535280297Sjkim * an ASN1_ADB structure which contains a table of values to decode the
536109998Smarkm * relevant type
537109998Smarkm */
538109998Smarkm
539280297Sjkim# define ASN1_TFLG_ADB_MASK      (0x3<<8)
540109998Smarkm
541280297Sjkim# define ASN1_TFLG_ADB_OID       (0x1<<8)
542109998Smarkm
543280297Sjkim# define ASN1_TFLG_ADB_INT       (0x1<<9)
544109998Smarkm
545280297Sjkim/*
546280297Sjkim * This flag means a parent structure is passed instead of the field: this is
547280297Sjkim * useful is a SEQUENCE is being combined with a CHOICE for example. Since
548280297Sjkim * this means the structure and item name will differ we need to use the
549109998Smarkm * ASN1_CHOICE_END_name() macro for example.
550109998Smarkm */
551109998Smarkm
552280297Sjkim# define ASN1_TFLG_COMBINE       (0x1<<10)
553109998Smarkm
554280297Sjkim/*
555280297Sjkim * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
556280297Sjkim * indefinite length constructed encoding to be used if required.
557160814Ssimon */
558160814Ssimon
559280297Sjkim# define ASN1_TFLG_NDEF          (0x1<<11)
560160814Ssimon
561109998Smarkm/* This is the actual ASN1 item itself */
562109998Smarkm
563109998Smarkmstruct ASN1_ITEM_st {
564280297Sjkim    char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
565280297Sjkim                                 * or extern */
566280297Sjkim    long utype;                 /* underlying type */
567280297Sjkim    const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
568280297Sjkim                                     * the contents */
569280297Sjkim    long tcount;                /* Number of templates if SEQUENCE or CHOICE */
570280297Sjkim    const void *funcs;          /* functions that handle this type */
571280297Sjkim    long size;                  /* Structure size (usually) */
572280297Sjkim# ifndef NO_ASN1_FIELD_NAMES
573280297Sjkim    const char *sname;          /* Structure name */
574280297Sjkim# endif
575109998Smarkm};
576109998Smarkm
577280297Sjkim/*-
578280297Sjkim * These are values for the itype field and
579109998Smarkm * determine how the type is interpreted.
580109998Smarkm *
581109998Smarkm * For PRIMITIVE types the underlying type
582109998Smarkm * determines the behaviour if items is NULL.
583109998Smarkm *
584280297Sjkim * Otherwise templates must contain a single
585109998Smarkm * template and the type is treated in the
586109998Smarkm * same way as the type specified in the template.
587109998Smarkm *
588109998Smarkm * For SEQUENCE types the templates field points
589109998Smarkm * to the members, the size field is the
590109998Smarkm * structure size.
591109998Smarkm *
592109998Smarkm * For CHOICE types the templates field points
593109998Smarkm * to each possible member (typically a union)
594109998Smarkm * and the 'size' field is the offset of the
595109998Smarkm * selector.
596109998Smarkm *
597109998Smarkm * The 'funcs' field is used for application
598280297Sjkim * specific functions.
599109998Smarkm *
600109998Smarkm * For COMPAT types the funcs field gives a
601109998Smarkm * set of functions that handle this type, this
602109998Smarkm * supports the old d2i, i2d convention.
603109998Smarkm *
604109998Smarkm * The EXTERN type uses a new style d2i/i2d.
605109998Smarkm * The new style should be used where possible
606109998Smarkm * because it avoids things like the d2i IMPLICIT
607109998Smarkm * hack.
608109998Smarkm *
609109998Smarkm * MSTRING is a multiple string type, it is used
610109998Smarkm * for a CHOICE of character strings where the
611109998Smarkm * actual strings all occupy an ASN1_STRING
612109998Smarkm * structure. In this case the 'utype' field
613109998Smarkm * has a special meaning, it is used as a mask
614109998Smarkm * of acceptable types using the B_ASN1 constants.
615109998Smarkm *
616160814Ssimon * NDEF_SEQUENCE is the same as SEQUENCE except
617160814Ssimon * that it will use indefinite length constructed
618160814Ssimon * encoding if requested.
619160814Ssimon *
620109998Smarkm */
621109998Smarkm
622280297Sjkim# define ASN1_ITYPE_PRIMITIVE            0x0
623109998Smarkm
624280297Sjkim# define ASN1_ITYPE_SEQUENCE             0x1
625109998Smarkm
626280297Sjkim# define ASN1_ITYPE_CHOICE               0x2
627109998Smarkm
628280297Sjkim# define ASN1_ITYPE_COMPAT               0x3
629109998Smarkm
630280297Sjkim# define ASN1_ITYPE_EXTERN               0x4
631109998Smarkm
632280297Sjkim# define ASN1_ITYPE_MSTRING              0x5
633109998Smarkm
634280297Sjkim# define ASN1_ITYPE_NDEF_SEQUENCE        0x6
635160814Ssimon
636280297Sjkim/*
637280297Sjkim * Cache for ASN1 tag and length, so we don't keep re-reading it for things
638109998Smarkm * like CHOICE
639109998Smarkm */
640109998Smarkm
641280297Sjkimstruct ASN1_TLC_st {
642280297Sjkim    char valid;                 /* Values below are valid */
643280297Sjkim    int ret;                    /* return value */
644280297Sjkim    long plen;                  /* length */
645280297Sjkim    int ptag;                   /* class value */
646280297Sjkim    int pclass;                 /* class value */
647280297Sjkim    int hdrlen;                 /* header length */
648109998Smarkm};
649109998Smarkm
650109998Smarkm/* Typedefs for ASN1 function pointers */
651109998Smarkm
652280297Sjkimtypedef ASN1_VALUE *ASN1_new_func(void);
653109998Smarkmtypedef void ASN1_free_func(ASN1_VALUE *a);
654280297Sjkimtypedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in,
655280297Sjkim                                  long length);
656280297Sjkimtypedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in);
657109998Smarkm
658280297Sjkimtypedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
659280297Sjkim                        const ASN1_ITEM *it, int tag, int aclass, char opt,
660280297Sjkim                        ASN1_TLC *ctx);
661109998Smarkm
662280297Sjkimtypedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
663280297Sjkim                        const ASN1_ITEM *it, int tag, int aclass);
664109998Smarkmtypedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
665109998Smarkmtypedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
666109998Smarkm
667280297Sjkimtypedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
668280297Sjkim                               int indent, const char *fname,
669280297Sjkim                               const ASN1_PCTX *pctx);
670238405Sjkim
671280297Sjkimtypedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
672280297Sjkim                               int *putype, const ASN1_ITEM *it);
673280297Sjkimtypedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
674280297Sjkim                               int len, int utype, char *free_cont,
675280297Sjkim                               const ASN1_ITEM *it);
676280297Sjkimtypedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
677280297Sjkim                                 const ASN1_ITEM *it, int indent,
678280297Sjkim                                 const ASN1_PCTX *pctx);
679109998Smarkm
680109998Smarkmtypedef struct ASN1_COMPAT_FUNCS_st {
681280297Sjkim    ASN1_new_func *asn1_new;
682280297Sjkim    ASN1_free_func *asn1_free;
683280297Sjkim    ASN1_d2i_func *asn1_d2i;
684280297Sjkim    ASN1_i2d_func *asn1_i2d;
685109998Smarkm} ASN1_COMPAT_FUNCS;
686109998Smarkm
687109998Smarkmtypedef struct ASN1_EXTERN_FUNCS_st {
688280297Sjkim    void *app_data;
689280297Sjkim    ASN1_ex_new_func *asn1_ex_new;
690280297Sjkim    ASN1_ex_free_func *asn1_ex_free;
691280297Sjkim    ASN1_ex_free_func *asn1_ex_clear;
692280297Sjkim    ASN1_ex_d2i *asn1_ex_d2i;
693280297Sjkim    ASN1_ex_i2d *asn1_ex_i2d;
694280297Sjkim    ASN1_ex_print_func *asn1_ex_print;
695109998Smarkm} ASN1_EXTERN_FUNCS;
696109998Smarkm
697109998Smarkmtypedef struct ASN1_PRIMITIVE_FUNCS_st {
698280297Sjkim    void *app_data;
699280297Sjkim    unsigned long flags;
700280297Sjkim    ASN1_ex_new_func *prim_new;
701280297Sjkim    ASN1_ex_free_func *prim_free;
702280297Sjkim    ASN1_ex_free_func *prim_clear;
703280297Sjkim    ASN1_primitive_c2i *prim_c2i;
704280297Sjkim    ASN1_primitive_i2c *prim_i2c;
705280297Sjkim    ASN1_primitive_print *prim_print;
706109998Smarkm} ASN1_PRIMITIVE_FUNCS;
707109998Smarkm
708280297Sjkim/*
709280297Sjkim * This is the ASN1_AUX structure: it handles various miscellaneous
710280297Sjkim * requirements. For example the use of reference counts and an informational
711280297Sjkim * callback. The "informational callback" is called at various points during
712280297Sjkim * the ASN1 encoding and decoding. It can be used to provide minor
713280297Sjkim * customisation of the structures used. This is most useful where the
714280297Sjkim * supplied routines *almost* do the right thing but need some extra help at
715280297Sjkim * a few points. If the callback returns zero then it is assumed a fatal
716280297Sjkim * error has occurred and the main operation should be abandoned. If major
717280297Sjkim * changes in the default behaviour are required then an external type is
718280297Sjkim * more appropriate.
719109998Smarkm */
720109998Smarkm
721238405Sjkimtypedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
722280297Sjkim                        void *exarg);
723109998Smarkm
724109998Smarkmtypedef struct ASN1_AUX_st {
725280297Sjkim    void *app_data;
726280297Sjkim    int flags;
727280297Sjkim    int ref_offset;             /* Offset of reference value */
728280297Sjkim    int ref_lock;               /* Lock type to use */
729280297Sjkim    ASN1_aux_cb *asn1_cb;
730280297Sjkim    int enc_offset;             /* Offset of ASN1_ENCODING structure */
731109998Smarkm} ASN1_AUX;
732109998Smarkm
733238405Sjkim/* For print related callbacks exarg points to this structure */
734238405Sjkimtypedef struct ASN1_PRINT_ARG_st {
735280297Sjkim    BIO *out;
736280297Sjkim    int indent;
737280297Sjkim    const ASN1_PCTX *pctx;
738238405Sjkim} ASN1_PRINT_ARG;
739238405Sjkim
740238405Sjkim/* For streaming related callbacks exarg points to this structure */
741238405Sjkimtypedef struct ASN1_STREAM_ARG_st {
742280297Sjkim    /* BIO to stream through */
743280297Sjkim    BIO *out;
744280297Sjkim    /* BIO with filters appended */
745280297Sjkim    BIO *ndef_bio;
746280297Sjkim    /* Streaming I/O boundary */
747280297Sjkim    unsigned char **boundary;
748238405Sjkim} ASN1_STREAM_ARG;
749238405Sjkim
750109998Smarkm/* Flags in ASN1_AUX */
751109998Smarkm
752109998Smarkm/* Use a reference count */
753280297Sjkim# define ASN1_AFLG_REFCOUNT      1
754109998Smarkm/* Save the encoding of structure (useful for signatures) */
755280297Sjkim# define ASN1_AFLG_ENCODING      2
756109998Smarkm/* The Sequence length is invalid */
757280297Sjkim# define ASN1_AFLG_BROKEN        4
758109998Smarkm
759109998Smarkm/* operation values for asn1_cb */
760109998Smarkm
761280297Sjkim# define ASN1_OP_NEW_PRE         0
762280297Sjkim# define ASN1_OP_NEW_POST        1
763280297Sjkim# define ASN1_OP_FREE_PRE        2
764280297Sjkim# define ASN1_OP_FREE_POST       3
765280297Sjkim# define ASN1_OP_D2I_PRE         4
766280297Sjkim# define ASN1_OP_D2I_POST        5
767280297Sjkim# define ASN1_OP_I2D_PRE         6
768280297Sjkim# define ASN1_OP_I2D_POST        7
769280297Sjkim# define ASN1_OP_PRINT_PRE       8
770280297Sjkim# define ASN1_OP_PRINT_POST      9
771280297Sjkim# define ASN1_OP_STREAM_PRE      10
772280297Sjkim# define ASN1_OP_STREAM_POST     11
773280297Sjkim# define ASN1_OP_DETACHED_PRE    12
774280297Sjkim# define ASN1_OP_DETACHED_POST   13
775109998Smarkm
776109998Smarkm/* Macro to implement a primitive type */
777280297Sjkim# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
778280297Sjkim# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
779280297Sjkim                                ASN1_ITEM_start(itname) \
780280297Sjkim                                        ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
781280297Sjkim                                ASN1_ITEM_end(itname)
782109998Smarkm
783109998Smarkm/* Macro to implement a multi string type */
784280297Sjkim# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
785280297Sjkim                                ASN1_ITEM_start(itname) \
786280297Sjkim                                        ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
787280297Sjkim                                ASN1_ITEM_end(itname)
788109998Smarkm
789109998Smarkm/* Macro to implement an ASN1_ITEM in terms of old style funcs */
790109998Smarkm
791280297Sjkim# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
792109998Smarkm
793280297Sjkim# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
794280297Sjkim        static const ASN1_COMPAT_FUNCS sname##_ff = { \
795280297Sjkim                (ASN1_new_func *)sname##_new, \
796280297Sjkim                (ASN1_free_func *)sname##_free, \
797280297Sjkim                (ASN1_d2i_func *)d2i_##sname, \
798280297Sjkim                (ASN1_i2d_func *)i2d_##sname, \
799280297Sjkim        }; \
800280297Sjkim        ASN1_ITEM_start(sname) \
801280297Sjkim                ASN1_ITYPE_COMPAT, \
802280297Sjkim                tag, \
803280297Sjkim                NULL, \
804280297Sjkim                0, \
805280297Sjkim                &sname##_ff, \
806280297Sjkim                0, \
807280297Sjkim                #sname \
808280297Sjkim        ASN1_ITEM_end(sname)
809109998Smarkm
810280297Sjkim# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
811280297Sjkim        ASN1_ITEM_start(sname) \
812280297Sjkim                ASN1_ITYPE_EXTERN, \
813280297Sjkim                tag, \
814280297Sjkim                NULL, \
815280297Sjkim                0, \
816280297Sjkim                &fptrs, \
817280297Sjkim                0, \
818280297Sjkim                #sname \
819280297Sjkim        ASN1_ITEM_end(sname)
820109998Smarkm
821109998Smarkm/* Macro to implement standard functions in terms of ASN1_ITEM structures */
822109998Smarkm
823280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
824109998Smarkm
825280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
826109998Smarkm
827280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
828280297Sjkim                        IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
829109998Smarkm
830280297Sjkim# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
831280297Sjkim                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
832238405Sjkim
833280297Sjkim# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
834280297Sjkim                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
835160814Ssimon
836280297Sjkim# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
837280297Sjkim        pre stname *fname##_new(void) \
838280297Sjkim        { \
839280297Sjkim                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
840280297Sjkim        } \
841280297Sjkim        pre void fname##_free(stname *a) \
842280297Sjkim        { \
843280297Sjkim                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
844280297Sjkim        }
845238405Sjkim
846280297Sjkim# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
847280297Sjkim        stname *fname##_new(void) \
848280297Sjkim        { \
849280297Sjkim                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
850280297Sjkim        } \
851280297Sjkim        void fname##_free(stname *a) \
852280297Sjkim        { \
853280297Sjkim                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
854280297Sjkim        }
855109998Smarkm
856280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
857280297Sjkim        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
858280297Sjkim        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
859109998Smarkm
860280297Sjkim# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
861280297Sjkim        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
862280297Sjkim        { \
863280297Sjkim                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
864280297Sjkim        } \
865280297Sjkim        int i2d_##fname(stname *a, unsigned char **out) \
866280297Sjkim        { \
867280297Sjkim                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
868280297Sjkim        }
869109998Smarkm
870280297Sjkim# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
871280297Sjkim        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
872280297Sjkim        { \
873280297Sjkim                return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
874280297Sjkim        }
875160814Ssimon
876280297Sjkim/*
877280297Sjkim * This includes evil casts to remove const: they will go away when full ASN1
878280297Sjkim * constification is done.
879109998Smarkm */
880280297Sjkim# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
881280297Sjkim        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
882280297Sjkim        { \
883280297Sjkim                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
884280297Sjkim        } \
885280297Sjkim        int i2d_##fname(const stname *a, unsigned char **out) \
886280297Sjkim        { \
887280297Sjkim                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
888280297Sjkim        }
889109998Smarkm
890280297Sjkim# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
891280297Sjkim        stname * stname##_dup(stname *x) \
892109998Smarkm        { \
893109998Smarkm        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
894109998Smarkm        }
895109998Smarkm
896280297Sjkim# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
897280297Sjkim        IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
898238405Sjkim
899280297Sjkim# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
900280297Sjkim        int fname##_print_ctx(BIO *out, stname *x, int indent, \
901280297Sjkim                                                const ASN1_PCTX *pctx) \
902280297Sjkim        { \
903280297Sjkim                return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
904280297Sjkim                        ASN1_ITEM_rptr(itname), pctx); \
905280297Sjkim        }
906238405Sjkim
907280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
908280297Sjkim                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
909109998Smarkm
910280297Sjkim# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
911280297Sjkim        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
912280297Sjkim        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
913109998Smarkm
914109998Smarkm/* external definitions for primitive types */
915109998Smarkm
916109998SmarkmDECLARE_ASN1_ITEM(ASN1_BOOLEAN)
917109998SmarkmDECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
918109998SmarkmDECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
919109998SmarkmDECLARE_ASN1_ITEM(ASN1_SEQUENCE)
920109998SmarkmDECLARE_ASN1_ITEM(CBIGNUM)
921109998SmarkmDECLARE_ASN1_ITEM(BIGNUM)
922109998SmarkmDECLARE_ASN1_ITEM(LONG)
923109998SmarkmDECLARE_ASN1_ITEM(ZLONG)
924109998Smarkm
925109998SmarkmDECLARE_STACK_OF(ASN1_VALUE)
926109998Smarkm
927109998Smarkm/* Functions used internally by the ASN1 code */
928109998Smarkm
929109998Smarkmint ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
930109998Smarkmvoid ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
931109998Smarkmint ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
932109998Smarkmint ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
933109998Smarkm
934109998Smarkmvoid ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
935280297Sjkimint ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
936280297Sjkim                      const ASN1_TEMPLATE *tt);
937280297Sjkimint ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
938280297Sjkim                     const ASN1_ITEM *it, int tag, int aclass, char opt,
939280297Sjkim                     ASN1_TLC *ctx);
940109998Smarkm
941280297Sjkimint ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
942280297Sjkim                     const ASN1_ITEM *it, int tag, int aclass);
943280297Sjkimint ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
944280297Sjkim                      const ASN1_TEMPLATE *tt);
945109998Smarkmvoid ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
946109998Smarkm
947280297Sjkimint asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
948280297Sjkim                const ASN1_ITEM *it);
949280297Sjkimint asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
950280297Sjkim                int utype, char *free_cont, const ASN1_ITEM *it);
951109998Smarkm
952109998Smarkmint asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
953280297Sjkimint asn1_set_choice_selector(ASN1_VALUE **pval, int value,
954280297Sjkim                             const ASN1_ITEM *it);
955109998Smarkm
956280297SjkimASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
957109998Smarkm
958280297Sjkimconst ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
959280297Sjkim                                 int nullerr);
960109998Smarkm
961109998Smarkmint asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
962109998Smarkm
963109998Smarkmvoid asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
964109998Smarkmvoid asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
965280297Sjkimint asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
966280297Sjkim                     const ASN1_ITEM *it);
967280297Sjkimint asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
968280297Sjkim                  const ASN1_ITEM *it);
969109998Smarkm
970109998Smarkm#ifdef  __cplusplus
971109998Smarkm}
972109998Smarkm#endif
973109998Smarkm#endif
974