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/************************************************************************/
22SEC_BEGIN_PROTOS
23
24/*
25 * XXX These function prototypes need full, explanatory comments.
26 */
27
28/*
29** Decoding.
30*/
31
32extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool,
33 void *dest,
34 const SEC_ASN1Template *t);
35
36/* XXX char or unsigned char? */
37extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
38 const char *buf,
39 unsigned long len);
40
41extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx);
42
43/* Higher level code detected an error, abort the rest of the processing */
44extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error);
45
46extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
47 SEC_ASN1WriteProc fn,
48 void *arg, PRBool no_store);
49
50extern void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx);
51
52extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
53 SEC_ASN1NotifyProc fn,
54 void *arg);
55
56extern void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx);
57
58extern 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
69extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
70 const SEC_ASN1Template *t,
71 const SECItem *src);
72
73extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
74 const SEC_ASN1Template* templateEntry,
75 const SECItem* src);
76
77/*
78** Encoding.
79*/
80
81extern 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? */
87extern SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
88 const char *buf,
89 unsigned long len);
90
91extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx);
92
93/* Higher level code detected an error, abort the rest of the processing */
94extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error);
95
96extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
97 SEC_ASN1NotifyProc fn,
98 void *arg);
99
100extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx);
101
102extern void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx);
103
104extern void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx);
105
106extern void sec_ASN1EncoderSetDER(SEC_ASN1EncoderContext *cx);
107
108extern void sec_ASN1EncoderClearDER(SEC_ASN1EncoderContext *cx);
109
110extern void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx);
111
112extern void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx);
113
114extern 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 */
124extern SECItem * SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest,
125 const void *src, const SEC_ASN1Template *t);
126
127extern SECItem * SEC_ASN1EncodeInteger(PLArenaPool *pool,
128 SECItem *dest, long value);
129
130extern SECItem * SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
131 SECItem *dest,
132 unsigned long value);
133
134extern 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 */
145extern 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 */
149extern 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 */
162extern const SEC_ASN1Template *
163SEC_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 */
169extern 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
184extern const SEC_ASN1Template SEC_AnyTemplate[];
185extern const SEC_ASN1Template SEC_BitStringTemplate[];
186extern const SEC_ASN1Template SEC_BMPStringTemplate[];
187extern const SEC_ASN1Template SEC_BooleanTemplate[];
188extern const SEC_ASN1Template SEC_EnumeratedTemplate[];
189extern const SEC_ASN1Template SEC_GeneralizedTimeTemplate[];
190extern const SEC_ASN1Template SEC_IA5StringTemplate[];
191extern const SEC_ASN1Template SEC_IntegerTemplate[];
192extern const SEC_ASN1Template SEC_NullTemplate[];
193extern const SEC_ASN1Template SEC_ObjectIDTemplate[];
194extern const SEC_ASN1Template SEC_OctetStringTemplate[];
195extern const SEC_ASN1Template SEC_PrintableStringTemplate[];
196extern const SEC_ASN1Template SEC_T61StringTemplate[];
197extern const SEC_ASN1Template SEC_UniversalStringTemplate[];
198extern const SEC_ASN1Template SEC_UTCTimeTemplate[];
199extern const SEC_ASN1Template SEC_UTF8StringTemplate[];
200extern const SEC_ASN1Template SEC_VisibleStringTemplate[];
201
202extern const SEC_ASN1Template SEC_PointerToAnyTemplate[];
203extern const SEC_ASN1Template SEC_PointerToBitStringTemplate[];
204extern const SEC_ASN1Template SEC_PointerToBMPStringTemplate[];
205extern const SEC_ASN1Template SEC_PointerToBooleanTemplate[];
206extern const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[];
207extern const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[];
208extern const SEC_ASN1Template SEC_PointerToIA5StringTemplate[];
209extern const SEC_ASN1Template SEC_PointerToIntegerTemplate[];
210extern const SEC_ASN1Template SEC_PointerToNullTemplate[];
211extern const SEC_ASN1Template SEC_PointerToObjectIDTemplate[];
212extern const SEC_ASN1Template SEC_PointerToOctetStringTemplate[];
213extern const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[];
214extern const SEC_ASN1Template SEC_PointerToT61StringTemplate[];
215extern const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[];
216extern const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[];
217extern const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[];
218extern const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[];
219
220extern const SEC_ASN1Template SEC_SequenceOfAnyTemplate[];
221extern const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[];
222extern const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[];
223extern const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[];
224extern const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[];
225extern const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[];
226extern const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[];
227extern const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[];
228extern const SEC_ASN1Template SEC_SequenceOfNullTemplate[];
229extern const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[];
230extern const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[];
231extern const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[];
232extern const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[];
233extern const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[];
234extern const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[];
235extern const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[];
236extern const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[];
237
238extern const SEC_ASN1Template SEC_SetOfAnyTemplate[];
239extern const SEC_ASN1Template SEC_SetOfBitStringTemplate[];
240extern const SEC_ASN1Template SEC_SetOfBMPStringTemplate[];
241extern const SEC_ASN1Template SEC_SetOfBooleanTemplate[];
242extern const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[];
243extern const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[];
244extern const SEC_ASN1Template SEC_SetOfIA5StringTemplate[];
245extern const SEC_ASN1Template SEC_SetOfIntegerTemplate[];
246extern const SEC_ASN1Template SEC_SetOfNullTemplate[];
247extern const SEC_ASN1Template SEC_SetOfObjectIDTemplate[];
248extern const SEC_ASN1Template SEC_SetOfOctetStringTemplate[];
249extern const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[];
250extern const SEC_ASN1Template SEC_SetOfT61StringTemplate[];
251extern const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[];
252extern const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[];
253extern const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[];
254extern const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[];
255
256/*
257 * Template for skipping a subitem; this only makes sense when decoding.
258 */
259extern 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*/
264SEC_ASN1_CHOOSER_DECLARE(SEC_AnyTemplate)
265SEC_ASN1_CHOOSER_DECLARE(SEC_BMPStringTemplate)
266SEC_ASN1_CHOOSER_DECLARE(SEC_BooleanTemplate)
267SEC_ASN1_CHOOSER_DECLARE(SEC_BitStringTemplate)
268SEC_ASN1_CHOOSER_DECLARE(SEC_GeneralizedTimeTemplate)
269SEC_ASN1_CHOOSER_DECLARE(SEC_IA5StringTemplate)
270SEC_ASN1_CHOOSER_DECLARE(SEC_IntegerTemplate)
271SEC_ASN1_CHOOSER_DECLARE(SEC_NullTemplate)
272SEC_ASN1_CHOOSER_DECLARE(SEC_ObjectIDTemplate)
273SEC_ASN1_CHOOSER_DECLARE(SEC_OctetStringTemplate)
274SEC_ASN1_CHOOSER_DECLARE(SEC_UTCTimeTemplate)
275SEC_ASN1_CHOOSER_DECLARE(SEC_UTF8StringTemplate)
276
277SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToAnyTemplate)
278SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToOctetStringTemplate)
279
280SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate)
281
282SEC_ASN1_CHOOSER_DECLARE(SEC_EnumeratedTemplate)
283SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToEnumeratedTemplate)
284SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfAnyTemplate)
285SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfObjectIDTemplate)
286SEC_ASN1_CHOOSER_DECLARE(SEC_SkipTemplate)
287SEC_ASN1_CHOOSER_DECLARE(SEC_UniversalStringTemplate)
288SEC_ASN1_CHOOSER_DECLARE(SEC_PrintableStringTemplate)
289SEC_ASN1_CHOOSER_DECLARE(SEC_T61StringTemplate)
290SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToGeneralizedTimeTemplate)
291SEC_END_PROTOS
292#endif /* _SECASN1_H_ */
293