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/************************************************************************/
21SEC_BEGIN_PROTOS
22
23/*
24 * XXX These function prototypes need full, explanatory comments.
25 */
26
27/*
28** Decoding.
29*/
30
31extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool,
32 void *dest,
33 const SEC_ASN1Template *t);
34
35/* XXX char or unsigned char? */
36extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
37 const char *buf,
38 unsigned long len);
39
40extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx);
41
42/* Higher level code detected an error, abort the rest of the processing */
43extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error);
44
45extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
46 SEC_ASN1WriteProc fn,
47 void *arg, PRBool no_store);
48
49extern void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx);
50
51extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
52 SEC_ASN1NotifyProc fn,
53 void *arg);
54
55extern 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*/
66extern void SEC_ASN1DecoderSetMaximumElementSize(SEC_ASN1DecoderContext *cx,
67 unsigned long max_size);
68
69extern 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
80extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
81 const SEC_ASN1Template *t,
82 const SECItem *src);
83
84extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool *arena, void *dest,
85 const SEC_ASN1Template *templateEntry,
86 const SECItem *src);
87
88/*
89** Encoding.
90*/
91
92extern 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? */
98extern SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
99 const char *buf,
100 unsigned long len);
101
102extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx);
103
104/* Higher level code detected an error, abort the rest of the processing */
105extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error);
106
107extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
108 SEC_ASN1NotifyProc fn,
109 void *arg);
110
111extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx);
112
113extern void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx);
114
115extern void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx);
116
117extern void sec_ASN1EncoderSetDER(SEC_ASN1EncoderContext *cx);
118
119extern void sec_ASN1EncoderClearDER(SEC_ASN1EncoderContext *cx);
120
121extern void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx);
122
123extern void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx);
124
125extern 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 */
135extern SECItem *SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest,
136 const void *src, const SEC_ASN1Template *t);
137
138extern SECItem *SEC_ASN1EncodeInteger(PLArenaPool *pool,
139 SECItem *dest, long value);
140
141extern SECItem *SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
142 SECItem *dest,
143 unsigned long value);
144
145extern 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 */
156extern 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 */
160extern 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 */
173extern const SEC_ASN1Template *
174SEC_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 */
180extern 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
195extern const SEC_ASN1Template SEC_AnyTemplate[];
196extern const SEC_ASN1Template SEC_BitStringTemplate[];
197extern const SEC_ASN1Template SEC_BMPStringTemplate[];
198extern const SEC_ASN1Template SEC_BooleanTemplate[];
199extern const SEC_ASN1Template SEC_EnumeratedTemplate[];
200extern const SEC_ASN1Template SEC_GeneralizedTimeTemplate[];
201extern const SEC_ASN1Template SEC_IA5StringTemplate[];
202extern const SEC_ASN1Template SEC_IntegerTemplate[];
203extern const SEC_ASN1Template SEC_NullTemplate[];
204extern const SEC_ASN1Template SEC_ObjectIDTemplate[];
205extern const SEC_ASN1Template SEC_OctetStringTemplate[];
206extern const SEC_ASN1Template SEC_PrintableStringTemplate[];
207extern const SEC_ASN1Template SEC_T61StringTemplate[];
208extern const SEC_ASN1Template SEC_UniversalStringTemplate[];
209extern const SEC_ASN1Template SEC_UTCTimeTemplate[];
210extern const SEC_ASN1Template SEC_UTF8StringTemplate[];
211extern const SEC_ASN1Template SEC_VisibleStringTemplate[];
212
213extern const SEC_ASN1Template SEC_PointerToAnyTemplate[];
214extern const SEC_ASN1Template SEC_PointerToBitStringTemplate[];
215extern const SEC_ASN1Template SEC_PointerToBMPStringTemplate[];
216extern const SEC_ASN1Template SEC_PointerToBooleanTemplate[];
217extern const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[];
218extern const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[];
219extern const SEC_ASN1Template SEC_PointerToIA5StringTemplate[];
220extern const SEC_ASN1Template SEC_PointerToIntegerTemplate[];
221extern const SEC_ASN1Template SEC_PointerToNullTemplate[];
222extern const SEC_ASN1Template SEC_PointerToObjectIDTemplate[];
223extern const SEC_ASN1Template SEC_PointerToOctetStringTemplate[];
224extern const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[];
225extern const SEC_ASN1Template SEC_PointerToT61StringTemplate[];
226extern const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[];
227extern const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[];
228extern const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[];
229extern const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[];
230
231extern const SEC_ASN1Template SEC_SequenceOfAnyTemplate[];
232extern const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[];
233extern const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[];
234extern const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[];
235extern const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[];
236extern const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[];
237extern const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[];
238extern const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[];
239extern const SEC_ASN1Template SEC_SequenceOfNullTemplate[];
240extern const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[];
241extern const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[];
242extern const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[];
243extern const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[];
244extern const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[];
245extern const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[];
246extern const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[];
247extern const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[];
248
249extern const SEC_ASN1Template SEC_SetOfAnyTemplate[];
250extern const SEC_ASN1Template SEC_SetOfBitStringTemplate[];
251extern const SEC_ASN1Template SEC_SetOfBMPStringTemplate[];
252extern const SEC_ASN1Template SEC_SetOfBooleanTemplate[];
253extern const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[];
254extern const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[];
255extern const SEC_ASN1Template SEC_SetOfIA5StringTemplate[];
256extern const SEC_ASN1Template SEC_SetOfIntegerTemplate[];
257extern const SEC_ASN1Template SEC_SetOfNullTemplate[];
258extern const SEC_ASN1Template SEC_SetOfObjectIDTemplate[];
259extern const SEC_ASN1Template SEC_SetOfOctetStringTemplate[];
260extern const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[];
261extern const SEC_ASN1Template SEC_SetOfT61StringTemplate[];
262extern const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[];
263extern const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[];
264extern const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[];
265extern const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[];
266
267/*
268 * Template for skipping a subitem; this only makes sense when decoding.
269 */
270extern 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*/
275SEC_ASN1_CHOOSER_DECLARE(SEC_AnyTemplate)
276SEC_ASN1_CHOOSER_DECLARE(SEC_BMPStringTemplate)
277SEC_ASN1_CHOOSER_DECLARE(SEC_BooleanTemplate)
278SEC_ASN1_CHOOSER_DECLARE(SEC_BitStringTemplate)
279SEC_ASN1_CHOOSER_DECLARE(SEC_GeneralizedTimeTemplate)
280SEC_ASN1_CHOOSER_DECLARE(SEC_IA5StringTemplate)
281SEC_ASN1_CHOOSER_DECLARE(SEC_IntegerTemplate)
282SEC_ASN1_CHOOSER_DECLARE(SEC_NullTemplate)
283SEC_ASN1_CHOOSER_DECLARE(SEC_ObjectIDTemplate)
284SEC_ASN1_CHOOSER_DECLARE(SEC_OctetStringTemplate)
285SEC_ASN1_CHOOSER_DECLARE(SEC_UTCTimeTemplate)
286SEC_ASN1_CHOOSER_DECLARE(SEC_UTF8StringTemplate)
287
288SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToAnyTemplate)
289SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToOctetStringTemplate)
290
291SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate)
292
293SEC_ASN1_CHOOSER_DECLARE(SEC_EnumeratedTemplate)
294SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToEnumeratedTemplate)
295SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfAnyTemplate)
296SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfObjectIDTemplate)
297SEC_ASN1_CHOOSER_DECLARE(SEC_SkipTemplate)
298SEC_ASN1_CHOOSER_DECLARE(SEC_UniversalStringTemplate)
299SEC_ASN1_CHOOSER_DECLARE(SEC_PrintableStringTemplate)
300SEC_ASN1_CHOOSER_DECLARE(SEC_T61StringTemplate)
301SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToGeneralizedTimeTemplate)
302SEC_END_PROTOS
303#endif /* _SECASN1_H_ */
304