]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccder.h
756afd29520f07876d594172d2e1c3acb242e80c
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccder.h
1 /*
2 * ccder.h
3 * corecrypto
4 *
5 * Created by Michael Brouwer on 2/28/12.
6 * Copyright 2012 Apple Inc. All rights reserved.
7 *
8 */
9
10 #ifndef _CORECRYPTO_CCDER_H_
11 #define _CORECRYPTO_CCDER_H_
12
13 #include <corecrypto/ccasn1.h>
14 #include <corecrypto/ccn.h>
15
16 #define CCDER_MULTIBYTE_TAGS 1
17
18 #ifdef CCDER_MULTIBYTE_TAGS
19 typedef unsigned long ccder_tag;
20 #else
21 typedef uint8_t ccder_tag;
22 #endif
23
24 /* DER types to be used with ccder_decode and ccder_encode functions. */
25 enum {
26 CCDER_EOL = CCASN1_EOL,
27 CCDER_BOOLEAN = CCASN1_BOOLEAN,
28 CCDER_INTEGER = CCASN1_INTEGER,
29 CCDER_BIT_STRING = CCASN1_BIT_STRING,
30 CCDER_OCTET_STRING = CCASN1_OCTET_STRING,
31 CCDER_NULL = CCASN1_NULL,
32 CCDER_OBJECT_IDENTIFIER = CCASN1_OBJECT_IDENTIFIER,
33 CCDER_OBJECT_DESCRIPTOR = CCASN1_OBJECT_DESCRIPTOR,
34 /* External or instance-of 0x08 */
35 CCDER_REAL = CCASN1_REAL,
36 CCDER_ENUMERATED = CCASN1_ENUMERATED,
37 CCDER_EMBEDDED_PDV = CCASN1_EMBEDDED_PDV,
38 CCDER_UTF8_STRING = CCASN1_UTF8_STRING,
39 /* 0x0d */
40 /* 0x0e */
41 /* 0x0f */
42 CCDER_SEQUENCE = CCASN1_SEQUENCE,
43 CCDER_SET = CCASN1_SET,
44 CCDER_NUMERIC_STRING = CCASN1_NUMERIC_STRING,
45 CCDER_PRINTABLE_STRING = CCASN1_PRINTABLE_STRING,
46 CCDER_T61_STRING = CCASN1_T61_STRING,
47 CCDER_VIDEOTEX_STRING = CCASN1_VIDEOTEX_STRING,
48 CCDER_IA5_STRING = CCASN1_IA5_STRING,
49 CCDER_UTC_TIME = CCASN1_UTC_TIME,
50 CCDER_GENERALIZED_TIME = CCASN1_GENERALIZED_TIME,
51 CCDER_GRAPHIC_STRING = CCASN1_GRAPHIC_STRING,
52 CCDER_VISIBLE_STRING = CCASN1_VISIBLE_STRING,
53 CCDER_GENERAL_STRING = CCASN1_GENERAL_STRING,
54 CCDER_UNIVERSAL_STRING = CCASN1_UNIVERSAL_STRING,
55 /* 0x1d */
56 CCDER_BMP_STRING = CCASN1_BMP_STRING,
57 CCDER_HIGH_TAG_NUMBER = CCASN1_HIGH_TAG_NUMBER,
58 CCDER_TELETEX_STRING = CCDER_T61_STRING,
59
60 #ifdef CCDER_MULTIBYTE_TAGS
61 CCDER_TAG_MASK = ((ccder_tag)~0),
62 CCDER_TAGNUM_MASK = ((ccder_tag)~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3))),
63
64 CCDER_METHOD_MASK = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
65 CCDER_PRIMITIVE = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3)),
66 CCDER_CONSTRUCTED = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
67
68 CCDER_CLASS_MASK = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
69 CCDER_UNIVERSAL = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2)),
70 CCDER_APPLICATION = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2)),
71 CCDER_CONTEXT_SPECIFIC = ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2)),
72 CCDER_PRIVATE = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
73 #else
74 CCDER_TAG_MASK = CCASN1_TAG_MASK,
75 CCDER_TAGNUM_MASK = CCASN1_TAGNUM_MASK,
76
77 CCDER_METHOD_MASK = CCASN1_METHOD_MASK,
78 CCDER_PRIMITIVE = CCASN1_PRIMITIVE,
79 CCDER_CONSTRUCTED = CCASN1_CONSTRUCTED,
80
81 CCDER_CLASS_MASK = CCASN1_CLASS_MASK,
82 CCDER_UNIVERSAL = CCASN1_UNIVERSAL,
83 CCDER_APPLICATION = CCASN1_APPLICATION,
84 CCDER_CONTEXT_SPECIFIC = CCASN1_CONTEXT_SPECIFIC,
85 CCDER_PRIVATE = CCASN1_PRIVATE,
86 #endif
87 CCDER_CONSTRUCTED_SET = CCDER_SET | CCDER_CONSTRUCTED,
88 CCDER_CONSTRUCTED_SEQUENCE = CCDER_SEQUENCE | CCDER_CONSTRUCTED,
89 };
90
91
92 #pragma mark ccder_sizeof_ functions
93
94 inline CC_CONST
95 size_t ccder_sizeof_tag(ccder_tag tag);
96
97 inline CC_CONST
98 size_t ccder_sizeof_len(size_t len);
99
100 /* Returns the size of an asn1 encoded item of length l in bytes,
101 assuming a 1 byte tag. */
102 inline CC_CONST
103 size_t ccder_sizeof(ccder_tag tag, size_t len);
104
105 inline CC_CONST
106 size_t ccder_sizeof_oid(ccoid_t oid);
107
108 #pragma mark ccder_encode_ functions.
109
110 /* Encode a tag backwards, der_end should point to one byte past the end of
111 destination for the tag, returns a pointer to the first byte of the tag.
112 Returns NULL if there is an encoding error. */
113 inline CC_NONNULL2
114 uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
115
116 /* Returns a pointer to the start of the len field. returns NULL if there
117 is an encoding error. */
118 inline CC_NONNULL2
119 uint8_t *
120 ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
121
122 /* der_end should point to the first byte of the content of this der item. */
123 inline CC_NONNULL3
124 uint8_t *
125 ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
126
127 inline CC_PURE CC_NONNULL2
128 uint8_t *
129 ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
130
131 /* Encode the tag and length of a constructed object. der is the lower
132 bound, der_end is one byte paste where we want to write the length and
133 body_end is one byte past the end of the body of the der object we are
134 encoding the tag and length of. */
135 inline CC_NONNULL((2,3))
136 uint8_t *
137 ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end,
138 const uint8_t *der, uint8_t *der_end);
139
140 /* Encodes oid into der and returns
141 der + ccder_sizeof_oid(oid). */
142 inline CC_NONNULL1 CC_NONNULL2
143 uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
144
145 inline CC_NONNULL((3,4))
146 uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag,
147 cc_size n, const cc_unit *s,
148 const uint8_t *der, uint8_t *der_end);
149
150 inline CC_NONNULL((2,3))
151 uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s,
152 const uint8_t *der, uint8_t *der_end);
153
154 inline CC_NONNULL3
155 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag,
156 uint64_t value,
157 const uint8_t *der, uint8_t *der_end);
158
159 inline CC_NONNULL3
160 uint8_t *ccder_encode_uint64(uint64_t value,
161 const uint8_t *der, uint8_t *der_end);
162
163 inline CC_NONNULL((3,4))
164 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag,
165 cc_size n, const cc_unit *s,
166 const uint8_t *der,
167 uint8_t *der_end);
168
169 inline CC_NONNULL((2,3))
170 uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s,
171 const uint8_t *der, uint8_t *der_end);
172
173 inline CC_NONNULL((3,4))
174 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
175 size_t s_size, const uint8_t *s,
176 const uint8_t *der,
177 uint8_t *der_end);
178
179 inline CC_NONNULL((2,3))
180 uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s,
181 const uint8_t *der, uint8_t *der_end);
182
183 /* ccder_encode_body COPIES the body into the der.
184 It's inefficient – especially when you already have to convert to get to
185 the form for the body.
186 see encode integer for the right way to unify conversion and insertion */
187 inline CC_NONNULL3
188 uint8_t *
189 ccder_encode_body(size_t size, const uint8_t* body,
190 const uint8_t *der, uint8_t *der_end);
191
192 #pragma mark ccder_decode_ functions.
193
194 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
195 returns NULL if there is a decoding error. */
196 inline CC_NONNULL((1,3))
197 const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
198
199 inline CC_NONNULL((1,3))
200 const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
201
202 /* Returns a pointer to the start of the der object, and returns the length in len.
203 returns NULL if there is a decoding error. */
204 inline CC_NONNULL((2,4))
205 const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp,
206 const uint8_t *der, const uint8_t *der_end);
207
208 inline CC_NONNULL((2,3))
209 const uint8_t *
210 ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end,
211 const uint8_t *der, const uint8_t *der_end);
212
213 inline CC_NONNULL((1,3))
214 const uint8_t *
215 ccder_decode_sequence_tl(const uint8_t **body_end,
216 const uint8_t *der, const uint8_t *der_end);
217
218 inline CC_NONNULL((2,4))
219 const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r,
220 const uint8_t *der, const uint8_t *der_end);
221
222 inline CC_NONNULL((1,3))
223 const uint8_t *ccder_decode_uint64(uint64_t* r,
224 const uint8_t *der, const uint8_t *der_end);
225
226 /* Decode SEQUENCE { r, s -- (unsigned)integer } in der into r and s.
227 Returns NULL on decode errors, returns pointer just past the end of the
228 sequence of integers otherwise. */
229 inline CC_NONNULL((2,3,5))
230 const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s,
231 const uint8_t *der, const uint8_t *der_end);
232 inline CC_NONNULL_ALL
233 const uint8_t *ccder_decode_oid(ccoid_t *oidp,
234 const uint8_t *der, const uint8_t *der_end);
235
236 #ifndef CCDER_MULTIBYTE_TAGS
237 #include <corecrypto/ccder_decode_constructed_tl.h>
238 #include <corecrypto/ccder_decode_len.h>
239 #include <corecrypto/ccder_decode_oid.h>
240 #include <corecrypto/ccder_decode_seqii.h>
241 #include <corecrypto/ccder_decode_sequence_tl.h>
242 #include <corecrypto/ccder_decode_tag.h>
243 #include <corecrypto/ccder_decode_tl.h>
244 #include <corecrypto/ccder_decode_uint.h>
245 #include <corecrypto/ccder_encode_body_nocopy.h>
246 #include <corecrypto/ccder_encode_constructed_tl.h>
247 #include <corecrypto/ccder_encode_implicit_integer.h>
248 #include <corecrypto/ccder_encode_implicit_octet_string.h>
249 #include <corecrypto/ccder_encode_implicit_uint64.h>
250 #include <corecrypto/ccder_encode_integer.h>
251 #include <corecrypto/ccder_encode_len.h>
252 #include <corecrypto/ccder_encode_octet_string.h>
253 #include <corecrypto/ccder_encode_oid.h>
254 #include <corecrypto/ccder_encode_tag.h>
255 #include <corecrypto/ccder_encode_tl.h>
256 #include <corecrypto/ccder_encode_uint64.h>
257 #include <corecrypto/ccder_sizeof.h>
258 #include <corecrypto/ccder_sizeof_len.h>
259 #include <corecrypto/ccder_sizeof_oid.h>
260 #include <corecrypto/ccder_sizeof_tag.h>
261 #endif
262
263 #endif /* _CORECRYPTO_CCDER_H_ */