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
21 //TODO related to rdar://problem/24868013
22 typedef int ccder_tag
; //MSVC forces enums to be ints
24 typedef unsigned long ccder_tag
;
27 typedef uint8_t ccder_tag
;
30 /* DER types to be used with ccder_decode and ccder_encode functions. */
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
,
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
,
62 CCDER_BMP_STRING
= CCASN1_BMP_STRING
,
63 CCDER_HIGH_TAG_NUMBER
= CCASN1_HIGH_TAG_NUMBER
,
64 CCDER_TELETEX_STRING
= CCDER_T61_STRING
,
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))),
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)),
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)),
80 CCDER_TAG_MASK
= CCASN1_TAG_MASK
,
81 CCDER_TAGNUM_MASK
= CCASN1_TAGNUM_MASK
,
83 CCDER_METHOD_MASK
= CCASN1_METHOD_MASK
,
84 CCDER_PRIMITIVE
= CCASN1_PRIMITIVE
,
85 CCDER_CONSTRUCTED
= CCASN1_CONSTRUCTED
,
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
,
93 CCDER_CONSTRUCTED_SET
= CCDER_SET
| CCDER_CONSTRUCTED
,
94 CCDER_CONSTRUCTED_SEQUENCE
= CCDER_SEQUENCE
| CCDER_CONSTRUCTED
,
97 // MARK: ccder_sizeof_ functions
99 /* Returns the size of an asn1 encoded item of length l in bytes. */
101 size_t ccder_sizeof(ccder_tag tag
, size_t len
);
104 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag
,
105 cc_size n
, const cc_unit
*s
);
108 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag
,
109 cc_size n
, const cc_unit
*s
);
112 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag
,
115 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag
, uint64_t value
);
118 size_t ccder_sizeof_integer(cc_size n
, const cc_unit
*s
);
121 size_t ccder_sizeof_len(size_t len
);
124 size_t ccder_sizeof_octet_string(cc_size n
, const cc_unit
*s
);
127 size_t ccder_sizeof_oid(ccoid_t oid
);
130 size_t ccder_sizeof_raw_octet_string(size_t s_size
);
133 size_t ccder_sizeof_tag(ccder_tag tag
);
136 size_t ccder_sizeof_uint64(uint64_t value
);
138 // MARK: ccder_encode_ functions.
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. */
144 uint8_t *ccder_encode_tag(ccder_tag tag
, const uint8_t *der
, uint8_t *der_end
);
146 /* Returns a pointer to the start of the len field. returns NULL if there
147 is an encoding error. */
150 ccder_encode_len(size_t len
, const uint8_t *der
, uint8_t *der_end
);
152 /* der_end should point to the first byte of the content of this der item. */
155 ccder_encode_tl(ccder_tag tag
, size_t len
, const uint8_t *der
, uint8_t *der_end
);
159 ccder_encode_body_nocopy(size_t size
, const uint8_t *der
, uint8_t *der_end
);
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. */
167 ccder_encode_constructed_tl(ccder_tag tag
, const uint8_t *body_end
,
168 const uint8_t *der
, uint8_t *der_end
);
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
);
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
);
181 uint8_t *ccder_encode_integer(cc_size n
, const cc_unit
*s
,
182 const uint8_t *der
, uint8_t *der_end
);
185 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag
,
187 const uint8_t *der
, uint8_t *der_end
);
190 uint8_t *ccder_encode_uint64(uint64_t value
,
191 const uint8_t *der
, uint8_t *der_end
);
194 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag
,
195 cc_size n
, const cc_unit
*s
,
200 uint8_t *ccder_encode_octet_string(cc_size n
, const cc_unit
*s
,
201 const uint8_t *der
, uint8_t *der_end
);
204 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag
,
205 size_t s_size
, const uint8_t *s
,
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
);
213 size_t ccder_encode_eckey_size(size_t priv_size
, ccoid_t oid
, size_t pub_size
);
215 CC_NONNULL2 CC_NONNULL5 CC_NONNULL6 CC_NONNULL7
216 uint8_t *ccder_encode_eckey(size_t priv_size
, const uint8_t *priv_key
,
218 size_t pub_size
, const uint8_t *pub_key
,
219 uint8_t *der
, uint8_t *der_end
);
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 */
227 ccder_encode_body(size_t size
, const uint8_t* body
,
228 const uint8_t *der
, uint8_t *der_end
);
230 // MARK: ccder_decode_ functions.
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. */
235 const uint8_t *ccder_decode_tag(ccder_tag
*tagp
, const uint8_t *der
, const uint8_t *der_end
);
238 const uint8_t *ccder_decode_len(size_t *lenp
, const uint8_t *der
, const uint8_t *der_end
);
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. */
243 const uint8_t *ccder_decode_tl(ccder_tag expected_tag
, size_t *lenp
,
244 const uint8_t *der
, const uint8_t *der_end
);
248 ccder_decode_constructed_tl(ccder_tag expected_tag
, const uint8_t **body_end
,
249 const uint8_t *der
, const uint8_t *der_end
);
253 ccder_decode_sequence_tl(const uint8_t **body_end
,
254 const uint8_t *der
, const uint8_t *der_end
);
257 @function ccder_decode_uint_n
258 @abstract length in cc_unit of a der unsigned integer after skipping the leading zeroes
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
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
269 const uint8_t *ccder_decode_uint_n(cc_size
*n
,
270 const uint8_t *der
, const uint8_t *der_end
);
273 @function ccder_decode_uint
274 @abstract Represent in cc_unit a der unsigned integer after skipping the leading zeroes
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.
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
287 const uint8_t *ccder_decode_uint(cc_size n
, cc_unit
*r
,
288 const uint8_t *der
, const uint8_t *der_end
);
291 const uint8_t *ccder_decode_uint64(uint64_t* r
,
292 const uint8_t *der
, const uint8_t *der_end
);
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
);
305 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string
,
307 const uint8_t *der
, const uint8_t *der_end
);
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
,
313 size_t *pub_size
, const uint8_t **pub_key
,
314 const uint8_t *der
, const uint8_t *der_end
);
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")}
323 #endif /* _CORECRYPTO_CCDER_H_ */