]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/libDER/libDER/DER_Decode.h
827c2bcf0f0690af2bd702da78108af8d63544cb
[apple/security.git] / OSX / libsecurity_keychain / libDER / libDER / DER_Decode.h
1 /*
2 * Copyright (c) 2005-2011 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 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #include <libDER/libDER.h>
36 #include <stdbool.h>
37
38 /*
39 * Decoding one item consists of extracting its tag, a pointer
40 * to the actual content, and the length of the content. Those
41 * three are represented by a DERDecodedInfo.
42 */
43 typedef struct {
44 DERTag tag;
45 DERItem content;
46 } DERDecodedInfo;
47
48 /*
49 * Basic decoding primitive. Only works with:
50 *
51 * -- definite length encoding
52 * -- one-byte tags
53 * -- max content length fits in a DERSize
54 *
55 * No malloc or copy of the contents is performed; the returned
56 * content->content.data is a pointer into the incoming der data.
57 */
58 DERReturn DERDecodeItem(
59 const DERItem *der, /* data to decode */
60 DERDecodedInfo *decoded); /* RETURNED */
61
62 /*
63 * Given a BIT_STRING, in the form of its raw content bytes,
64 * obtain the number of unused bits and the raw bit string bytes.
65 */
66 DERReturn DERParseBitString(
67 const DERItem *contents,
68 DERItem *bitStringBytes, /* RETURNED */
69 DERByte *numUnusedBits); /* RETURNED */
70
71 /*
72 * Given a BOOLEAN, in the form of its raw content bytes,
73 * obtain it's value.
74 */
75 DERReturn DERParseBoolean(
76 const DERItem *contents,
77 bool defaultValue,
78 bool *value); /* RETURNED */
79
80 DERReturn DERParseInteger(
81 const DERItem *contents,
82 uint32_t *value); /* RETURNED */
83
84 /*
85 * Sequence/set decode support.
86 */
87
88 /* state representing a sequence or set being decoded */
89 typedef struct {
90 DERByte *nextItem;
91 DERByte *end;
92 } DERSequence;
93
94 /*
95 * To decode a set or sequence, call DERDecodeSeqInit or
96 * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to
97 * get each enclosed item.
98 *
99 * DERDecodeSeqNext returns DR_EndOfSequence when no more
100 * items are available.
101 */
102
103 /*
104 * Use this to parse the top level sequence's tag and content length.
105 */
106 DERReturn DERDecodeSeqInit(
107 const DERItem *der, /* data to decode */
108 DERTag *tag, /* RETURNED tag of sequence/set. This will be
109 * either ASN1_CONSTR_SEQUENCE or
110 * ASN1_CONSTR_SET. */
111 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */
112
113 /*
114 * Use this to start in on decoding a sequence's content, when
115 * the top-level tag and content have already been decoded.
116 */
117 DERReturn DERDecodeSeqContentInit(
118 const DERItem *content,
119 DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */
120
121 /* obtain the next decoded item in a sequence or set */
122 DERReturn DERDecodeSeqNext(
123 DERSequence *derSeq,
124 DERDecodedInfo *decoded); /* RETURNED */
125
126 /*
127 * High level sequence decode.
128 */
129
130 /*
131 * Per-item decode options.
132 */
133
134 /* Explicit default, no options */
135 #define DER_DEC_NO_OPTS 0x0000
136
137 /* This item optional, can be skipped during decode */
138 #define DER_DEC_OPTIONAL 0x0001
139
140 /* Skip the tag check; accept anything. */
141 #define DER_DEC_ASN_ANY 0x0002
142
143 /* Skip item, no write to DERDecodedInfo (but tag check still performed) */
144 #define DER_DEC_SKIP 0x0004
145
146 /* Save full DER encoding in DERDecodedInfo, including tag and length. Normally
147 * only the content is saved. */
148 #define DER_DEC_SAVE_DER 0x0008
149
150 /*
151 * High level sequence parse, starting with top-level tag and content.
152 * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's
153 * OK, use DERParseSequenceContent().
154 *
155 * These never return DR_EndOfSequence - if an *unexpected* end of sequence
156 * occurs, return DR_IncompleteSeq.
157 *
158 * Results of the decoding of one item are placed in a DERItem whose address
159 * is the dest arg plus the offset value in the associated DERItemSpec.
160 *
161 * Items which are optional (DER_DEC_OPTIONAL) and which are not found,
162 * leave their associated DERDecodedInfos unmodified.
163 *
164 * Processing of a sequence ends on detection of any error or after the
165 * last DERItemSpec is processed.
166 *
167 * The sizeToZero argument, if nonzero, indicates the number of bytes
168 * starting at dest to zero before processing the sequence. This is
169 * generally desirable, particularly if there are any DER_DEC_OPTIONAL
170 * items in the sequence; skipped optional items are detected by the
171 * caller via a NULL DERDecodedInfo.content.data; if this hasn't been
172 * explicitly zeroed (generally, by passing a nonzero value of sizeToZero),
173 * skipped items can't be detected.
174 */
175 DERReturn DERParseSequence(
176 const DERItem *der,
177 DERShort numItems, /* size of itemSpecs[] */
178 const DERItemSpec *itemSpecs,
179 void *dest, /* DERDecodedInfo(s) here RETURNED */
180 DERSize sizeToZero); /* optional */
181
182 /* high level sequence parse, starting with sequence's content */
183 DERReturn DERParseSequenceContent(
184 const DERItem *content,
185 DERShort numItems, /* size of itemSpecs[] */
186 const DERItemSpec *itemSpecs,
187 void *dest, /* DERDecodedInfo(s) here RETURNED */
188 DERSize sizeToZero); /* optional */
189
190 #ifdef __cplusplus
191 }
192 #endif
193
194 #endif /* _DER_DECODE_H_ */
195