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. */
27 CCDER_EOL
= CCASN1_EOL
,
28 CCDER_BOOLEAN
= CCASN1_BOOLEAN
,
29 CCDER_INTEGER
= CCASN1_INTEGER
,
30 CCDER_BIT_STRING
= CCASN1_BIT_STRING
,
31 CCDER_OCTET_STRING
= CCASN1_OCTET_STRING
,
32 CCDER_NULL
= CCASN1_NULL
,
33 CCDER_OBJECT_IDENTIFIER
= CCASN1_OBJECT_IDENTIFIER
,
34 CCDER_OBJECT_DESCRIPTOR
= CCASN1_OBJECT_DESCRIPTOR
,
35 /* External or instance-of 0x08 */
36 CCDER_REAL
= CCASN1_REAL
,
37 CCDER_ENUMERATED
= CCASN1_ENUMERATED
,
38 CCDER_EMBEDDED_PDV
= CCASN1_EMBEDDED_PDV
,
39 CCDER_UTF8_STRING
= CCASN1_UTF8_STRING
,
43 CCDER_SEQUENCE
= CCASN1_SEQUENCE
,
44 CCDER_SET
= CCASN1_SET
,
45 CCDER_NUMERIC_STRING
= CCASN1_NUMERIC_STRING
,
46 CCDER_PRINTABLE_STRING
= CCASN1_PRINTABLE_STRING
,
47 CCDER_T61_STRING
= CCASN1_T61_STRING
,
48 CCDER_VIDEOTEX_STRING
= CCASN1_VIDEOTEX_STRING
,
49 CCDER_IA5_STRING
= CCASN1_IA5_STRING
,
50 CCDER_UTC_TIME
= CCASN1_UTC_TIME
,
51 CCDER_GENERALIZED_TIME
= CCASN1_GENERALIZED_TIME
,
52 CCDER_GRAPHIC_STRING
= CCASN1_GRAPHIC_STRING
,
53 CCDER_VISIBLE_STRING
= CCASN1_VISIBLE_STRING
,
54 CCDER_GENERAL_STRING
= CCASN1_GENERAL_STRING
,
55 CCDER_UNIVERSAL_STRING
= CCASN1_UNIVERSAL_STRING
,
57 CCDER_BMP_STRING
= CCASN1_BMP_STRING
,
58 CCDER_HIGH_TAG_NUMBER
= CCASN1_HIGH_TAG_NUMBER
,
59 CCDER_TELETEX_STRING
= CCDER_T61_STRING
,
61 #ifdef CCDER_MULTIBYTE_TAGS
62 CCDER_TAG_MASK
= ((ccder_tag
)~0),
63 CCDER_TAGNUM_MASK
= ((ccder_tag
)~((ccder_tag
)7 << (sizeof(ccder_tag
) * 8 - 3))),
65 CCDER_METHOD_MASK
= ((ccder_tag
)1 << (sizeof(ccder_tag
) * 8 - 3)),
66 CCDER_PRIMITIVE
= ((ccder_tag
)0 << (sizeof(ccder_tag
) * 8 - 3)),
67 CCDER_CONSTRUCTED
= ((ccder_tag
)1 << (sizeof(ccder_tag
) * 8 - 3)),
69 CCDER_CLASS_MASK
= ((ccder_tag
)3 << (sizeof(ccder_tag
) * 8 - 2)),
70 CCDER_UNIVERSAL
= ((ccder_tag
)0 << (sizeof(ccder_tag
) * 8 - 2)),
71 CCDER_APPLICATION
= ((ccder_tag
)1 << (sizeof(ccder_tag
) * 8 - 2)),
72 CCDER_CONTEXT_SPECIFIC
= ((ccder_tag
)2 << (sizeof(ccder_tag
) * 8 - 2)),
73 CCDER_PRIVATE
= ((ccder_tag
)3 << (sizeof(ccder_tag
) * 8 - 2)),
75 CCDER_TAG_MASK
= CCASN1_TAG_MASK
,
76 CCDER_TAGNUM_MASK
= CCASN1_TAGNUM_MASK
,
78 CCDER_METHOD_MASK
= CCASN1_METHOD_MASK
,
79 CCDER_PRIMITIVE
= CCASN1_PRIMITIVE
,
80 CCDER_CONSTRUCTED
= CCASN1_CONSTRUCTED
,
82 CCDER_CLASS_MASK
= CCASN1_CLASS_MASK
,
83 CCDER_UNIVERSAL
= CCASN1_UNIVERSAL
,
84 CCDER_APPLICATION
= CCASN1_APPLICATION
,
85 CCDER_CONTEXT_SPECIFIC
= CCASN1_CONTEXT_SPECIFIC
,
86 CCDER_PRIVATE
= CCASN1_PRIVATE
,
88 CCDER_CONSTRUCTED_SET
= CCDER_SET
| CCDER_CONSTRUCTED
,
89 CCDER_CONSTRUCTED_SEQUENCE
= CCDER_SEQUENCE
| CCDER_CONSTRUCTED
,
94 // MARK: ccder_sizeof_ functions
96 /* Returns the size of an asn1 encoded item of length l in bytes. */
98 size_t ccder_sizeof(ccder_tag tag
, size_t len
);
101 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag
,
102 cc_size n
, const cc_unit
*s
);
105 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag
,
106 cc_size n
, const cc_unit
*s
);
108 CC_NO_INLINE CC_CONST
109 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag
,
111 CC_NO_INLINE CC_CONST
112 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag
, uint64_t value
);
115 size_t ccder_sizeof_integer(cc_size n
, const cc_unit
*s
);
117 CC_NO_INLINE CC_CONST
118 size_t ccder_sizeof_len(size_t len
);
121 size_t ccder_sizeof_octet_string(cc_size n
, const cc_unit
*s
);
124 size_t ccder_sizeof_oid(ccoid_t oid
);
126 CC_NO_INLINE CC_CONST
127 size_t ccder_sizeof_raw_octet_string(size_t s_size
);
129 CC_NO_INLINE CC_CONST
130 size_t ccder_sizeof_tag(ccder_tag tag
);
132 CC_NO_INLINE CC_CONST
133 size_t ccder_sizeof_uint64(uint64_t value
);
136 // MARK: ccder_encode_ functions.
138 /* Encode a tag backwards, der_end should point to one byte past the end of
139 destination for the tag, returns a pointer to the first byte of the tag.
140 Returns NULL if there is an encoding error. */
141 CC_NO_INLINE CC_NONNULL2
142 uint8_t *ccder_encode_tag(ccder_tag tag
, const uint8_t *der
, uint8_t *der_end
);
144 /* Returns a pointer to the start of the len field. returns NULL if there
145 is an encoding error. */
146 CC_NO_INLINE CC_NONNULL2
148 ccder_encode_len(size_t len
, const uint8_t *der
, uint8_t *der_end
);
150 /* der_end should point to the first byte of the content of this der item. */
151 CC_NO_INLINE CC_NONNULL3
153 ccder_encode_tl(ccder_tag tag
, size_t len
, const uint8_t *der
, uint8_t *der_end
);
155 CC_NO_INLINE CC_PURE CC_NONNULL2
157 ccder_encode_body_nocopy(size_t size
, const uint8_t *der
, uint8_t *der_end
);
159 /* Encode the tag and length of a constructed object. der is the lower
160 bound, der_end is one byte paste where we want to write the length and
161 body_end is one byte past the end of the body of the der object we are
162 encoding the tag and length of. */
163 CC_NO_INLINE
CC_NONNULL((2, 3))
165 ccder_encode_constructed_tl(ccder_tag tag
, const uint8_t *body_end
,
166 const uint8_t *der
, uint8_t *der_end
);
168 /* Encodes oid into der and returns
169 der + ccder_sizeof_oid(oid). */
170 CC_NO_INLINE
CC_NONNULL_TU((1)) CC_NONNULL2
171 uint8_t *ccder_encode_oid(ccoid_t oid
, const uint8_t *der
, uint8_t *der_end
);
173 CC_NO_INLINE
CC_NONNULL((3, 4))
174 uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag
,
175 cc_size n
, const cc_unit
*s
,
176 const uint8_t *der
, uint8_t *der_end
);
178 CC_NO_INLINE
CC_NONNULL((2, 3))
179 uint8_t *ccder_encode_integer(cc_size n
, const cc_unit
*s
,
180 const uint8_t *der
, uint8_t *der_end
);
182 CC_NO_INLINE CC_NONNULL3
183 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag
,
185 const uint8_t *der
, uint8_t *der_end
);
187 CC_NO_INLINE CC_NONNULL2
188 uint8_t *ccder_encode_uint64(uint64_t value
,
189 const uint8_t *der
, uint8_t *der_end
);
191 CC_NO_INLINE
CC_NONNULL((3, 4))
192 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag
,
193 cc_size n
, const cc_unit
*s
,
197 CC_NO_INLINE
CC_NONNULL((2, 3))
198 uint8_t *ccder_encode_octet_string(cc_size n
, const cc_unit
*s
,
199 const uint8_t *der
, uint8_t *der_end
);
201 CC_NO_INLINE
CC_NONNULL((3, 4))
202 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag
,
203 size_t s_size
, const uint8_t *s
,
207 CC_NO_INLINE
CC_NONNULL((2, 3))
208 uint8_t *ccder_encode_raw_octet_string(size_t s_size
, const uint8_t *s
,
209 const uint8_t *der
, uint8_t *der_end
);
211 /* ccder_encode_body COPIES the body into the der.
212 It's inefficient – especially when you already have to convert to get to
213 the form for the body.
214 see encode integer for the right way to unify conversion and insertion */
215 CC_NO_INLINE CC_NONNULL3
217 ccder_encode_body(size_t size
, const uint8_t* body
,
218 const uint8_t *der
, uint8_t *der_end
);
220 // MARK: ccder_decode_ functions.
222 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
223 returns NULL if there is a decoding error. */
224 CC_NO_INLINE
CC_NONNULL((1, 3))
225 const uint8_t *ccder_decode_tag(ccder_tag
*tagp
, const uint8_t *der
, const uint8_t *der_end
);
227 CC_NO_INLINE
CC_NONNULL((1, 3))
228 const uint8_t *ccder_decode_len(size_t *lenp
, const uint8_t *der
, const uint8_t *der_end
);
230 /* Returns a pointer to the start of the der object, and returns the length in len.
231 returns NULL if there is a decoding error. */
232 CC_NO_INLINE
CC_NONNULL((2, 4))
233 const uint8_t *ccder_decode_tl(ccder_tag expected_tag
, size_t *lenp
,
234 const uint8_t *der
, const uint8_t *der_end
);
236 CC_NO_INLINE
CC_NONNULL((2, 4))
238 ccder_decode_constructed_tl(ccder_tag expected_tag
, const uint8_t **body_end
,
239 const uint8_t *der
, const uint8_t *der_end
);
241 CC_NO_INLINE
CC_NONNULL((1, 3))
243 ccder_decode_sequence_tl(const uint8_t **body_end
,
244 const uint8_t *der
, const uint8_t *der_end
);
246 CC_NO_INLINE
CC_NONNULL((2, 4))
247 const uint8_t *ccder_decode_uint(cc_size n
, cc_unit
*r
,
248 const uint8_t *der
, const uint8_t *der_end
);
250 CC_NO_INLINE
CC_NONNULL((3))
251 const uint8_t *ccder_decode_uint64(uint64_t* r
,
252 const uint8_t *der
, const uint8_t *der_end
);
254 /* Decode SEQUENCE { r, s -- (unsigned)integer } in der into r and s.
255 Returns NULL on decode errors, returns pointer just past the end of the
256 sequence of integers otherwise. */
257 CC_NO_INLINE
CC_NONNULL((2, 3, 5))
258 const uint8_t *ccder_decode_seqii(cc_size n
, cc_unit
*r
, cc_unit
*s
,
259 const uint8_t *der
, const uint8_t *der_end
);
260 CC_NO_INLINE
CC_NONNULL_TU((1)) CC_NONNULL((3))
261 const uint8_t *ccder_decode_oid(ccoid_t
*oidp
,
262 const uint8_t *der
, const uint8_t *der_end
);
264 CC_NO_INLINE
CC_NONNULL((1,2,4))
265 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string
,
267 const uint8_t *der
, const uint8_t *der_end
);
269 CC_NO_INLINE
CC_NONNULL_TU((4)) CC_NONNULL((1,2,3,5,6,8))
270 const uint8_t *ccder_decode_eckey(uint64_t *version
,
271 size_t *priv_size
, const uint8_t **priv_key
,
273 size_t *pub_size
, const uint8_t **pub_key
,
274 const uint8_t *der
, const uint8_t *der_end
);
276 #ifndef CCDER_MULTIBYTE_TAGS
277 #include <corecrypto/ccder_decode_constructed_tl.h>
278 #include <corecrypto/ccder_decode_len.h>
279 #include <corecrypto/ccder_decode_oid.h>
280 #include <corecrypto/ccder_decode_seqii.h>
281 #include <corecrypto/ccder_decode_sequence_tl.h>
282 #include <corecrypto/ccder_decode_tag.h>
283 #include <corecrypto/ccder_decode_tl.h>
284 #include <corecrypto/ccder_decode_uint.h>
285 #include <corecrypto/ccder_decode_bitstring.h>
286 #include <corecrypto/ccder_decode_eckey.h>
287 #include <corecrypto/ccder_encode_body_nocopy.h>
288 #include <corecrypto/ccder_encode_constructed_tl.h>
289 #include <corecrypto/ccder_encode_implicit_integer.h>
290 #include <corecrypto/ccder_encode_implicit_octet_string.h>
291 #include <corecrypto/ccder_encode_implicit_uint64.h>
292 #include <corecrypto/ccder_encode_integer.h>
293 #include <corecrypto/ccder_encode_len.h>
294 #include <corecrypto/ccder_encode_octet_string.h>
295 #include <corecrypto/ccder_encode_oid.h>
296 #include <corecrypto/ccder_encode_tag.h>
297 #include <corecrypto/ccder_encode_tl.h>
298 #include <corecrypto/ccder_encode_uint64.h>
299 #include <corecrypto/ccder_sizeof.h>
300 #include <corecrypto/ccder_sizeof_integer.h>
301 #include <corecrypto/ccder_sizeof_len.h>
302 #include <corecrypto/ccder_sizeof_oid.h>
303 #include <corecrypto/ccder_sizeof_tag.h>
306 #endif /* _CORECRYPTO_CCDER_H_ */