]>
Commit | Line | Data |
---|---|---|
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 | typedef unsigned long ccder_tag; | |
21 | #else | |
22 | typedef uint8_t ccder_tag; | |
23 | #endif | |
24 | ||
25 | /* DER types to be used with ccder_decode and ccder_encode functions. */ | |
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 | |
34 | /* External or instance-of 0x08 */ | |
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 | |
39 | /* 0x0d */ | |
40 | /* 0x0e */ | |
41 | /* 0x0f */ | |
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 | |
55 | /* 0x1d */ | |
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 | |
59 | ||
60 | #ifdef CCDER_MULTIBYTE_TAGS | |
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 | ||
90 | ||
91 | // MARK: ccder_sizeof_ functions | |
92 | ||
93 | /* Returns the size of an asn1 encoded item of length l in bytes. */ | |
94 | CC_CONST | |
95 | size_t ccder_sizeof(ccder_tag tag, size_t len); | |
96 | ||
97 | CC_PURE | |
98 | size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag, | |
99 | cc_size n, const cc_unit *s); | |
100 | ||
101 | CC_PURE | |
102 | size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag, | |
103 | cc_size n, const cc_unit *s); | |
104 | ||
105 | CC_CONST | |
106 | size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag, | |
107 | size_t s_size); | |
108 | CC_CONST | |
109 | size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value); | |
110 | ||
111 | CC_PURE | |
112 | size_t ccder_sizeof_integer(cc_size n, const cc_unit *s); | |
113 | ||
114 | CC_CONST | |
115 | size_t ccder_sizeof_len(size_t len); | |
116 | ||
117 | CC_PURE | |
118 | size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s); | |
119 | ||
120 | CC_PURE | |
121 | size_t ccder_sizeof_oid(ccoid_t oid); | |
122 | ||
123 | CC_CONST | |
124 | size_t ccder_sizeof_raw_octet_string(size_t s_size); | |
125 | ||
126 | CC_CONST | |
127 | size_t ccder_sizeof_tag(ccder_tag tag); | |
128 | ||
129 | CC_CONST | |
130 | size_t ccder_sizeof_uint64(uint64_t value); | |
131 | ||
132 | // MARK: ccder_encode_ functions. | |
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. */ | |
137 | CC_NONNULL((2)) | |
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. */ | |
142 | CC_NONNULL((2)) | |
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. */ | |
147 | CC_NONNULL((3)) | |
148 | uint8_t * | |
149 | ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end); | |
150 | ||
151 | CC_PURE CC_NONNULL((2)) | |
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. */ | |
159 | CC_NONNULL((2, 3)) | |
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). */ | |
166 | CC_NONNULL((1, 2)) | |
167 | uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end); | |
168 | ||
169 | CC_NONNULL((3, 4)) | |
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 | ||
174 | CC_NONNULL((2, 3)) | |
175 | uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s, | |
176 | const uint8_t *der, uint8_t *der_end); | |
177 | ||
178 | CC_NONNULL((3)) | |
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 | ||
183 | CC_NONNULL((2)) | |
184 | uint8_t *ccder_encode_uint64(uint64_t value, | |
185 | const uint8_t *der, uint8_t *der_end); | |
186 | ||
187 | CC_NONNULL((3, 4)) | |
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 | ||
193 | CC_NONNULL((2, 3)) | |
194 | uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s, | |
195 | const uint8_t *der, uint8_t *der_end); | |
196 | ||
197 | CC_NONNULL((3, 4)) | |
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 | ||
203 | CC_NONNULL((2, 3)) | |
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 | ||
207 | size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size); | |
208 | ||
209 | CC_NONNULL((2, 5, 6, 7)) | |
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 | ||
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 */ | |
219 | CC_NONNULL((3)) | |
220 | uint8_t * | |
221 | ccder_encode_body(size_t size, const uint8_t* body, | |
222 | const uint8_t *der, uint8_t *der_end); | |
223 | ||
224 | // MARK: ccder_decode_ functions. | |
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. */ | |
228 | CC_NONNULL((1, 3)) | |
229 | const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end); | |
230 | ||
231 | CC_NONNULL((1, 3)) | |
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. */ | |
236 | CC_NONNULL((2, 4)) | |
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 | ||
240 | CC_NONNULL((2, 4)) | |
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 | ||
245 | CC_NONNULL((1, 3)) | |
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 | ||
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)) | |
281 | const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r, | |
282 | const uint8_t *der, const uint8_t *der_end); | |
283 | ||
284 | CC_NONNULL((3)) | |
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. */ | |
291 | CC_NONNULL((2, 3, 5)) | |
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); | |
294 | CC_NONNULL((1, 3)) | |
295 | const uint8_t *ccder_decode_oid(ccoid_t *oidp, | |
296 | const uint8_t *der, const uint8_t *der_end); | |
297 | ||
298 | CC_NONNULL((1, 2, 4)) | |
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 | ||
303 | CC_NONNULL((1, 2, 3, 4, 5, 6, 8)) | |
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 | ||
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 | ||
316 | ||
317 | #endif /* _CORECRYPTO_CCDER_H_ */ |