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