]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/libDER/libDER/DER_Decode.h
048739fa0e62d5d557df9ea2f85c56b165990657
[apple/security.git] / OSX / libsecurity_keychain / libDER / libDER / DER_Decode.h
1 /*
2 * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * DER_Decode.h - DER decoding routines
26 */
27
28 #ifndef _DER_DECODE_H_
29 #define _DER_DECODE_H_
30
31 #include <libDER/libDER.h>
32 #include <stdbool.h>
33
34 __BEGIN_DECLS
35
36 /*
37 * Decoding one item consists of extracting its tag, a pointer
38 * to the actual content, and the length of the content. Those
39 * three are represented by a DERDecodedInfo.
40 */
41 typedef struct {
42 DERTag tag;
43 DERItem content;
44 } DERDecodedInfo;
45
46 /*
47 * Basic decoding primitive. Only works with:
48 *
49 * -- definite length encoding
50 * -- one-byte tags
51 * -- max content length fits in a DERSize
52 *
53 * No malloc or copy of the contents is performed; the returned
54 * content->content.data is a pointer into the incoming der data.
55 */
56 DERReturn DERDecodeItem(
57 const DERItem *der, /* data to decode */
58 DERDecodedInfo *decoded); /* RETURNED */
59
60 /*
61 * Basic decoding primitive. Allows for decoding with a partial buffer.
62 * if allowPartialBuffer is true. A partial buffer would normally fail
63 * because the encoded length would be greater than the size of the buffer passed in.
64 * Only works with:
65 *
66 * -- definite length encoding
67 * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined)
68 * -- max content length fits in a DERSize
69 *
70 * No malloc or copy of the contents is performed; the returned
71 * content->content.data is a pointer into the incoming der data.
72 */
73 DERReturn DERDecodeItemPartialBuffer(
74 const DERItem *der, /* data to decode */
75 DERDecodedInfo *decoded, /* RETURNED */
76 bool allowPartialBuffer);
77
78 /*
79 * Given a BIT_STRING, in the form of its raw content bytes,
80 * obtain the number of unused bits and the raw bit string bytes.
81 */
82 DERReturn DERParseBitString(
83 const DERItem *contents,
84 DERItem *bitStringBytes, /* RETURNED */
85 DERByte *numUnusedBits); /* RETURNED */
86
87 /*
88 * Given a BOOLEAN, in the form of its raw content bytes,
89 * obtain it's value.
90 */
91 DERReturn DERParseBoolean(
92 const DERItem *contents,
93 bool *value); /* RETURNED */
94
95 DERReturn DERParseBooleanWithDefault(
96 const DERItem *contents,
97 bool defaultValue,
98 bool *value); /* RETURNED */
99 /*
100 * Given a positive INTEGER, in the form of its raw content bytes,
101 * obtain it's value as a 32 bit or 64 bit quantity.
102 * Returns DR_BufOverflow if the value is too large to fit in the return type
103 */
104
105 DERReturn DERParseInteger(
106 const DERItem *contents,
107 uint32_t *value); /* RETURNED */
108
109 DERReturn DERParseInteger64(
110 const DERItem *contents,
111 uint64_t *value); /* RETURNED */
112
113 /*
114 * Sequence/set decode support.
115 */
116
117 /* state representing a sequence or set being decoded */
118 typedef struct {
119 DERByte *nextItem;
120 DERByte *end;
121 } DERSequence;
122
123 /*
124 * To decode a set or sequence, call DERDecodeSeqInit or
125 * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to
126 * get each enclosed item.
127 *
128 * DERDecodeSeqNext returns DR_EndOfSequence when no more
129 * items are available.
130 */
131
132 /*
133 * Use this to parse the top level sequence's tag and content length.
134 */
135 DERReturn DERDecodeSeqInit(
136 const DERItem *der, /* data to decode */
137 DERTag *tag, /* RETURNED tag of sequence/set. This will be
138 * either ASN1_CONSTR_SEQUENCE or
139 * ASN1_CONSTR_SET. */
140 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */
141
142 /*
143 * Use this to start in on decoding a sequence's content, when
144 * the top-level tag and content have already been decoded.
145 */
146 DERReturn DERDecodeSeqContentInit(
147 const DERItem *content,
148 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */
149
150 /* obtain the next decoded item in a sequence or set */
151 DERReturn DERDecodeSeqNext(
152 DERSequence *derSeq,
153 DERDecodedInfo *decoded); /* RETURNED */
154
155 /*
156 * High level sequence decode.
157 */
158
159 /*
160 * Per-item decode options.
161 */
162
163 /* Explicit default, no options */
164 #define DER_DEC_NO_OPTS 0x0000
165
166 /* This item optional, can be skipped during decode */
167 #define DER_DEC_OPTIONAL 0x0001
168
169 /* Skip the tag check; accept anything. */
170 #define DER_DEC_ASN_ANY 0x0002
171
172 /* Skip item, no write to DERDecodedInfo (but tag check still performed) */
173 #define DER_DEC_SKIP 0x0004
174
175 /* Save full DER encoding in DERDecodedInfo, including tag and length. Normally
176 * only the content is saved. */
177 #define DER_DEC_SAVE_DER 0x0008
178
179 /*
180 * High level sequence parse, starting with top-level tag and content.
181 * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's
182 * OK, use DERParseSequenceContent().
183 *
184 * These never return DR_EndOfSequence - if an *unexpected* end of sequence
185 * occurs, return DR_IncompleteSeq.
186 *
187 * Results of the decoding of one item are placed in a DERItem whose address
188 * is the dest arg plus the offset value in the associated DERItemSpec.
189 *
190 * Items which are optional (DER_DEC_OPTIONAL) and which are not found,
191 * leave their associated DERDecodedInfos unmodified.
192 *
193 * Processing of a sequence ends on detection of any error or after the
194 * last DERItemSpec is processed.
195 *
196 * The sizeToZero argument, if nonzero, indicates the number of bytes
197 * starting at dest to zero before processing the sequence. This is
198 * generally desirable, particularly if there are any DER_DEC_OPTIONAL
199 * items in the sequence; skipped optional items are detected by the
200 * caller via a NULL DERDecodedInfo.content.data; if this hasn't been
201 * explicitly zeroed (generally, by passing a nonzero value of sizeToZero),
202 * skipped items can't be detected.
203 */
204 DERReturn DERParseSequence(
205 const DERItem *der,
206 DERShort numItems, /* size of itemSpecs[] */
207 const DERItemSpec *itemSpecs,
208 void *dest, /* DERDecodedInfo(s) here RETURNED */
209 DERSize sizeToZero); /* optional */
210
211 /* high level sequence parse, starting with sequence's content */
212 DERReturn DERParseSequenceContent(
213 const DERItem *content,
214 DERShort numItems, /* size of itemSpecs[] */
215 const DERItemSpec *itemSpecs,
216 void *dest, /* DERDecodedInfo(s) here RETURNED */
217 DERSize sizeToZero); /* optional */
218
219 __END_DECLS
220
221 #endif /* _DER_DECODE_H_ */
222