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_ */ |
293 | |