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