1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | |
5 | /* |
6 | * Support for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished |
7 | * Encoding Rules). The routines are found in and used extensively by the |
8 | * security library, but exported for other use. |
9 | */ |
10 | |
11 | #ifndef _SECASN1_H_ |
12 | #define _SECASN1_H_ |
13 | |
14 | #include "utilrename.h" |
15 | #include "plarena.h" |
16 | |
17 | #include "seccomon.h" |
18 | #include "secasn1t.h" |
19 | |
20 | /************************************************************************/ |
21 | SEC_BEGIN_PROTOS |
22 | |
23 | /* |
24 | * XXX These function prototypes need full, explanatory comments. |
25 | */ |
26 | |
27 | /* |
28 | ** Decoding. |
29 | */ |
30 | |
31 | extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool, |
32 | void *dest, |
33 | const SEC_ASN1Template *t); |
34 | |
35 | /* XXX char or unsigned char? */ |
36 | extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx, |
37 | const char *buf, |
38 | unsigned long len); |
39 | |
40 | extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx); |
41 | |
42 | /* Higher level code detected an error, abort the rest of the processing */ |
43 | extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error); |
44 | |
45 | extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx, |
46 | SEC_ASN1WriteProc fn, |
47 | void *arg, PRBool no_store); |
48 | |
49 | extern void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx); |
50 | |
51 | extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx, |
52 | SEC_ASN1NotifyProc fn, |
53 | void *arg); |
54 | |
55 | extern void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx); |
56 | |
57 | /* Sets the maximum size that should be allocated for a single ASN.1 |
58 | * element. Set to 0 to indicate there is no limit. |
59 | * |
60 | * Note: This does not set the maximum size overall that may be allocated |
61 | * while parsing, nor does it guarantee that the decoder won't allocate |
62 | * more than |max_size| while parsing an individual element; rather, it |
63 | * merely guarantees that any individual allocation for returned data |
64 | * should not exceed |max_size|. |
65 | */ |
66 | extern void SEC_ASN1DecoderSetMaximumElementSize(SEC_ASN1DecoderContext *cx, |
67 | unsigned long max_size); |
68 | |
69 | extern SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest, |
70 | const SEC_ASN1Template *t, |
71 | const char *buf, long len); |
72 | |
73 | /* Both classic ASN.1 and QuickDER have a feature that removes leading zeroes |
74 | out of SEC_ASN1_INTEGER if the caller sets siUnsignedInteger in the type |
75 | field of the target SECItem prior to calling the decoder. Otherwise, the |
76 | type field is ignored and untouched. For SECItem that are dynamically |
77 | allocated (from POINTER, SET OF, SEQUENCE OF) the decoder sets the type |
78 | field to siBuffer. */ |
79 | |
80 | extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest, |
81 | const SEC_ASN1Template *t, |
82 | const SECItem *src); |
83 | |
84 | extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool *arena, void *dest, |
85 | const SEC_ASN1Template *templateEntry, |
86 | const SECItem *src); |
87 | |
88 | /* |
89 | ** Encoding. |
90 | */ |
91 | |
92 | extern SEC_ASN1EncoderContext *SEC_ASN1EncoderStart(const void *src, |
93 | const SEC_ASN1Template *t, |
94 | SEC_ASN1WriteProc fn, |
95 | void *output_arg); |
96 | |
97 | /* XXX char or unsigned char? */ |
98 | extern SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx, |
99 | const char *buf, |
100 | unsigned long len); |
101 | |
102 | extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx); |
103 | |
104 | /* Higher level code detected an error, abort the rest of the processing */ |
105 | extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error); |
106 | |
107 | extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx, |
108 | SEC_ASN1NotifyProc fn, |
109 | void *arg); |
110 | |
111 | extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx); |
112 | |
113 | extern void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx); |
114 | |
115 | extern void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx); |
116 | |
117 | extern void sec_ASN1EncoderSetDER(SEC_ASN1EncoderContext *cx); |
118 | |
119 | extern void sec_ASN1EncoderClearDER(SEC_ASN1EncoderContext *cx); |
120 | |
121 | extern void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx); |
122 | |
123 | extern void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx); |
124 | |
125 | extern SECStatus SEC_ASN1Encode(const void *src, const SEC_ASN1Template *t, |
126 | SEC_ASN1WriteProc output_proc, |
127 | void *output_arg); |
128 | |
129 | /* |
130 | * If both pool and dest are NULL, the caller should free the returned SECItem |
131 | * with a SECITEM_FreeItem(..., PR_TRUE) call. If pool is NULL but dest is |
132 | * not NULL, the caller should free the data buffer pointed to by dest with a |
133 | * SECITEM_FreeItem(dest, PR_FALSE) or PORT_Free(dest->data) call. |
134 | */ |
135 | extern SECItem *SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest, |
136 | const void *src, const SEC_ASN1Template *t); |
137 | |
138 | extern SECItem *SEC_ASN1EncodeInteger(PLArenaPool *pool, |
139 | SECItem *dest, long value); |
140 | |
141 | extern SECItem *SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool, |
142 | SECItem *dest, |
143 | unsigned long value); |
144 | |
145 | extern SECStatus SEC_ASN1DecodeInteger(SECItem *src, |
146 | unsigned long *value); |
147 | |
148 | /* |
149 | ** Utilities. |
150 | */ |
151 | |
152 | /* |
153 | * We have a length that needs to be encoded; how many bytes will the |
154 | * encoding take? |
155 | */ |
156 | extern int SEC_ASN1LengthLength(unsigned long len); |
157 | |
158 | /* encode the length and return the number of bytes we encoded. Buffer |
159 | * must be pre allocated */ |
160 | extern int SEC_ASN1EncodeLength(unsigned char *buf, int value); |
161 | |
162 | /* |
163 | * Find the appropriate subtemplate for the given template. |
164 | * This may involve calling a "chooser" function, or it may just |
165 | * be right there. In either case, it is expected to *have* a |
166 | * subtemplate; this is asserted in debug builds (in non-debug |
167 | * builds, NULL will be returned). |
168 | * |
169 | * "thing" is a pointer to the structure being encoded/decoded |
170 | * "encoding", when true, means that we are in the process of encoding |
171 | * (as opposed to in the process of decoding) |
172 | */ |
173 | extern const SEC_ASN1Template * |
174 | SEC_ASN1GetSubtemplate(const SEC_ASN1Template *inTemplate, void *thing, |
175 | PRBool encoding); |
176 | |
177 | /* whether the template is for a primitive type or a choice of |
178 | * primitive types |
179 | */ |
180 | extern PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate); |
181 | |
182 | /************************************************************************/ |
183 | |
184 | /* |
185 | * Generic Templates |
186 | * One for each of the simple types, plus a special one for ANY, plus: |
187 | * - a pointer to each one of those |
188 | * - a set of each one of those |
189 | * - a sequence of each one of those |
190 | * |
191 | * Note that these are alphabetical (case insensitive); please add new |
192 | * ones in the appropriate place. |
193 | */ |
194 | |
195 | extern const SEC_ASN1Template SEC_AnyTemplate[]; |
196 | extern const SEC_ASN1Template SEC_BitStringTemplate[]; |
197 | extern const SEC_ASN1Template SEC_BMPStringTemplate[]; |
198 | extern const SEC_ASN1Template SEC_BooleanTemplate[]; |
199 | extern const SEC_ASN1Template SEC_EnumeratedTemplate[]; |
200 | extern const SEC_ASN1Template SEC_GeneralizedTimeTemplate[]; |
201 | extern const SEC_ASN1Template SEC_IA5StringTemplate[]; |
202 | extern const SEC_ASN1Template SEC_IntegerTemplate[]; |
203 | extern const SEC_ASN1Template SEC_NullTemplate[]; |
204 | extern const SEC_ASN1Template SEC_ObjectIDTemplate[]; |
205 | extern const SEC_ASN1Template SEC_OctetStringTemplate[]; |
206 | extern const SEC_ASN1Template SEC_PrintableStringTemplate[]; |
207 | extern const SEC_ASN1Template SEC_T61StringTemplate[]; |
208 | extern const SEC_ASN1Template SEC_UniversalStringTemplate[]; |
209 | extern const SEC_ASN1Template SEC_UTCTimeTemplate[]; |
210 | extern const SEC_ASN1Template SEC_UTF8StringTemplate[]; |
211 | extern const SEC_ASN1Template SEC_VisibleStringTemplate[]; |
212 | |
213 | extern const SEC_ASN1Template SEC_PointerToAnyTemplate[]; |
214 | extern const SEC_ASN1Template SEC_PointerToBitStringTemplate[]; |
215 | extern const SEC_ASN1Template SEC_PointerToBMPStringTemplate[]; |
216 | extern const SEC_ASN1Template SEC_PointerToBooleanTemplate[]; |
217 | extern const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[]; |
218 | extern const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[]; |
219 | extern const SEC_ASN1Template SEC_PointerToIA5StringTemplate[]; |
220 | extern const SEC_ASN1Template SEC_PointerToIntegerTemplate[]; |
221 | extern const SEC_ASN1Template SEC_PointerToNullTemplate[]; |
222 | extern const SEC_ASN1Template SEC_PointerToObjectIDTemplate[]; |
223 | extern const SEC_ASN1Template SEC_PointerToOctetStringTemplate[]; |
224 | extern const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[]; |
225 | extern const SEC_ASN1Template SEC_PointerToT61StringTemplate[]; |
226 | extern const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[]; |
227 | extern const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[]; |
228 | extern const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[]; |
229 | extern const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[]; |
230 | |
231 | extern const SEC_ASN1Template SEC_SequenceOfAnyTemplate[]; |
232 | extern const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[]; |
233 | extern const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[]; |
234 | extern const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[]; |
235 | extern const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[]; |
236 | extern const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[]; |
237 | extern const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[]; |
238 | extern const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[]; |
239 | extern const SEC_ASN1Template SEC_SequenceOfNullTemplate[]; |
240 | extern const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[]; |
241 | extern const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[]; |
242 | extern const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[]; |
243 | extern const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[]; |
244 | extern const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[]; |
245 | extern const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[]; |
246 | extern const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[]; |
247 | extern const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[]; |
248 | |
249 | extern const SEC_ASN1Template SEC_SetOfAnyTemplate[]; |
250 | extern const SEC_ASN1Template SEC_SetOfBitStringTemplate[]; |
251 | extern const SEC_ASN1Template SEC_SetOfBMPStringTemplate[]; |
252 | extern const SEC_ASN1Template SEC_SetOfBooleanTemplate[]; |
253 | extern const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[]; |
254 | extern const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[]; |
255 | extern const SEC_ASN1Template SEC_SetOfIA5StringTemplate[]; |
256 | extern const SEC_ASN1Template SEC_SetOfIntegerTemplate[]; |
257 | extern const SEC_ASN1Template SEC_SetOfNullTemplate[]; |
258 | extern const SEC_ASN1Template SEC_SetOfObjectIDTemplate[]; |
259 | extern const SEC_ASN1Template SEC_SetOfOctetStringTemplate[]; |
260 | extern const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[]; |
261 | extern const SEC_ASN1Template SEC_SetOfT61StringTemplate[]; |
262 | extern const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[]; |
263 | extern const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[]; |
264 | extern const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[]; |
265 | extern const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[]; |
266 | |
267 | /* |
268 | * Template for skipping a subitem; this only makes sense when decoding. |
269 | */ |
270 | extern const SEC_ASN1Template SEC_SkipTemplate[]; |
271 | |
272 | /* These functions simply return the address of the above-declared templates. |
273 | ** This is necessary for Windows DLLs. Sigh. |
274 | */ |
275 | SEC_ASN1_CHOOSER_DECLARE(SEC_AnyTemplate) |
276 | SEC_ASN1_CHOOSER_DECLARE(SEC_BMPStringTemplate) |
277 | SEC_ASN1_CHOOSER_DECLARE(SEC_BooleanTemplate) |
278 | SEC_ASN1_CHOOSER_DECLARE(SEC_BitStringTemplate) |
279 | SEC_ASN1_CHOOSER_DECLARE(SEC_GeneralizedTimeTemplate) |
280 | SEC_ASN1_CHOOSER_DECLARE(SEC_IA5StringTemplate) |
281 | SEC_ASN1_CHOOSER_DECLARE(SEC_IntegerTemplate) |
282 | SEC_ASN1_CHOOSER_DECLARE(SEC_NullTemplate) |
283 | SEC_ASN1_CHOOSER_DECLARE(SEC_ObjectIDTemplate) |
284 | SEC_ASN1_CHOOSER_DECLARE(SEC_OctetStringTemplate) |
285 | SEC_ASN1_CHOOSER_DECLARE(SEC_UTCTimeTemplate) |
286 | SEC_ASN1_CHOOSER_DECLARE(SEC_UTF8StringTemplate) |
287 | |
288 | SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToAnyTemplate) |
289 | SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToOctetStringTemplate) |
290 | |
291 | SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate) |
292 | |
293 | SEC_ASN1_CHOOSER_DECLARE(SEC_EnumeratedTemplate) |
294 | SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToEnumeratedTemplate) |
295 | SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfAnyTemplate) |
296 | SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfObjectIDTemplate) |
297 | SEC_ASN1_CHOOSER_DECLARE(SEC_SkipTemplate) |
298 | SEC_ASN1_CHOOSER_DECLARE(SEC_UniversalStringTemplate) |
299 | SEC_ASN1_CHOOSER_DECLARE(SEC_PrintableStringTemplate) |
300 | SEC_ASN1_CHOOSER_DECLARE(SEC_T61StringTemplate) |
301 | SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToGeneralizedTimeTemplate) |
302 | SEC_END_PROTOS |
303 | #endif /* _SECASN1_H_ */ |
304 | |