• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 
12 #ifndef GMSSL_ASN1_H
13 #define GMSSL_ASN1_H
14 
15 #include <time.h>
16 #include <stdlib.h>
17 #include <stdint.h>
18 
19 #if __cplusplus
20 extern "C" {
21 #endif
22 
23 
24 #define ASN1_TAG_UNIVERSAL		0x00
25 #define ASN1_TAG_APPLICATION		0x40
26 #define ASN1_TAG_CONTENT_SPECIFIC	0x80
27 #define ASN1_TAG_PRIVATE		0xC0
28 #define ASN1_TAG_PRIMITIVE		0x00
29 #define ASN1_TAG_CONSTRUCTED		0x20
30 
31 #define ASN1_TAG_IMPLICIT(index)	(ASN1_TAG_CONTENT_SPECIFIC|(index))
32 #define ASN1_TAG_EXPLICIT(index)	ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index))
33 
34 
35 #define ASN1_FMT_FULL	0x01
36 
37 
38 enum ASN1_TAG {
39 	ASN1_TAG_BOOLEAN		= 1,
40 	ASN1_TAG_INTEGER		= 2,
41 	ASN1_TAG_BIT_STRING		= 3,
42 	ASN1_TAG_OCTET_STRING		= 4,
43 	ASN1_TAG_NULL			= 5,
44 	ASN1_TAG_OBJECT_IDENTIFIER	= 6,
45 	ASN1_TAG_ObjectDescriptor	= 7,
46 	ASN1_TAG_EXTERNAL		= 8,
47 	ASN1_TAG_REAL			= 9,
48 	ASN1_TAG_ENUMERATED		= 10, // 0x0A
49 	ASN1_TAG_EMBEDDED		= 11, // 0x0B
50 	ASN1_TAG_UTF8String		= 12, // 0x0C
51 	ASN1_TAG_RELATIVE_OID		= 13, // 0x0D
52 	ASN1_TAG_NumericString		= 18, // 0x12
53 	ASN1_TAG_PrintableString	= 19, // 0x13, printable subset of ascii
54 	ASN1_TAG_TeletexString		= 20, // 0x14, T61String
55 	ASN1_TAG_VideotexString		= 21, // 0x15
56 	ASN1_TAG_IA5String		= 22, // 0x16, 7-bit ascii
57 	ASN1_TAG_UTCTime		= 23, // 0x17
58 	ASN1_TAG_GeneralizedTime	= 24, // 0x18
59 	ASN1_TAG_GraphicString		= 25, // 0x19
60 	ASN1_TAG_VisibleString		= 26, // 0x20
61 	ASN1_TAG_GeneralString		= 27, // 0x21
62 	ASN1_TAG_UniversalString	= 28, // 0x22
63 	ASN1_TAG_CHARACTER_STRING	= 29, // 0x23
64 	ASN1_TAG_BMPString		= 30, // 0x24, 2-byte unicode with zeros
65 	ASN1_TAG_SEQUENCE		= 0x30,
66 	ASN1_TAG_SET			= 0x31,
67 	ASN1_TAG_EXPLICIT		= 0xa0,
68 };
69 
70 const char *asn1_tag_name(int tag);
71 int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen);
72 int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen);
73 int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen);
74 int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen); // 尝试读取下一个tag,但是并不修改in,inlen
75 int asn1_tag_is_cstring(int tag);
76 int asn1_length_to_der(size_t dlen, uint8_t **out, size_t *outlen);
77 int asn1_length_from_der(size_t *dlen, const uint8_t **in, size_t *inlen);
78 int asn1_length_is_zero(size_t len);
79 int asn1_length_le(size_t len1, size_t len2); // less than
80 int asn1_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
81 int asn1_data_from_der(const uint8_t **d, size_t dlen, const uint8_t **in, size_t *inlen);
82 
83 int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
84 int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
85 int asn1_any_type_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
86 int asn1_any_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); // 调用方应保证a,alen为TLV
87 int asn1_any_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); // 该函数会检查输入是否为TLV
88 
89 const char *asn1_boolean_name(int val);
90 int asn1_boolean_from_name(int *val, const char *name);
91 int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen);
92 int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen);
93 #define asn1_boolean_to_der(val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,val,out,outlen)
94 #define asn1_boolean_from_der(val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,val,in,inlen)
95 #define asn1_implicit_boolean_to_der(i,val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
96 #define asn1_implicit_boolean_from_der(i,val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
97 
98 // asn1_integer_ 不支持负数编解码
99 int asn1_integer_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
100 int asn1_integer_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
101 #define asn1_integer_to_der(d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,d,dlen,out,outlen)
102 #define asn1_integer_from_der(d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,d,dlen,in,inlen)
103 #define asn1_implicit_integer_to_der(i,d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
104 #define asn1_implicit_integer_from_der(i,d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
105 
106 // asn1_int_ 只支持小的无符号整数的编解码,不支持负数
107 int asn1_int_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); // 当 val == -1 时,不输出,返回 0
108 int asn1_int_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); // 不支持负数,返回0时 *val 设置为 -1
109 #define asn1_int_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_INTEGER,val,out,outlen)
110 #define asn1_int_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_INTEGER,val,in,inlen)
111 #define asn1_implicit_int_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
112 #define asn1_implicit_int_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
113 
114 // 比特长度不必须为8的整数倍
115 int asn1_bit_string_to_der_ex(int tag, const uint8_t *d, size_t nbits, uint8_t **out, size_t *outlen);
116 int asn1_bit_string_from_der_ex(int tag, const uint8_t **d, size_t *nbits, const uint8_t **in, size_t *inlen);
117 #define asn1_bit_string_to_der(d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,d,nbits,out,outlen)
118 #define asn1_bit_string_from_der(d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,d,nbits,in,inlen)
119 #define asn1_implicit_bit_string_to_der(i,d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,out,outlen)
120 #define asn1_implicit_bit_string_from_der(i,d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,in,inlen)
121 
122 // 比特长度必须为8的整数倍,因此使用字节长度
123 int asn1_bit_octets_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
124 int asn1_bit_octets_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
125 #define asn1_bit_octets_to_der(d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen)
126 #define asn1_bit_octets_from_der(d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_BIT_STRING,d,dlen,in,inlen)
127 #define asn1_implicit_bit_octets_to_der(i,d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
128 #define asn1_implicit_bit_octets_from_der(i,d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
129 
130 // bits == -1 不编码,只支持较少的比特数量
131 int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen);
132 int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen);
133 #define asn1_bits_to_der(bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,bits,out,outlen)
134 #define asn1_bits_from_der(bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,bits,in,inlen)
135 #define asn1_implicit_bits_to_der(i,bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(i),bits,out,outlen)
136 #define asn1_implicit_bits_from_der(i,bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(i),bits,in,inlen)
137 // names[i]对应第i个比特
138 int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits);
139 
140 #define asn1_octet_string_to_der_ex(tag,d,dlen,out,outlen) asn1_type_to_der(tag,d,dlen,out,outlen)
141 #define asn1_octet_string_from_der_ex(tag,d,dlen,in,inlen) asn1_type_from_der(tag,d,dlen,in,inlen)
142 #define asn1_octet_string_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_OCTET_STRING,d,dlen,out,outlen)
143 #define asn1_octet_string_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_OCTET_STRING,d,dlen,in,inlen)
144 #define asn1_implicit_octet_string_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
145 #define asn1_implicit_octet_string_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
146 
147 const char *asn1_null_name(void);
148 int asn1_null_to_der(uint8_t **out, size_t *outlen);
149 int asn1_null_from_der(const uint8_t **in, size_t *inlen);
150 
151 #define ASN1_OID_MAX_NODES 32
152 int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen);
153 int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen);
154 
155 int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt);
156 int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen);
157 int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen);
158 #define asn1_object_identifier_to_der(nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,out,outlen)
159 #define asn1_object_identifier_from_der(nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,in,inlen)
160 #define asn1_implicit_object_identifier_to_der(i,nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,out,outlen)
161 #define asn1_implicit_object_identifier_from_der(i,nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,in,inlen)
162 int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label, const char *name,
163 	const uint32_t *nodes, size_t nodes_cnt);
164 
165 #define asn1_enumerated_to_der_ex(tag,val,out,outlen) asn1_int_to_der_ex(tag,val,out,outlen)
166 #define asn1_enumerated_from_der_ex(tag,val,in,inlen) asn1_int_from_der_ex(tag,val,in,inlen)
167 #define asn1_enumerated_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen)
168 #define asn1_enumerated_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_ENUMERATED,val,in,inlen)
169 #define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
170 #define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
171 
172 int asn1_utf8_string_check(const char *d, size_t dlen);
173 int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
174 int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
175 #define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen)
176 #define asn1_utf8_string_from_der(d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,d,dlen,in,inlen)
177 #define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
178 #define asn1_implicit_utf8_string_from_der(i,d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
179 
180 int asn1_printable_string_check(const char *d, size_t dlen);
181 int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
182 int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
183 #define asn1_printable_string_to_der(d,dlen,out,outlen)	asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,d,dlen,out,outlen)
184 #define asn1_printable_string_from_der(d,dlen,in,inlen)	asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,d,dlen,in,inlen)
185 #define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
186 #define asn1_implicit_printable_string_from_der(i,d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
187 
188 int asn1_ia5_string_check(const char *d, size_t dlen);
189 int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
190 int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
191 #define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen)
192 #define asn1_ia5_string_from_der(d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,d,dlen,in,inlen)
193 #define asn1_implicit_ia5_string_to_der(i,d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
194 #define asn1_implicit_ia5_string_from_der(i,d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
195 
196 int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
197 
198 #define ASN1_UTC_TIME_LEN		(sizeof("YYMMDDHHMMSSZ")-1)
199 #define ASN1_GENERALIZED_TIME_LEN	(sizeof("YYYYMMDDHHMMSSZ")-1)
200 
201 int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen);
202 int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen);
203 #define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen)
204 #define asn1_utc_time_from_der(tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,tv,in,inlen)
205 #define asn1_implicit_utc_time_to_der(i,tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
206 #define asn1_implicit_utc_time_from_der(i,tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
207 
208 int asn1_generalized_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen);
209 int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen);
210 #define asn1_generalized_time_to_der(tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,tv,out,outlen)
211 #define asn1_generalized_time_from_der(tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,tv,in,inlen)
212 #define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
213 #define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
214 
215 #define asn1_sequence_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen)
216 #define asn1_sequence_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen)
217 #define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
218 #define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
219 
220 #define asn1_set_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SET,d,dlen,out,outlen)
221 #define asn1_set_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SET,d,dlen,in,inlen)
222 #define asn1_implicit_set_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
223 #define asn1_implicit_set_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
224 
225 #define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
226 #define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
227 
228 int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen);
229 #define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
230 
231 #define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen)
232 
233 #define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen)
234 #define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
235 
236 #define asn1_set_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SET,dlen,out,outlen)
237 #define asn1_implicit_set_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
238 
239 #define asn1_explicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
240 
241 #define asn1_explicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
242 #define asn1_explicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
243 
244 // d,dlen 是 SEQUENCE OF, SET OF 中的值
245 int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt);
246 int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag,
247 	int index, const uint8_t **item_d, size_t *item_dlen);
248 
249 int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen);
250 int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen);
251 int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
252 
253 
254 typedef struct {
255 	int oid;
256 	char *name;
257 	uint32_t *nodes;
258 	size_t nodes_cnt;
259 	int flags;
260 	char *description;
261 } ASN1_OID_INFO;
262 
263 const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name);
264 const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid);
265 int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt,
266 	const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen);
267 int asn1_oid_info_from_der(const ASN1_OID_INFO **info,
268 	const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen);
269 
270 
271 int asn1_check(int expr);
272 
273 
274 #if __cplusplus
275 }
276 #endif
277 #endif
278