xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/asn1t.h (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* asn1t.h */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate  * project 2000.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate  * are met:
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
180Sstevel@tonic-gate  *    distribution.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate  *    software must display the following acknowledgment:
220Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate  *    endorse or promote products derived from this software without
270Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
280Sstevel@tonic-gate  *    licensing@OpenSSL.org.
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate  *    permission of the OpenSSL Project.
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate  *    acknowledgment:
360Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate  * ====================================================================
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
550Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate #ifndef HEADER_ASN1T_H
590Sstevel@tonic-gate #define HEADER_ASN1T_H
600Sstevel@tonic-gate 
610Sstevel@tonic-gate #include <stddef.h>
620Sstevel@tonic-gate #include <openssl/e_os2.h>
630Sstevel@tonic-gate #include <openssl/asn1.h>
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #ifdef OPENSSL_BUILD_SHLIBCRYPTO
660Sstevel@tonic-gate # undef OPENSSL_EXTERN
670Sstevel@tonic-gate # define OPENSSL_EXTERN OPENSSL_EXPORT
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /* ASN1 template defines, structures and functions */
710Sstevel@tonic-gate 
720Sstevel@tonic-gate #ifdef  __cplusplus
730Sstevel@tonic-gate extern "C" {
740Sstevel@tonic-gate #endif
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 
770Sstevel@tonic-gate #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
800Sstevel@tonic-gate #define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 
830Sstevel@tonic-gate /* Macros for start and end of ASN1_ITEM definition */
840Sstevel@tonic-gate 
850Sstevel@tonic-gate #define ASN1_ITEM_start(itname) \
860Sstevel@tonic-gate 	OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
870Sstevel@tonic-gate 
880Sstevel@tonic-gate #define ASN1_ITEM_end(itname) \
890Sstevel@tonic-gate 		};
900Sstevel@tonic-gate 
910Sstevel@tonic-gate #else
920Sstevel@tonic-gate 
930Sstevel@tonic-gate /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
940Sstevel@tonic-gate #define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 
970Sstevel@tonic-gate /* Macros for start and end of ASN1_ITEM definition */
980Sstevel@tonic-gate 
990Sstevel@tonic-gate #define ASN1_ITEM_start(itname) \
1000Sstevel@tonic-gate 	const ASN1_ITEM * itname##_it(void) \
1010Sstevel@tonic-gate 	{ \
1020Sstevel@tonic-gate 		static const ASN1_ITEM local_it = { \
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate #define ASN1_ITEM_end(itname) \
1050Sstevel@tonic-gate 		}; \
1060Sstevel@tonic-gate 	return &local_it; \
1070Sstevel@tonic-gate 	}
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate #endif
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate /* Macros to aid ASN1 template writing */
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate #define ASN1_ITEM_TEMPLATE(tname) \
115*2139Sjp161948 	static const ASN1_TEMPLATE tname##_item_tt
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate #define ASN1_ITEM_TEMPLATE_END(tname) \
1180Sstevel@tonic-gate 	;\
1190Sstevel@tonic-gate 	ASN1_ITEM_start(tname) \
1200Sstevel@tonic-gate 		ASN1_ITYPE_PRIMITIVE,\
1210Sstevel@tonic-gate 		-1,\
1220Sstevel@tonic-gate 		&tname##_item_tt,\
1230Sstevel@tonic-gate 		0,\
1240Sstevel@tonic-gate 		NULL,\
1250Sstevel@tonic-gate 		0,\
1260Sstevel@tonic-gate 		#tname \
1270Sstevel@tonic-gate 	ASN1_ITEM_end(tname)
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /* This is a ASN1 type which just embeds a template */
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate /* This pair helps declare a SEQUENCE. We can do:
1330Sstevel@tonic-gate  *
1340Sstevel@tonic-gate  * 	ASN1_SEQUENCE(stname) = {
1350Sstevel@tonic-gate  * 		... SEQUENCE components ...
1360Sstevel@tonic-gate  * 	} ASN1_SEQUENCE_END(stname)
1370Sstevel@tonic-gate  *
1380Sstevel@tonic-gate  * 	This will produce an ASN1_ITEM called stname_it
1390Sstevel@tonic-gate  *	for a structure called stname.
1400Sstevel@tonic-gate  *
1410Sstevel@tonic-gate  * 	If you want the same structure but a different
1420Sstevel@tonic-gate  *	name then use:
1430Sstevel@tonic-gate  *
1440Sstevel@tonic-gate  * 	ASN1_SEQUENCE(itname) = {
1450Sstevel@tonic-gate  * 		... SEQUENCE components ...
1460Sstevel@tonic-gate  * 	} ASN1_SEQUENCE_END_name(stname, itname)
1470Sstevel@tonic-gate  *
1480Sstevel@tonic-gate  *	This will create an item called itname_it using
1490Sstevel@tonic-gate  *	a structure called stname.
1500Sstevel@tonic-gate  */
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate #define ASN1_SEQUENCE(tname) \
153*2139Sjp161948 	static const ASN1_TEMPLATE tname##_seq_tt[]
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate #define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate #define ASN1_SEQUENCE_END_name(stname, tname) \
1580Sstevel@tonic-gate 	;\
1590Sstevel@tonic-gate 	ASN1_ITEM_start(tname) \
1600Sstevel@tonic-gate 		ASN1_ITYPE_SEQUENCE,\
1610Sstevel@tonic-gate 		V_ASN1_SEQUENCE,\
1620Sstevel@tonic-gate 		tname##_seq_tt,\
1630Sstevel@tonic-gate 		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
1640Sstevel@tonic-gate 		NULL,\
1650Sstevel@tonic-gate 		sizeof(stname),\
1660Sstevel@tonic-gate 		#stname \
1670Sstevel@tonic-gate 	ASN1_ITEM_end(tname)
1680Sstevel@tonic-gate 
169*2139Sjp161948 #define ASN1_NDEF_SEQUENCE(tname) \
170*2139Sjp161948 	ASN1_SEQUENCE(tname)
171*2139Sjp161948 
1720Sstevel@tonic-gate #define ASN1_SEQUENCE_cb(tname, cb) \
173*2139Sjp161948 	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
1740Sstevel@tonic-gate 	ASN1_SEQUENCE(tname)
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate #define ASN1_BROKEN_SEQUENCE(tname) \
177*2139Sjp161948 	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
1780Sstevel@tonic-gate 	ASN1_SEQUENCE(tname)
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate #define ASN1_SEQUENCE_ref(tname, cb, lck) \
181*2139Sjp161948 	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
1820Sstevel@tonic-gate 	ASN1_SEQUENCE(tname)
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate #define ASN1_SEQUENCE_enc(tname, enc, cb) \
185*2139Sjp161948 	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
1860Sstevel@tonic-gate 	ASN1_SEQUENCE(tname)
1870Sstevel@tonic-gate 
188*2139Sjp161948 #define ASN1_NDEF_SEQUENCE_END(tname) \
189*2139Sjp161948 	;\
190*2139Sjp161948 	ASN1_ITEM_start(tname) \
191*2139Sjp161948 		ASN1_ITYPE_NDEF_SEQUENCE,\
192*2139Sjp161948 		V_ASN1_SEQUENCE,\
193*2139Sjp161948 		tname##_seq_tt,\
194*2139Sjp161948 		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
195*2139Sjp161948 		NULL,\
196*2139Sjp161948 		sizeof(tname),\
197*2139Sjp161948 		#tname \
198*2139Sjp161948 	ASN1_ITEM_end(tname)
199*2139Sjp161948 
2000Sstevel@tonic-gate #define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate #define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate #define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate #define ASN1_SEQUENCE_END_ref(stname, tname) \
2070Sstevel@tonic-gate 	;\
2080Sstevel@tonic-gate 	ASN1_ITEM_start(tname) \
2090Sstevel@tonic-gate 		ASN1_ITYPE_SEQUENCE,\
2100Sstevel@tonic-gate 		V_ASN1_SEQUENCE,\
2110Sstevel@tonic-gate 		tname##_seq_tt,\
2120Sstevel@tonic-gate 		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
2130Sstevel@tonic-gate 		&tname##_aux,\
2140Sstevel@tonic-gate 		sizeof(stname),\
2150Sstevel@tonic-gate 		#stname \
2160Sstevel@tonic-gate 	ASN1_ITEM_end(tname)
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate /* This pair helps declare a CHOICE type. We can do:
2200Sstevel@tonic-gate  *
2210Sstevel@tonic-gate  * 	ASN1_CHOICE(chname) = {
2220Sstevel@tonic-gate  * 		... CHOICE options ...
2230Sstevel@tonic-gate  * 	ASN1_CHOICE_END(chname)
2240Sstevel@tonic-gate  *
2250Sstevel@tonic-gate  * 	This will produce an ASN1_ITEM called chname_it
2260Sstevel@tonic-gate  *	for a structure called chname. The structure
2270Sstevel@tonic-gate  *	definition must look like this:
2280Sstevel@tonic-gate  *	typedef struct {
2290Sstevel@tonic-gate  *		int type;
2300Sstevel@tonic-gate  *		union {
2310Sstevel@tonic-gate  *			ASN1_SOMETHING *opt1;
2320Sstevel@tonic-gate  *			ASN1_SOMEOTHER *opt2;
2330Sstevel@tonic-gate  *		} value;
2340Sstevel@tonic-gate  *	} chname;
2350Sstevel@tonic-gate  *
2360Sstevel@tonic-gate  *	the name of the selector must be 'type'.
2370Sstevel@tonic-gate  * 	to use an alternative selector name use the
2380Sstevel@tonic-gate  *      ASN1_CHOICE_END_selector() version.
2390Sstevel@tonic-gate  */
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate #define ASN1_CHOICE(tname) \
242*2139Sjp161948 	static const ASN1_TEMPLATE tname##_ch_tt[]
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate #define ASN1_CHOICE_cb(tname, cb) \
245*2139Sjp161948 	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
2460Sstevel@tonic-gate 	ASN1_CHOICE(tname)
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate #define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate #define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate #define ASN1_CHOICE_END_selector(stname, tname, selname) \
2530Sstevel@tonic-gate 	;\
2540Sstevel@tonic-gate 	ASN1_ITEM_start(tname) \
2550Sstevel@tonic-gate 		ASN1_ITYPE_CHOICE,\
2560Sstevel@tonic-gate 		offsetof(stname,selname) ,\
2570Sstevel@tonic-gate 		tname##_ch_tt,\
2580Sstevel@tonic-gate 		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
2590Sstevel@tonic-gate 		NULL,\
2600Sstevel@tonic-gate 		sizeof(stname),\
2610Sstevel@tonic-gate 		#stname \
2620Sstevel@tonic-gate 	ASN1_ITEM_end(tname)
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate #define ASN1_CHOICE_END_cb(stname, tname, selname) \
2650Sstevel@tonic-gate 	;\
2660Sstevel@tonic-gate 	ASN1_ITEM_start(tname) \
2670Sstevel@tonic-gate 		ASN1_ITYPE_CHOICE,\
2680Sstevel@tonic-gate 		offsetof(stname,selname) ,\
2690Sstevel@tonic-gate 		tname##_ch_tt,\
2700Sstevel@tonic-gate 		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
2710Sstevel@tonic-gate 		&tname##_aux,\
2720Sstevel@tonic-gate 		sizeof(stname),\
2730Sstevel@tonic-gate 		#stname \
2740Sstevel@tonic-gate 	ASN1_ITEM_end(tname)
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate /* This helps with the template wrapper form of ASN1_ITEM */
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate #define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
2790Sstevel@tonic-gate 	(flags), (tag), 0,\
2800Sstevel@tonic-gate 	#name, ASN1_ITEM_ref(type) }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate /* These help with SEQUENCE or CHOICE components */
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate /* used to declare other types */
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate #define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
2870Sstevel@tonic-gate 	(flags), (tag), offsetof(stname, field),\
2880Sstevel@tonic-gate 	#field, ASN1_ITEM_ref(type) }
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate /* used when the structure is combined with the parent */
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate #define ASN1_EX_COMBINE(flags, tag, type) { \
2930Sstevel@tonic-gate 	(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate /* implicit and explicit helper macros */
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate #define ASN1_IMP_EX(stname, field, type, tag, ex) \
2980Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate #define ASN1_EXP_EX(stname, field, type, tag, ex) \
3010Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate /* Any defined by macros: the field used is in the table itself */
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
3060Sstevel@tonic-gate #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
3070Sstevel@tonic-gate #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
3080Sstevel@tonic-gate #else
3090Sstevel@tonic-gate #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
3100Sstevel@tonic-gate #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
3110Sstevel@tonic-gate #endif
3120Sstevel@tonic-gate /* Plain simple type */
3130Sstevel@tonic-gate #define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate /* OPTIONAL simple type */
3160Sstevel@tonic-gate #define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate /* IMPLICIT tagged simple type */
3190Sstevel@tonic-gate #define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate /* IMPLICIT tagged OPTIONAL simple type */
3220Sstevel@tonic-gate #define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate /* Same as above but EXPLICIT */
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate #define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
3270Sstevel@tonic-gate #define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate /* SEQUENCE OF type */
3300Sstevel@tonic-gate #define ASN1_SEQUENCE_OF(stname, field, type) \
3310Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate /* OPTIONAL SEQUENCE OF */
3340Sstevel@tonic-gate #define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
3350Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate /* Same as above but for SET OF */
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate #define ASN1_SET_OF(stname, field, type) \
3400Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate #define ASN1_SET_OF_OPT(stname, field, type) \
3430Sstevel@tonic-gate 		ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate /* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate #define ASN1_IMP_SET_OF(stname, field, type, tag) \
3480Sstevel@tonic-gate 			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate #define ASN1_EXP_SET_OF(stname, field, type, tag) \
3510Sstevel@tonic-gate 			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate #define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
3540Sstevel@tonic-gate 			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate #define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
3570Sstevel@tonic-gate 			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate #define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
3600Sstevel@tonic-gate 			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate #define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
3630Sstevel@tonic-gate 			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate #define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
3660Sstevel@tonic-gate 			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate #define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
3690Sstevel@tonic-gate 			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
3700Sstevel@tonic-gate 
371*2139Sjp161948 /* EXPLICIT OPTIONAL using indefinite length constructed form */
372*2139Sjp161948 #define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
373*2139Sjp161948 			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
374*2139Sjp161948 
3750Sstevel@tonic-gate /* Macros for the ASN1_ADB structure */
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate #define ASN1_ADB(name) \
378*2139Sjp161948 	static const ASN1_ADB_TABLE name##_adbtbl[]
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate #define ASN1_ADB_END(name, flags, field, app_table, def, none) \
3830Sstevel@tonic-gate 	;\
384*2139Sjp161948 	static const ASN1_ADB name##_adb = {\
3850Sstevel@tonic-gate 		flags,\
3860Sstevel@tonic-gate 		offsetof(name, field),\
3870Sstevel@tonic-gate 		app_table,\
3880Sstevel@tonic-gate 		name##_adbtbl,\
3890Sstevel@tonic-gate 		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
3900Sstevel@tonic-gate 		def,\
3910Sstevel@tonic-gate 		none\
3920Sstevel@tonic-gate 	}
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate #else
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate #define ASN1_ADB_END(name, flags, field, app_table, def, none) \
3970Sstevel@tonic-gate 	;\
398*2139Sjp161948 	static const ASN1_ITEM *name##_adb(void) \
3990Sstevel@tonic-gate 	{ \
400*2139Sjp161948 	static const ASN1_ADB internal_adb = \
4010Sstevel@tonic-gate 		{\
4020Sstevel@tonic-gate 		flags,\
4030Sstevel@tonic-gate 		offsetof(name, field),\
4040Sstevel@tonic-gate 		app_table,\
4050Sstevel@tonic-gate 		name##_adbtbl,\
4060Sstevel@tonic-gate 		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
4070Sstevel@tonic-gate 		def,\
4080Sstevel@tonic-gate 		none\
4090Sstevel@tonic-gate 		}; \
4100Sstevel@tonic-gate 		return (const ASN1_ITEM *) &internal_adb; \
4110Sstevel@tonic-gate 	} \
4120Sstevel@tonic-gate 	void dummy_function(void)
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate #endif
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate #define ADB_ENTRY(val, template) {val, template}
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate #define ASN1_ADB_TEMPLATE(name) \
419*2139Sjp161948 	static const ASN1_TEMPLATE name##_tt
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate /* This is the ASN1 template structure that defines
4220Sstevel@tonic-gate  * a wrapper round the actual type. It determines the
4230Sstevel@tonic-gate  * actual position of the field in the value structure,
4240Sstevel@tonic-gate  * various flags such as OPTIONAL and the field name.
4250Sstevel@tonic-gate  */
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate struct ASN1_TEMPLATE_st {
4280Sstevel@tonic-gate unsigned long flags;		/* Various flags */
4290Sstevel@tonic-gate long tag;			/* tag, not used if no tagging */
4300Sstevel@tonic-gate unsigned long offset;		/* Offset of this field in structure */
4310Sstevel@tonic-gate #ifndef NO_ASN1_FIELD_NAMES
432*2139Sjp161948 const char *field_name;		/* Field name */
4330Sstevel@tonic-gate #endif
4340Sstevel@tonic-gate ASN1_ITEM_EXP *item;		/* Relevant ASN1_ITEM or ASN1_ADB */
4350Sstevel@tonic-gate };
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate /* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate #define ASN1_TEMPLATE_item(t) (t->item_ptr)
4400Sstevel@tonic-gate #define ASN1_TEMPLATE_adb(t) (t->item_ptr)
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
4430Sstevel@tonic-gate typedef struct ASN1_ADB_st ASN1_ADB;
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate struct ASN1_ADB_st {
4460Sstevel@tonic-gate 	unsigned long flags;	/* Various flags */
4470Sstevel@tonic-gate 	unsigned long offset;	/* Offset of selector field */
4480Sstevel@tonic-gate 	STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
4490Sstevel@tonic-gate 	const ASN1_ADB_TABLE *tbl;	/* Table of possible types */
4500Sstevel@tonic-gate 	long tblcount;		/* Number of entries in tbl */
4510Sstevel@tonic-gate 	const ASN1_TEMPLATE *default_tt;  /* Type to use if no match */
4520Sstevel@tonic-gate 	const ASN1_TEMPLATE *null_tt;  /* Type to use if selector is NULL */
4530Sstevel@tonic-gate };
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate struct ASN1_ADB_TABLE_st {
4560Sstevel@tonic-gate 	long value;		/* NID for an object or value for an int */
4570Sstevel@tonic-gate 	const ASN1_TEMPLATE tt;		/* item for this value */
4580Sstevel@tonic-gate };
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate /* template flags */
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate /* Field is optional */
4630Sstevel@tonic-gate #define ASN1_TFLG_OPTIONAL	(0x1)
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate /* Field is a SET OF */
4660Sstevel@tonic-gate #define ASN1_TFLG_SET_OF	(0x1 << 1)
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate /* Field is a SEQUENCE OF */
4690Sstevel@tonic-gate #define ASN1_TFLG_SEQUENCE_OF	(0x2 << 1)
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate /* Special case: this refers to a SET OF that
4720Sstevel@tonic-gate  * will be sorted into DER order when encoded *and*
4730Sstevel@tonic-gate  * the corresponding STACK will be modified to match
4740Sstevel@tonic-gate  * the new order.
4750Sstevel@tonic-gate  */
4760Sstevel@tonic-gate #define ASN1_TFLG_SET_ORDER	(0x3 << 1)
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate /* Mask for SET OF or SEQUENCE OF */
4790Sstevel@tonic-gate #define ASN1_TFLG_SK_MASK	(0x3 << 1)
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate /* These flags mean the tag should be taken from the
4820Sstevel@tonic-gate  * tag field. If EXPLICIT then the underlying type
4830Sstevel@tonic-gate  * is used for the inner tag.
4840Sstevel@tonic-gate  */
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate /* IMPLICIT tagging */
4870Sstevel@tonic-gate #define ASN1_TFLG_IMPTAG	(0x1 << 3)
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate /* EXPLICIT tagging, inner tag from underlying type */
4910Sstevel@tonic-gate #define ASN1_TFLG_EXPTAG	(0x2 << 3)
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate #define ASN1_TFLG_TAG_MASK	(0x3 << 3)
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate /* context specific IMPLICIT */
4960Sstevel@tonic-gate #define ASN1_TFLG_IMPLICIT	ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate /* context specific EXPLICIT */
4990Sstevel@tonic-gate #define ASN1_TFLG_EXPLICIT	ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate /* If tagging is in force these determine the
5020Sstevel@tonic-gate  * type of tag to use. Otherwise the tag is
5030Sstevel@tonic-gate  * determined by the underlying type. These
5040Sstevel@tonic-gate  * values reflect the actual octet format.
5050Sstevel@tonic-gate  */
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate /* Universal tag */
5080Sstevel@tonic-gate #define ASN1_TFLG_UNIVERSAL	(0x0<<6)
5090Sstevel@tonic-gate /* Application tag */
5100Sstevel@tonic-gate #define ASN1_TFLG_APPLICATION	(0x1<<6)
5110Sstevel@tonic-gate /* Context specific tag */
5120Sstevel@tonic-gate #define ASN1_TFLG_CONTEXT	(0x2<<6)
5130Sstevel@tonic-gate /* Private tag */
5140Sstevel@tonic-gate #define ASN1_TFLG_PRIVATE	(0x3<<6)
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate #define ASN1_TFLG_TAG_CLASS	(0x3<<6)
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate /* These are for ANY DEFINED BY type. In this case
5190Sstevel@tonic-gate  * the 'item' field points to an ASN1_ADB structure
5200Sstevel@tonic-gate  * which contains a table of values to decode the
5210Sstevel@tonic-gate  * relevant type
5220Sstevel@tonic-gate  */
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate #define ASN1_TFLG_ADB_MASK	(0x3<<8)
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate #define ASN1_TFLG_ADB_OID	(0x1<<8)
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate #define ASN1_TFLG_ADB_INT	(0x1<<9)
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate /* This flag means a parent structure is passed
5310Sstevel@tonic-gate  * instead of the field: this is useful is a
5320Sstevel@tonic-gate  * SEQUENCE is being combined with a CHOICE for
5330Sstevel@tonic-gate  * example. Since this means the structure and
5340Sstevel@tonic-gate  * item name will differ we need to use the
5350Sstevel@tonic-gate  * ASN1_CHOICE_END_name() macro for example.
5360Sstevel@tonic-gate  */
5370Sstevel@tonic-gate 
5380Sstevel@tonic-gate #define ASN1_TFLG_COMBINE	(0x1<<10)
5390Sstevel@tonic-gate 
540*2139Sjp161948 /* This flag when present in a SEQUENCE OF, SET OF
541*2139Sjp161948  * or EXPLICIT causes indefinite length constructed
542*2139Sjp161948  * encoding to be used if required.
543*2139Sjp161948  */
544*2139Sjp161948 
545*2139Sjp161948 #define ASN1_TFLG_NDEF		(0x1<<11)
546*2139Sjp161948 
5470Sstevel@tonic-gate /* This is the actual ASN1 item itself */
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate struct ASN1_ITEM_st {
5500Sstevel@tonic-gate char itype;			/* The item type, primitive, SEQUENCE, CHOICE or extern */
5510Sstevel@tonic-gate long utype;			/* underlying type */
5520Sstevel@tonic-gate const ASN1_TEMPLATE *templates;	/* If SEQUENCE or CHOICE this contains the contents */
5530Sstevel@tonic-gate long tcount;			/* Number of templates if SEQUENCE or CHOICE */
5540Sstevel@tonic-gate const void *funcs;		/* functions that handle this type */
5550Sstevel@tonic-gate long size;			/* Structure size (usually)*/
5560Sstevel@tonic-gate #ifndef NO_ASN1_FIELD_NAMES
5570Sstevel@tonic-gate const char *sname;		/* Structure name */
5580Sstevel@tonic-gate #endif
5590Sstevel@tonic-gate };
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate /* These are values for the itype field and
5620Sstevel@tonic-gate  * determine how the type is interpreted.
5630Sstevel@tonic-gate  *
5640Sstevel@tonic-gate  * For PRIMITIVE types the underlying type
5650Sstevel@tonic-gate  * determines the behaviour if items is NULL.
5660Sstevel@tonic-gate  *
5670Sstevel@tonic-gate  * Otherwise templates must contain a single
5680Sstevel@tonic-gate  * template and the type is treated in the
5690Sstevel@tonic-gate  * same way as the type specified in the template.
5700Sstevel@tonic-gate  *
5710Sstevel@tonic-gate  * For SEQUENCE types the templates field points
5720Sstevel@tonic-gate  * to the members, the size field is the
5730Sstevel@tonic-gate  * structure size.
5740Sstevel@tonic-gate  *
5750Sstevel@tonic-gate  * For CHOICE types the templates field points
5760Sstevel@tonic-gate  * to each possible member (typically a union)
5770Sstevel@tonic-gate  * and the 'size' field is the offset of the
5780Sstevel@tonic-gate  * selector.
5790Sstevel@tonic-gate  *
5800Sstevel@tonic-gate  * The 'funcs' field is used for application
5810Sstevel@tonic-gate  * specific functions.
5820Sstevel@tonic-gate  *
5830Sstevel@tonic-gate  * For COMPAT types the funcs field gives a
5840Sstevel@tonic-gate  * set of functions that handle this type, this
5850Sstevel@tonic-gate  * supports the old d2i, i2d convention.
5860Sstevel@tonic-gate  *
5870Sstevel@tonic-gate  * The EXTERN type uses a new style d2i/i2d.
5880Sstevel@tonic-gate  * The new style should be used where possible
5890Sstevel@tonic-gate  * because it avoids things like the d2i IMPLICIT
5900Sstevel@tonic-gate  * hack.
5910Sstevel@tonic-gate  *
5920Sstevel@tonic-gate  * MSTRING is a multiple string type, it is used
5930Sstevel@tonic-gate  * for a CHOICE of character strings where the
5940Sstevel@tonic-gate  * actual strings all occupy an ASN1_STRING
5950Sstevel@tonic-gate  * structure. In this case the 'utype' field
5960Sstevel@tonic-gate  * has a special meaning, it is used as a mask
5970Sstevel@tonic-gate  * of acceptable types using the B_ASN1 constants.
5980Sstevel@tonic-gate  *
599*2139Sjp161948  * NDEF_SEQUENCE is the same as SEQUENCE except
600*2139Sjp161948  * that it will use indefinite length constructed
601*2139Sjp161948  * encoding if requested.
602*2139Sjp161948  *
6030Sstevel@tonic-gate  */
6040Sstevel@tonic-gate 
605*2139Sjp161948 #define ASN1_ITYPE_PRIMITIVE		0x0
6060Sstevel@tonic-gate 
607*2139Sjp161948 #define ASN1_ITYPE_SEQUENCE		0x1
6080Sstevel@tonic-gate 
609*2139Sjp161948 #define ASN1_ITYPE_CHOICE		0x2
6100Sstevel@tonic-gate 
611*2139Sjp161948 #define ASN1_ITYPE_COMPAT		0x3
612*2139Sjp161948 
613*2139Sjp161948 #define ASN1_ITYPE_EXTERN		0x4
6140Sstevel@tonic-gate 
615*2139Sjp161948 #define ASN1_ITYPE_MSTRING		0x5
6160Sstevel@tonic-gate 
617*2139Sjp161948 #define ASN1_ITYPE_NDEF_SEQUENCE	0x6
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate /* Cache for ASN1 tag and length, so we
6200Sstevel@tonic-gate  * don't keep re-reading it for things
6210Sstevel@tonic-gate  * like CHOICE
6220Sstevel@tonic-gate  */
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate struct ASN1_TLC_st{
6250Sstevel@tonic-gate 	char valid;	/* Values below are valid */
6260Sstevel@tonic-gate 	int ret;	/* return value */
6270Sstevel@tonic-gate 	long plen;	/* length */
6280Sstevel@tonic-gate 	int ptag;	/* class value */
6290Sstevel@tonic-gate 	int pclass;	/* class value */
6300Sstevel@tonic-gate 	int hdrlen;	/* header length */
6310Sstevel@tonic-gate };
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate /* Typedefs for ASN1 function pointers */
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate typedef ASN1_VALUE * ASN1_new_func(void);
6360Sstevel@tonic-gate typedef void ASN1_free_func(ASN1_VALUE *a);
637*2139Sjp161948 typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
6380Sstevel@tonic-gate typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
6390Sstevel@tonic-gate 
640*2139Sjp161948 typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
6410Sstevel@tonic-gate 					int tag, int aclass, char opt, ASN1_TLC *ctx);
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
6440Sstevel@tonic-gate typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
6450Sstevel@tonic-gate typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
648*2139Sjp161948 typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate typedef struct ASN1_COMPAT_FUNCS_st {
6510Sstevel@tonic-gate 	ASN1_new_func *asn1_new;
6520Sstevel@tonic-gate 	ASN1_free_func *asn1_free;
6530Sstevel@tonic-gate 	ASN1_d2i_func *asn1_d2i;
6540Sstevel@tonic-gate 	ASN1_i2d_func *asn1_i2d;
6550Sstevel@tonic-gate } ASN1_COMPAT_FUNCS;
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate typedef struct ASN1_EXTERN_FUNCS_st {
6580Sstevel@tonic-gate 	void *app_data;
6590Sstevel@tonic-gate 	ASN1_ex_new_func *asn1_ex_new;
6600Sstevel@tonic-gate 	ASN1_ex_free_func *asn1_ex_free;
6610Sstevel@tonic-gate 	ASN1_ex_free_func *asn1_ex_clear;
6620Sstevel@tonic-gate 	ASN1_ex_d2i *asn1_ex_d2i;
6630Sstevel@tonic-gate 	ASN1_ex_i2d *asn1_ex_i2d;
6640Sstevel@tonic-gate } ASN1_EXTERN_FUNCS;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate typedef struct ASN1_PRIMITIVE_FUNCS_st {
6670Sstevel@tonic-gate 	void *app_data;
6680Sstevel@tonic-gate 	unsigned long flags;
6690Sstevel@tonic-gate 	ASN1_ex_new_func *prim_new;
6700Sstevel@tonic-gate 	ASN1_ex_free_func *prim_free;
6710Sstevel@tonic-gate 	ASN1_ex_free_func *prim_clear;
6720Sstevel@tonic-gate 	ASN1_primitive_c2i *prim_c2i;
6730Sstevel@tonic-gate 	ASN1_primitive_i2c *prim_i2c;
6740Sstevel@tonic-gate } ASN1_PRIMITIVE_FUNCS;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate /* This is the ASN1_AUX structure: it handles various
6770Sstevel@tonic-gate  * miscellaneous requirements. For example the use of
6780Sstevel@tonic-gate  * reference counts and an informational callback.
6790Sstevel@tonic-gate  *
6800Sstevel@tonic-gate  * The "informational callback" is called at various
6810Sstevel@tonic-gate  * points during the ASN1 encoding and decoding. It can
6820Sstevel@tonic-gate  * be used to provide minor customisation of the structures
6830Sstevel@tonic-gate  * used. This is most useful where the supplied routines
6840Sstevel@tonic-gate  * *almost* do the right thing but need some extra help
6850Sstevel@tonic-gate  * at a few points. If the callback returns zero then
6860Sstevel@tonic-gate  * it is assumed a fatal error has occurred and the
6870Sstevel@tonic-gate  * main operation should be abandoned.
6880Sstevel@tonic-gate  *
6890Sstevel@tonic-gate  * If major changes in the default behaviour are required
6900Sstevel@tonic-gate  * then an external type is more appropriate.
6910Sstevel@tonic-gate  */
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate typedef struct ASN1_AUX_st {
6960Sstevel@tonic-gate 	void *app_data;
6970Sstevel@tonic-gate 	int flags;
6980Sstevel@tonic-gate 	int ref_offset;		/* Offset of reference value */
6990Sstevel@tonic-gate 	int ref_lock;		/* Lock type to use */
7000Sstevel@tonic-gate 	ASN1_aux_cb *asn1_cb;
7010Sstevel@tonic-gate 	int enc_offset;		/* Offset of ASN1_ENCODING structure */
7020Sstevel@tonic-gate } ASN1_AUX;
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate /* Flags in ASN1_AUX */
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate /* Use a reference count */
7070Sstevel@tonic-gate #define ASN1_AFLG_REFCOUNT	1
7080Sstevel@tonic-gate /* Save the encoding of structure (useful for signatures) */
7090Sstevel@tonic-gate #define ASN1_AFLG_ENCODING	2
7100Sstevel@tonic-gate /* The Sequence length is invalid */
7110Sstevel@tonic-gate #define ASN1_AFLG_BROKEN	4
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate /* operation values for asn1_cb */
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate #define ASN1_OP_NEW_PRE		0
7160Sstevel@tonic-gate #define ASN1_OP_NEW_POST	1
7170Sstevel@tonic-gate #define ASN1_OP_FREE_PRE	2
7180Sstevel@tonic-gate #define ASN1_OP_FREE_POST	3
7190Sstevel@tonic-gate #define ASN1_OP_D2I_PRE		4
7200Sstevel@tonic-gate #define ASN1_OP_D2I_POST	5
7210Sstevel@tonic-gate #define ASN1_OP_I2D_PRE		6
7220Sstevel@tonic-gate #define ASN1_OP_I2D_POST	7
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate /* Macro to implement a primitive type */
7250Sstevel@tonic-gate #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
7260Sstevel@tonic-gate #define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
7270Sstevel@tonic-gate 				ASN1_ITEM_start(itname) \
7280Sstevel@tonic-gate 					ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
7290Sstevel@tonic-gate 				ASN1_ITEM_end(itname)
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate /* Macro to implement a multi string type */
7320Sstevel@tonic-gate #define IMPLEMENT_ASN1_MSTRING(itname, mask) \
7330Sstevel@tonic-gate 				ASN1_ITEM_start(itname) \
7340Sstevel@tonic-gate 					ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
7350Sstevel@tonic-gate 				ASN1_ITEM_end(itname)
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate /* Macro to implement an ASN1_ITEM in terms of old style funcs */
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate #define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
7400Sstevel@tonic-gate 
7410Sstevel@tonic-gate #define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
7420Sstevel@tonic-gate 	static const ASN1_COMPAT_FUNCS sname##_ff = { \
7430Sstevel@tonic-gate 		(ASN1_new_func *)sname##_new, \
7440Sstevel@tonic-gate 		(ASN1_free_func *)sname##_free, \
7450Sstevel@tonic-gate 		(ASN1_d2i_func *)d2i_##sname, \
7460Sstevel@tonic-gate 		(ASN1_i2d_func *)i2d_##sname, \
7470Sstevel@tonic-gate 	}; \
7480Sstevel@tonic-gate 	ASN1_ITEM_start(sname) \
7490Sstevel@tonic-gate 		ASN1_ITYPE_COMPAT, \
7500Sstevel@tonic-gate 		tag, \
7510Sstevel@tonic-gate 		NULL, \
7520Sstevel@tonic-gate 		0, \
7530Sstevel@tonic-gate 		&sname##_ff, \
7540Sstevel@tonic-gate 		0, \
7550Sstevel@tonic-gate 		#sname \
7560Sstevel@tonic-gate 	ASN1_ITEM_end(sname)
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate #define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
7590Sstevel@tonic-gate 	ASN1_ITEM_start(sname) \
7600Sstevel@tonic-gate 		ASN1_ITYPE_EXTERN, \
7610Sstevel@tonic-gate 		tag, \
7620Sstevel@tonic-gate 		NULL, \
7630Sstevel@tonic-gate 		0, \
7640Sstevel@tonic-gate 		&fptrs, \
7650Sstevel@tonic-gate 		0, \
7660Sstevel@tonic-gate 		#sname \
7670Sstevel@tonic-gate 	ASN1_ITEM_end(sname)
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate /* Macro to implement standard functions in terms of ASN1_ITEM structures */
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
7720Sstevel@tonic-gate 
7730Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
7760Sstevel@tonic-gate 			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
7770Sstevel@tonic-gate 
778*2139Sjp161948 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
779*2139Sjp161948 		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
780*2139Sjp161948 
7810Sstevel@tonic-gate #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
7820Sstevel@tonic-gate 	stname *fname##_new(void) \
7830Sstevel@tonic-gate 	{ \
7840Sstevel@tonic-gate 		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
7850Sstevel@tonic-gate 	} \
7860Sstevel@tonic-gate 	void fname##_free(stname *a) \
7870Sstevel@tonic-gate 	{ \
7880Sstevel@tonic-gate 		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
7890Sstevel@tonic-gate 	}
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
7920Sstevel@tonic-gate 	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
7930Sstevel@tonic-gate 	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
796*2139Sjp161948 	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
7970Sstevel@tonic-gate 	{ \
7980Sstevel@tonic-gate 		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
7990Sstevel@tonic-gate 	} \
8000Sstevel@tonic-gate 	int i2d_##fname(stname *a, unsigned char **out) \
8010Sstevel@tonic-gate 	{ \
8020Sstevel@tonic-gate 		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
8030Sstevel@tonic-gate 	}
8040Sstevel@tonic-gate 
805*2139Sjp161948 #define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
806*2139Sjp161948 	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
807*2139Sjp161948 	{ \
808*2139Sjp161948 		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
809*2139Sjp161948 	}
810*2139Sjp161948 
8110Sstevel@tonic-gate /* This includes evil casts to remove const: they will go away when full
8120Sstevel@tonic-gate  * ASN1 constification is done.
8130Sstevel@tonic-gate  */
8140Sstevel@tonic-gate #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
8150Sstevel@tonic-gate 	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
8160Sstevel@tonic-gate 	{ \
817*2139Sjp161948 		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
8180Sstevel@tonic-gate 	} \
8190Sstevel@tonic-gate 	int i2d_##fname(const stname *a, unsigned char **out) \
8200Sstevel@tonic-gate 	{ \
8210Sstevel@tonic-gate 		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
8220Sstevel@tonic-gate 	}
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate #define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
8250Sstevel@tonic-gate 	stname * stname##_dup(stname *x) \
8260Sstevel@tonic-gate         { \
8270Sstevel@tonic-gate         return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
8280Sstevel@tonic-gate         }
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
8310Sstevel@tonic-gate 		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate #define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
8340Sstevel@tonic-gate 	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
8350Sstevel@tonic-gate 	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
8360Sstevel@tonic-gate 
8370Sstevel@tonic-gate /* external definitions for primitive types */
8380Sstevel@tonic-gate 
8390Sstevel@tonic-gate DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
8400Sstevel@tonic-gate DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
8410Sstevel@tonic-gate DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
8420Sstevel@tonic-gate DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
8430Sstevel@tonic-gate DECLARE_ASN1_ITEM(CBIGNUM)
8440Sstevel@tonic-gate DECLARE_ASN1_ITEM(BIGNUM)
8450Sstevel@tonic-gate DECLARE_ASN1_ITEM(LONG)
8460Sstevel@tonic-gate DECLARE_ASN1_ITEM(ZLONG)
8470Sstevel@tonic-gate 
8480Sstevel@tonic-gate DECLARE_STACK_OF(ASN1_VALUE)
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate /* Functions used internally by the ASN1 code */
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
8530Sstevel@tonic-gate void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
8540Sstevel@tonic-gate int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
8550Sstevel@tonic-gate int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
858*2139Sjp161948 int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
859*2139Sjp161948 int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
8600Sstevel@tonic-gate 				int tag, int aclass, char opt, ASN1_TLC *ctx);
8610Sstevel@tonic-gate 
8620Sstevel@tonic-gate int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
8630Sstevel@tonic-gate int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
8640Sstevel@tonic-gate void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
867*2139Sjp161948 int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
8700Sstevel@tonic-gate int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
8750Sstevel@tonic-gate 
8760Sstevel@tonic-gate int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
8790Sstevel@tonic-gate void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
8800Sstevel@tonic-gate int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
881*2139Sjp161948 int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate #ifdef  __cplusplus
8840Sstevel@tonic-gate }
8850Sstevel@tonic-gate #endif
8860Sstevel@tonic-gate #endif
887