]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccder.h
5 * Created on 03/14/2012
7 * Copyright (c) 2012,2013,2014,2015 Apple Inc. All rights reserved.
11 #ifndef _CORECRYPTO_CCDER_H_
12 #define _CORECRYPTO_CCDER_H_
14 #include <corecrypto/ccasn1.h>
15 #include <corecrypto/ccn.h>
17 #define CCDER_MULTIBYTE_TAGS 1
19 #ifdef CCDER_MULTIBYTE_TAGS
20 typedef unsigned long ccder_tag
;
22 typedef uint8_t ccder_tag
;
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
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
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
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)))
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))
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
77 #define CCDER_METHOD_MASK CCASN1_METHOD_MASK
78 #define CCDER_PRIMITIVE CCASN1_PRIMITIVE
79 #define CCDER_CONSTRUCTED CCASN1_CONSTRUCTED
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)
91 // MARK: ccder_sizeof_ functions
93 /* Returns the size of an asn1 encoded item of length l in bytes. */
95 size_t ccder_sizeof(ccder_tag tag
, size_t len
);
98 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag
,
99 cc_size n
, const cc_unit
*s
);
102 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag
,
103 cc_size n
, const cc_unit
*s
);
106 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag
,
109 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag
, uint64_t value
);
112 size_t ccder_sizeof_integer(cc_size n
, const cc_unit
*s
);
115 size_t ccder_sizeof_len(size_t len
);
118 size_t ccder_sizeof_octet_string(cc_size n
, const cc_unit
*s
);
121 size_t ccder_sizeof_oid(ccoid_t oid
);
124 size_t ccder_sizeof_raw_octet_string(size_t s_size
);
127 size_t ccder_sizeof_tag(ccder_tag tag
);
130 size_t ccder_sizeof_uint64(uint64_t value
);
132 // MARK: ccder_encode_ functions.
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. */
138 uint8_t *ccder_encode_tag(ccder_tag tag
, const uint8_t *der
, uint8_t *der_end
);
140 /* Returns a pointer to the start of the len field. returns NULL if there
141 is an encoding error. */
144 ccder_encode_len(size_t len
, const uint8_t *der
, uint8_t *der_end
);
146 /* der_end should point to the first byte of the content of this der item. */
149 ccder_encode_tl(ccder_tag tag
, size_t len
, const uint8_t *der
, uint8_t *der_end
);
151 CC_PURE
CC_NONNULL((2))
153 ccder_encode_body_nocopy(size_t size
, const uint8_t *der
, uint8_t *der_end
);
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. */
161 ccder_encode_constructed_tl(ccder_tag tag
, const uint8_t *body_end
,
162 const uint8_t *der
, uint8_t *der_end
);
164 /* Encodes oid into der and returns
165 der + ccder_sizeof_oid(oid). */
167 uint8_t *ccder_encode_oid(ccoid_t oid
, const uint8_t *der
, uint8_t *der_end
);
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
);
175 uint8_t *ccder_encode_integer(cc_size n
, const cc_unit
*s
,
176 const uint8_t *der
, uint8_t *der_end
);
179 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag
,
181 const uint8_t *der
, uint8_t *der_end
);
184 uint8_t *ccder_encode_uint64(uint64_t value
,
185 const uint8_t *der
, uint8_t *der_end
);
188 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag
,
189 cc_size n
, const cc_unit
*s
,
194 uint8_t *ccder_encode_octet_string(cc_size n
, const cc_unit
*s
,
195 const uint8_t *der
, uint8_t *der_end
);
198 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag
,
199 size_t s_size
, const uint8_t *s
,
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
);
207 size_t ccder_encode_eckey_size(size_t priv_size
, ccoid_t oid
, size_t pub_size
);
209 CC_NONNULL((2, 5, 6, 7))
210 uint8_t *ccder_encode_eckey(size_t priv_size
, const uint8_t *priv_key
,
212 size_t pub_size
, const uint8_t *pub_key
,
213 uint8_t *der
, uint8_t *der_end
);
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 */
221 ccder_encode_body(size_t size
, const uint8_t* body
,
222 const uint8_t *der
, uint8_t *der_end
);
224 // MARK: ccder_decode_ functions.
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. */
229 const uint8_t *ccder_decode_tag(ccder_tag
*tagp
, const uint8_t *der
, const uint8_t *der_end
);
232 const uint8_t *ccder_decode_len(size_t *lenp
, const uint8_t *der
, const uint8_t *der_end
);
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. */
237 const uint8_t *ccder_decode_tl(ccder_tag expected_tag
, size_t *lenp
,
238 const uint8_t *der
, const uint8_t *der_end
);
242 ccder_decode_constructed_tl(ccder_tag expected_tag
, const uint8_t **body_end
,
243 const uint8_t *der
, const uint8_t *der_end
);
247 ccder_decode_sequence_tl(const uint8_t **body_end
,
248 const uint8_t *der
, const uint8_t *der_end
);
251 @function ccder_decode_uint_n
252 @abstract length in cc_unit of a der unsigned integer after skipping the leading zeroes
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
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
263 const uint8_t *ccder_decode_uint_n(cc_size
*n
,
264 const uint8_t *der
, const uint8_t *der_end
);
267 @function ccder_decode_uint
268 @abstract Represent in cc_unit a der unsigned integer after skipping the leading zeroes
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.
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
281 const uint8_t *ccder_decode_uint(cc_size n
, cc_unit
*r
,
282 const uint8_t *der
, const uint8_t *der_end
);
285 const uint8_t *ccder_decode_uint64(uint64_t* r
,
286 const uint8_t *der
, const uint8_t *der_end
);
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
);
295 const uint8_t *ccder_decode_oid(ccoid_t
*oidp
,
296 const uint8_t *der
, const uint8_t *der_end
);
298 CC_NONNULL((1, 2, 4))
299 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string
,
301 const uint8_t *der
, const uint8_t *der_end
);
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
,
307 size_t *pub_size
, const uint8_t **pub_key
,
308 const uint8_t *der
, const uint8_t *der_end
);
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")}
317 #endif /* _CORECRYPTO_CCDER_H_ */