]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccder.h
xnu-3789.31.2.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccder.h
1 /*
2 * ccder.h
3 * corecrypto
4 *
5 * Created on 03/14/2012
6 *
7 * Copyright (c) 2012,2013,2014,2015 Apple Inc. All rights reserved.
8 *
9 */
10
11 #ifndef _CORECRYPTO_CCDER_H_
12 #define _CORECRYPTO_CCDER_H_
13
14 #include <corecrypto/ccasn1.h>
15 #include <corecrypto/ccn.h>
16
17 #define CCDER_MULTIBYTE_TAGS 1
18
19 #ifdef CCDER_MULTIBYTE_TAGS
20 #if defined(_MSC_VER)
21 //TODO related to rdar://problem/24868013
22 typedef int ccder_tag; //MSVC forces enums to be ints
23 #else
24 typedef unsigned long ccder_tag;
25 #endif
26 #else
27 typedef uint8_t ccder_tag;
28 #endif
29
30 /* DER types to be used with ccder_decode and ccder_encode functions. */
31 enum {
32 CCDER_EOL = CCASN1_EOL,
33 CCDER_BOOLEAN = CCASN1_BOOLEAN,
34 CCDER_INTEGER = CCASN1_INTEGER,
35 CCDER_BIT_STRING = CCASN1_BIT_STRING,
36 CCDER_OCTET_STRING = CCASN1_OCTET_STRING,
37 CCDER_NULL = CCASN1_NULL,
38 CCDER_OBJECT_IDENTIFIER = CCASN1_OBJECT_IDENTIFIER,
39 CCDER_OBJECT_DESCRIPTOR = CCASN1_OBJECT_DESCRIPTOR,
40 /* External or instance-of 0x08 */
41 CCDER_REAL = CCASN1_REAL,
42 CCDER_ENUMERATED = CCASN1_ENUMERATED,
43 CCDER_EMBEDDED_PDV = CCASN1_EMBEDDED_PDV,
44 CCDER_UTF8_STRING = CCASN1_UTF8_STRING,
45 /* 0x0d */
46 /* 0x0e */
47 /* 0x0f */
48 CCDER_SEQUENCE = CCASN1_SEQUENCE,
49 CCDER_SET = CCASN1_SET,
50 CCDER_NUMERIC_STRING = CCASN1_NUMERIC_STRING,
51 CCDER_PRINTABLE_STRING = CCASN1_PRINTABLE_STRING,
52 CCDER_T61_STRING = CCASN1_T61_STRING,
53 CCDER_VIDEOTEX_STRING = CCASN1_VIDEOTEX_STRING,
54 CCDER_IA5_STRING = CCASN1_IA5_STRING,
55 CCDER_UTC_TIME = CCASN1_UTC_TIME,
56 CCDER_GENERALIZED_TIME = CCASN1_GENERALIZED_TIME,
57 CCDER_GRAPHIC_STRING = CCASN1_GRAPHIC_STRING,
58 CCDER_VISIBLE_STRING = CCASN1_VISIBLE_STRING,
59 CCDER_GENERAL_STRING = CCASN1_GENERAL_STRING,
60 CCDER_UNIVERSAL_STRING = CCASN1_UNIVERSAL_STRING,
61 /* 0x1d */
62 CCDER_BMP_STRING = CCASN1_BMP_STRING,
63 CCDER_HIGH_TAG_NUMBER = CCASN1_HIGH_TAG_NUMBER,
64 CCDER_TELETEX_STRING = CCDER_T61_STRING,
65
66 #ifdef CCDER_MULTIBYTE_TAGS
67 CCDER_TAG_MASK = ((ccder_tag)~0),
68 CCDER_TAGNUM_MASK = ((ccder_tag)~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3))),
69
70 CCDER_METHOD_MASK = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
71 CCDER_PRIMITIVE = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3)),
72 CCDER_CONSTRUCTED = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
73
74 CCDER_CLASS_MASK = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
75 CCDER_UNIVERSAL = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2)),
76 CCDER_APPLICATION = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2)),
77 CCDER_CONTEXT_SPECIFIC = ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2)),
78 CCDER_PRIVATE = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
79 #else
80 CCDER_TAG_MASK = CCASN1_TAG_MASK,
81 CCDER_TAGNUM_MASK = CCASN1_TAGNUM_MASK,
82
83 CCDER_METHOD_MASK = CCASN1_METHOD_MASK,
84 CCDER_PRIMITIVE = CCASN1_PRIMITIVE,
85 CCDER_CONSTRUCTED = CCASN1_CONSTRUCTED,
86
87 CCDER_CLASS_MASK = CCASN1_CLASS_MASK,
88 CCDER_UNIVERSAL = CCASN1_UNIVERSAL,
89 CCDER_APPLICATION = CCASN1_APPLICATION,
90 CCDER_CONTEXT_SPECIFIC = CCASN1_CONTEXT_SPECIFIC,
91 CCDER_PRIVATE = CCASN1_PRIVATE,
92 #endif
93 CCDER_CONSTRUCTED_SET = CCDER_SET | CCDER_CONSTRUCTED,
94 CCDER_CONSTRUCTED_SEQUENCE = CCDER_SEQUENCE | CCDER_CONSTRUCTED,
95 };
96
97 // MARK: ccder_sizeof_ functions
98
99 /* Returns the size of an asn1 encoded item of length l in bytes. */
100 CC_CONST
101 size_t ccder_sizeof(ccder_tag tag, size_t len);
102
103 CC_PURE
104 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag,
105 cc_size n, const cc_unit *s);
106
107 CC_PURE
108 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag,
109 cc_size n, const cc_unit *s);
110
111 CC_CONST
112 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag,
113 size_t s_size);
114 CC_CONST
115 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
116
117 CC_PURE
118 size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
119
120 CC_CONST
121 size_t ccder_sizeof_len(size_t len);
122
123 CC_PURE
124 size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
125
126 CC_PURE
127 size_t ccder_sizeof_oid(ccoid_t oid);
128
129 CC_CONST
130 size_t ccder_sizeof_raw_octet_string(size_t s_size);
131
132 CC_CONST
133 size_t ccder_sizeof_tag(ccder_tag tag);
134
135 CC_CONST
136 size_t ccder_sizeof_uint64(uint64_t value);
137
138 // MARK: ccder_encode_ functions.
139
140 /* Encode a tag backwards, der_end should point to one byte past the end of
141 destination for the tag, returns a pointer to the first byte of the tag.
142 Returns NULL if there is an encoding error. */
143 CC_NONNULL2
144 uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
145
146 /* Returns a pointer to the start of the len field. returns NULL if there
147 is an encoding error. */
148 CC_NONNULL2
149 uint8_t *
150 ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
151
152 /* der_end should point to the first byte of the content of this der item. */
153 CC_NONNULL3
154 uint8_t *
155 ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
156
157 CC_PURE CC_NONNULL2
158 uint8_t *
159 ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
160
161 /* Encode the tag and length of a constructed object. der is the lower
162 bound, der_end is one byte paste where we want to write the length and
163 body_end is one byte past the end of the body of the der object we are
164 encoding the tag and length of. */
165 CC_NONNULL((2, 3))
166 uint8_t *
167 ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end,
168 const uint8_t *der, uint8_t *der_end);
169
170 /* Encodes oid into der and returns
171 der + ccder_sizeof_oid(oid). */
172 CC_NONNULL_TU((1)) CC_NONNULL2
173 uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
174
175 CC_NONNULL((3, 4))
176 uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag,
177 cc_size n, const cc_unit *s,
178 const uint8_t *der, uint8_t *der_end);
179
180 CC_NONNULL((2, 3))
181 uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s,
182 const uint8_t *der, uint8_t *der_end);
183
184 CC_NONNULL3
185 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag,
186 uint64_t value,
187 const uint8_t *der, uint8_t *der_end);
188
189 CC_NONNULL2
190 uint8_t *ccder_encode_uint64(uint64_t value,
191 const uint8_t *der, uint8_t *der_end);
192
193 CC_NONNULL((3, 4))
194 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag,
195 cc_size n, const cc_unit *s,
196 const uint8_t *der,
197 uint8_t *der_end);
198
199 CC_NONNULL((2, 3))
200 uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s,
201 const uint8_t *der, uint8_t *der_end);
202
203 CC_NONNULL((3, 4))
204 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
205 size_t s_size, const uint8_t *s,
206 const uint8_t *der,
207 uint8_t *der_end);
208
209 CC_NONNULL((2, 3))
210 uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s,
211 const uint8_t *der, uint8_t *der_end);
212
213 size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size);
214
215 CC_NONNULL2 CC_NONNULL5 CC_NONNULL6 CC_NONNULL7
216 uint8_t *ccder_encode_eckey(size_t priv_size, const uint8_t *priv_key,
217 ccoid_t oid,
218 size_t pub_size, const uint8_t *pub_key,
219 uint8_t *der, uint8_t *der_end);
220
221 /* ccder_encode_body COPIES the body into the der.
222 It's inefficient – especially when you already have to convert to get to
223 the form for the body.
224 see encode integer for the right way to unify conversion and insertion */
225 CC_NONNULL3
226 uint8_t *
227 ccder_encode_body(size_t size, const uint8_t* body,
228 const uint8_t *der, uint8_t *der_end);
229
230 // MARK: ccder_decode_ functions.
231
232 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
233 returns NULL if there is a decoding error. */
234 CC_NONNULL((1, 3))
235 const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
236
237 CC_NONNULL((1, 3))
238 const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
239
240 /* Returns a pointer to the start of the der object, and returns the length in len.
241 returns NULL if there is a decoding error. */
242 CC_NONNULL((2, 4))
243 const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp,
244 const uint8_t *der, const uint8_t *der_end);
245
246 CC_NONNULL((2, 4))
247 const uint8_t *
248 ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end,
249 const uint8_t *der, const uint8_t *der_end);
250
251 CC_NONNULL((1, 3))
252 const uint8_t *
253 ccder_decode_sequence_tl(const uint8_t **body_end,
254 const uint8_t *der, const uint8_t *der_end);
255
256 /*!
257 @function ccder_decode_uint_n
258 @abstract length in cc_unit of a der unsigned integer after skipping the leading zeroes
259
260 @param der Beginning of input DER buffer
261 @param der_end End of input DER buffer
262 @param n Output the number of cc_unit required to represent the number
263
264 @result First byte after the parsed integer or
265 NULL if the integer is not valid (negative) or reach der_end when reading the integer
266 */
267
268 CC_NONNULL((3))
269 const uint8_t *ccder_decode_uint_n(cc_size *n,
270 const uint8_t *der, const uint8_t *der_end);
271
272 /*!
273 @function ccder_decode_uint
274 @abstract Represent in cc_unit a der unsigned integer after skipping the leading zeroes
275
276 @param der Beginning of input DER buffer
277 @param der_end End of input DER buffer
278 @param n Number of cc_unit allocated for r
279 @param r Allocated array of cc_unit to copy the integer into.
280
281 @result First byte after the parsed integer or
282 NULL if the integer is not valid (negative)
283 reach der_end when reading the integer
284 n cc_unit is not enough to represent the integer
285 */
286 CC_NONNULL((4))
287 const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r,
288 const uint8_t *der, const uint8_t *der_end);
289
290 CC_NONNULL((3))
291 const uint8_t *ccder_decode_uint64(uint64_t* r,
292 const uint8_t *der, const uint8_t *der_end);
293
294 /* Decode SEQUENCE { r, s -- (unsigned)integer } in der into r and s.
295 Returns NULL on decode errors, returns pointer just past the end of the
296 sequence of integers otherwise. */
297 CC_NONNULL((2, 3, 5))
298 const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s,
299 const uint8_t *der, const uint8_t *der_end);
300 CC_NONNULL_TU((1)) CC_NONNULL((3))
301 const uint8_t *ccder_decode_oid(ccoid_t *oidp,
302 const uint8_t *der, const uint8_t *der_end);
303
304 CC_NONNULL((1,2,4))
305 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string,
306 size_t *bit_length,
307 const uint8_t *der, const uint8_t *der_end);
308
309 CC_NONNULL_TU((4)) CC_NONNULL((1,2,3,5,6,8))
310 const uint8_t *ccder_decode_eckey(uint64_t *version,
311 size_t *priv_size, const uint8_t **priv_key,
312 ccoid_t *oid,
313 size_t *pub_size, const uint8_t **pub_key,
314 const uint8_t *der, const uint8_t *der_end);
315
316 #define CC_EC_OID_SECP192R1 {((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x01")}
317 #define CC_EC_OID_SECP256R1 {((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07")}
318 #define CC_EC_OID_SECP224R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x21")}
319 #define CC_EC_OID_SECP384R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x22")}
320 #define CC_EC_OID_SECP521R1 {((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x23")}
321
322
323 #endif /* _CORECRYPTO_CCDER_H_ */