summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/bs_ber.c220
-rw-r--r--src/lib/libssl/bs_cbb.c387
-rw-r--r--src/lib/libssl/bs_cbs.c390
-rw-r--r--src/lib/libssl/bytestring.h346
-rw-r--r--src/lib/libssl/src/ssl/bs_ber.c220
-rw-r--r--src/lib/libssl/src/ssl/bs_cbb.c387
-rw-r--r--src/lib/libssl/src/ssl/bs_cbs.c390
-rw-r--r--src/lib/libssl/src/ssl/bytestring.h346
-rw-r--r--src/lib/libssl/ssl/Makefile3
9 files changed, 2688 insertions, 1 deletions
diff --git a/src/lib/libssl/bs_ber.c b/src/lib/libssl/bs_ber.c
new file mode 100644
index 0000000000..b94b63e37e
--- /dev/null
+++ b/src/lib/libssl/bs_ber.c
@@ -0,0 +1,220 @@
1/* $OpenBSD: bs_ber.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <string.h>
18
19#include <openssl/opensslconf.h>
20
21#include "bytestring.h"
22
23/* kMaxDepth is a just a sanity limit. The code should be such that the length
24 * of the input being processes always decreases. None the less, a very large
25 * input could otherwise cause the stack to overflow. */
26static const unsigned kMaxDepth = 2048;
27
28/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
29 * depending on whether an indefinite length element was found. The value of
30 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
31 * and zero on error. */
32static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
33 CBS in;
34
35 if (depth > kMaxDepth) {
36 return 0;
37 }
38
39 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
40 *ber_found = 0;
41
42 while (CBS_len(&in) > 0) {
43 CBS contents;
44 unsigned tag;
45 size_t header_len;
46
47 if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) {
48 return 0;
49 }
50 if (CBS_len(&contents) == header_len &&
51 header_len > 0 &&
52 CBS_data(&contents)[header_len-1] == 0x80) {
53 *ber_found = 1;
54 return 1;
55 }
56 if (tag & CBS_ASN1_CONSTRUCTED) {
57 if (!CBS_skip(&contents, header_len) ||
58 !cbs_find_ber(&contents, ber_found, depth + 1)) {
59 return 0;
60 }
61 }
62 }
63
64 return 1;
65}
66
67/* is_primitive_type returns true if |tag| likely a primitive type. Normally
68 * one can just test the "constructed" bit in the tag but, in BER, even
69 * primitive tags can have the constructed bit if they have indefinite
70 * length. */
71static char is_primitive_type(unsigned tag) {
72 return (tag & 0xc0) == 0 &&
73 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
74 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
75}
76
77/* is_eoc returns true if |header_len| and |contents|, as returned by
78 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */
79static char is_eoc(size_t header_len, CBS *contents) {
80 return header_len == 2 && CBS_len(contents) == 2 &&
81 memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
82}
83
84/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
85 * |squash_header| is set then the top-level of elements from |in| will not
86 * have their headers written. This is used when concatenating the fragments of
87 * an indefinite length, primitive value. If |looking_for_eoc| is set then any
88 * EOC elements found will cause the function to return after consuming it.
89 * It returns one on success and zero on error. */
90static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
91 char looking_for_eoc, unsigned depth) {
92 if (depth > kMaxDepth) {
93 return 0;
94 }
95
96 while (CBS_len(in) > 0) {
97 CBS contents;
98 unsigned tag;
99 size_t header_len;
100 CBB *out_contents, out_contents_storage;
101
102 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) {
103 return 0;
104 }
105 out_contents = out;
106
107 if (CBS_len(&contents) == header_len) {
108 if (is_eoc(header_len, &contents)) {
109 return looking_for_eoc;
110 }
111
112 if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
113 /* This is an indefinite length element. If it's a SEQUENCE or SET then
114 * we just need to write the out the contents as normal, but with a
115 * concrete length prefix.
116 *
117 * If it's a something else then the contents will be a series of BER
118 * elements of the same type which need to be concatenated. */
119 const char context_specific = (tag & 0xc0) == 0x80;
120 char squash_child_headers = is_primitive_type(tag);
121
122 /* This is a hack, but it sufficies to handle NSS's output. If we find
123 * an indefinite length, context-specific tag with a definite, primtive
124 * tag inside it, then we assume that the context-specific tag is
125 * implicit and the tags within are fragments of a primitive type that
126 * need to be concatenated. */
127 if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
128 CBS in_copy, inner_contents;
129 unsigned inner_tag;
130 size_t inner_header_len;
131
132 CBS_init(&in_copy, CBS_data(in), CBS_len(in));
133 if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag,
134 &inner_header_len)) {
135 return 0;
136 }
137 if (CBS_len(&inner_contents) > inner_header_len &&
138 is_primitive_type(inner_tag)) {
139 squash_child_headers = 1;
140 }
141 }
142
143 if (!squash_header) {
144 unsigned out_tag = tag;
145 if (squash_child_headers) {
146 out_tag &= ~CBS_ASN1_CONSTRUCTED;
147 }
148 if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
149 return 0;
150 }
151 out_contents = &out_contents_storage;
152 }
153
154 if (!cbs_convert_ber(in, out_contents,
155 squash_child_headers,
156 1 /* looking for eoc */, depth + 1)) {
157 return 0;
158 }
159 if (out_contents != out && !CBB_flush(out)) {
160 return 0;
161 }
162 continue;
163 }
164 }
165
166 if (!squash_header) {
167 if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
168 return 0;
169 }
170 out_contents = &out_contents_storage;
171 }
172
173 if (!CBS_skip(&contents, header_len)) {
174 return 0;
175 }
176
177 if (tag & CBS_ASN1_CONSTRUCTED) {
178 if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
179 0 /* not looking for eoc */, depth + 1)) {
180 return 0;
181 }
182 } else {
183 if (!CBB_add_bytes(out_contents, CBS_data(&contents),
184 CBS_len(&contents))) {
185 return 0;
186 }
187 }
188
189 if (out_contents != out && !CBB_flush(out)) {
190 return 0;
191 }
192 }
193
194 return looking_for_eoc == 0;
195}
196
197int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) {
198 CBB cbb;
199
200 /* First, do a quick walk to find any indefinite-length elements. Most of the
201 * time we hope that there aren't any and thus we can quickly return. */
202 char conversion_needed;
203 if (!cbs_find_ber(in, &conversion_needed, 0)) {
204 return 0;
205 }
206
207 if (!conversion_needed) {
208 *out = NULL;
209 *out_len = 0;
210 return 1;
211 }
212
213 CBB_init(&cbb, CBS_len(in));
214 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
215 CBB_cleanup(&cbb);
216 return 0;
217 }
218
219 return CBB_finish(&cbb, out, out_len);
220}
diff --git a/src/lib/libssl/bs_cbb.c b/src/lib/libssl/bs_cbb.c
new file mode 100644
index 0000000000..668231c1c7
--- /dev/null
+++ b/src/lib/libssl/bs_cbb.c
@@ -0,0 +1,387 @@
1/* $OpenBSD: bs_cbb.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <assert.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <openssl/opensslconf.h>
22
23#include "bytestring.h"
24
25static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
26 struct cbb_buffer_st *base;
27
28 base = malloc(sizeof(struct cbb_buffer_st));
29 if (base == NULL) {
30 free(buf);
31 return 0;
32 }
33
34 base->buf = buf;
35 base->len = 0;
36 base->cap = cap;
37 base->can_resize = 1;
38
39 memset(cbb, 0, sizeof(CBB));
40 cbb->base = base;
41 cbb->is_top_level = 1;
42 return 1;
43}
44
45int CBB_init(CBB *cbb, size_t initial_capacity) {
46 uint8_t *buf;
47
48 buf = malloc(initial_capacity);
49 if (initial_capacity > 0 && buf == NULL) {
50 return 0;
51 }
52
53 return cbb_init(cbb, buf, initial_capacity);
54}
55
56int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
57 if (!cbb_init(cbb, buf, len)) {
58 return 0;
59 }
60
61 cbb->base->can_resize = 0;
62 return 1;
63}
64
65void CBB_cleanup(CBB *cbb) {
66 if (cbb->base) {
67 if (cbb->base->buf && cbb->base->can_resize) {
68 free(cbb->base->buf);
69 }
70 free(cbb->base);
71 }
72 cbb->base = NULL;
73}
74
75static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
76 size_t len) {
77 size_t newlen;
78
79 if (base == NULL) {
80 return 0;
81 }
82
83#if 0
84 // XXX Added for boringssl patch testing
85 if (len == 0) {
86 if (out) {
87 *out = NULL;
88 }
89 return 1;
90 }
91#endif
92
93 newlen = base->len + len;
94 if (newlen < base->len) {
95 /* Overflow */
96 return 0;
97 }
98
99 if (newlen > base->cap) {
100 size_t newcap = base->cap * 2;
101 uint8_t *newbuf;
102
103 if (!base->can_resize) {
104 return 0;
105 }
106
107 if (newcap < base->cap || newcap < newlen) {
108 newcap = newlen;
109 }
110 newbuf = realloc(base->buf, newcap);
111 if (newbuf == NULL) {
112 return 0;
113 }
114
115 base->buf = newbuf;
116 base->cap = newcap;
117 }
118
119 if (out) {
120 *out = base->buf + base->len;
121 }
122 base->len = newlen;
123 return 1;
124}
125
126static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v,
127 size_t len_len) {
128 uint8_t *buf;
129 size_t i;
130
131 if (len_len == 0) {
132 return 1;
133 }
134 if (!cbb_buffer_add(base, &buf, len_len)) {
135 return 0;
136 }
137
138 for (i = len_len - 1; i < len_len; i--) {
139 buf[i] = v;
140 v >>= 8;
141 }
142 return 1;
143}
144
145int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
146 if (!cbb->is_top_level) {
147 return 0;
148 }
149
150 if (!CBB_flush(cbb)) {
151 return 0;
152 }
153
154 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) {
155 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */
156 return 0;
157 }
158
159 if (out_data != NULL) {
160 *out_data = cbb->base->buf;
161 }
162 if (out_len != NULL) {
163 *out_len = cbb->base->len;
164 }
165 cbb->base->buf = NULL;
166 CBB_cleanup(cbb);
167 return 1;
168}
169
170/* CBB_flush recurses and then writes out any pending length prefix. The
171 * current length of the underlying base is taken to be the length of the
172 * length-prefixed data. */
173int CBB_flush(CBB *cbb) {
174 size_t child_start, i, len;
175
176 if (cbb->base == NULL) {
177 return 0;
178 }
179
180 if (cbb->child == NULL || cbb->pending_len_len == 0) {
181 return 1;
182 }
183
184 child_start = cbb->offset + cbb->pending_len_len;
185
186 if (!CBB_flush(cbb->child) ||
187 child_start < cbb->offset ||
188 cbb->base->len < child_start) {
189 return 0;
190 }
191
192 len = cbb->base->len - child_start;
193
194 if (cbb->pending_is_asn1) {
195 /* For ASN.1 we assume that we'll only need a single byte for the length.
196 * If that turned out to be incorrect, we have to move the contents along
197 * in order to make space. */
198 size_t len_len;
199 uint8_t initial_length_byte;
200
201 assert (cbb->pending_len_len == 1);
202
203 if (len > 0xfffffffe) {
204 /* Too large. */
205 return 0;
206 } else if (len > 0xffffff) {
207 len_len = 5;
208 initial_length_byte = 0x80 | 4;
209 } else if (len > 0xffff) {
210 len_len = 4;
211 initial_length_byte = 0x80 | 3;
212 } else if (len > 0xff) {
213 len_len = 3;
214 initial_length_byte = 0x80 | 2;
215 } else if (len > 0x7f) {
216 len_len = 2;
217 initial_length_byte = 0x80 | 1;
218 } else {
219 len_len = 1;
220 initial_length_byte = len;
221 len = 0;
222 }
223
224 if (len_len != 1) {
225 /* We need to move the contents along in order to make space. */
226 size_t extra_bytes = len_len - 1;
227 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) {
228 return 0;
229 }
230 memmove(cbb->base->buf + child_start + extra_bytes,
231 cbb->base->buf + child_start, len);
232 }
233 cbb->base->buf[cbb->offset++] = initial_length_byte;
234 cbb->pending_len_len = len_len - 1;
235 }
236
237 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
238 cbb->base->buf[cbb->offset + i] = len;
239 len >>= 8;
240 }
241 if (len != 0) {
242 return 0;
243 }
244
245 cbb->child->base = NULL;
246 cbb->child = NULL;
247 cbb->pending_len_len = 0;
248 cbb->pending_is_asn1 = 0;
249 cbb->offset = 0;
250
251 return 1;
252}
253
254
255static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
256 size_t len_len) {
257 uint8_t *prefix_bytes;
258
259 if (!CBB_flush(cbb)) {
260 return 0;
261 }
262
263 cbb->offset = cbb->base->len;
264 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
265 return 0;
266 }
267
268 memset(prefix_bytes, 0, len_len);
269 memset(out_contents, 0, sizeof(CBB));
270 out_contents->base = cbb->base;
271 cbb->child = out_contents;
272 cbb->pending_len_len = len_len;
273 cbb->pending_is_asn1 = 0;
274
275 return 1;
276}
277
278int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) {
279 return cbb_add_length_prefixed(cbb, out_contents, 1);
280}
281
282int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) {
283 return cbb_add_length_prefixed(cbb, out_contents, 2);
284}
285
286int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
287 return cbb_add_length_prefixed(cbb, out_contents, 3);
288}
289
290int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
291 if (!CBB_flush(cbb) ||
292 !CBB_add_u8(cbb, tag)) {
293 return 0;
294 }
295
296 cbb->offset = cbb->base->len;
297 if (!CBB_add_u8(cbb, 0)) {
298 return 0;
299 }
300
301 memset(out_contents, 0, sizeof(CBB));
302 out_contents->base = cbb->base;
303 cbb->child = out_contents;
304 cbb->pending_len_len = 1;
305 cbb->pending_is_asn1 = 1;
306
307 return 1;
308}
309
310int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
311 uint8_t *dest;
312
313 if (!CBB_flush(cbb) ||
314 !cbb_buffer_add(cbb->base, &dest, len)) {
315 return 0;
316 }
317 memcpy(dest, data, len);
318 return 1;
319}
320
321int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
322 if (!CBB_flush(cbb) ||
323 !cbb_buffer_add(cbb->base, out_data, len)) {
324 return 0;
325 }
326 return 1;
327}
328
329int CBB_add_u8(CBB *cbb, uint8_t value) {
330 if (!CBB_flush(cbb)) {
331 return 0;
332 }
333
334 return cbb_buffer_add_u(cbb->base, value, 1);
335}
336
337int CBB_add_u16(CBB *cbb, uint16_t value) {
338 if (!CBB_flush(cbb)) {
339 return 0;
340 }
341
342 return cbb_buffer_add_u(cbb->base, value, 2);
343}
344
345int CBB_add_u24(CBB *cbb, uint32_t value) {
346 if (!CBB_flush(cbb)) {
347 return 0;
348 }
349
350 return cbb_buffer_add_u(cbb->base, value, 3);
351}
352
353int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
354 CBB child;
355 size_t i;
356 int started = 0;
357
358 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
359 return 0;
360 }
361
362 for (i = 0; i < 8; i++) {
363 uint8_t byte = (value >> 8*(7-i)) & 0xff;
364 if (!started) {
365 if (byte == 0) {
366 /* Don't encode leading zeros. */
367 continue;
368 }
369 /* If the high bit is set, add a padding byte to make it
370 * unsigned. */
371 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) {
372 return 0;
373 }
374 started = 1;
375 }
376 if (!CBB_add_u8(&child, byte)) {
377 return 0;
378 }
379 }
380
381 /* 0 is encoded as a single 0, not the empty string. */
382 if (!started && !CBB_add_u8(&child, 0)) {
383 return 0;
384 }
385
386 return CBB_flush(cbb);
387}
diff --git a/src/lib/libssl/bs_cbs.c b/src/lib/libssl/bs_cbs.c
new file mode 100644
index 0000000000..7edfe65288
--- /dev/null
+++ b/src/lib/libssl/bs_cbs.c
@@ -0,0 +1,390 @@
1/* $OpenBSD: bs_cbs.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <assert.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <openssl/opensslconf.h>
22#include <openssl/buffer.h>
23#include <openssl/crypto.h>
24
25#include "bytestring.h"
26
27void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
28 cbs->data = data;
29 cbs->len = len;
30}
31
32static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
33 if (cbs->len < n) {
34 return 0;
35 }
36
37 *p = cbs->data;
38 cbs->data += n;
39 cbs->len -= n;
40 return 1;
41}
42
43int CBS_skip(CBS *cbs, size_t len) {
44 const uint8_t *dummy;
45 return cbs_get(cbs, &dummy, len);
46}
47
48const uint8_t *CBS_data(const CBS *cbs) {
49 return cbs->data;
50}
51
52size_t CBS_len(const CBS *cbs) {
53 return cbs->len;
54}
55
56int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
57 if (*out_ptr != NULL) {
58 free(*out_ptr);
59 *out_ptr = NULL;
60 }
61 *out_len = 0;
62
63 if (cbs->len == 0) {
64 return 1;
65 }
66 *out_ptr = BUF_memdup(cbs->data, cbs->len);
67 if (*out_ptr == NULL) {
68 return 0;
69 }
70 *out_len = cbs->len;
71 return 1;
72}
73
74int CBS_strdup(const CBS *cbs, char **out_ptr) {
75 if (*out_ptr != NULL) {
76 free(*out_ptr);
77 }
78 *out_ptr = strndup((const char*)cbs->data, cbs->len);
79 return (*out_ptr != NULL);
80}
81
82int CBS_contains_zero_byte(const CBS *cbs) {
83 return memchr(cbs->data, 0, cbs->len) != NULL;
84}
85
86int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
87 if (len != cbs->len)
88 return 0;
89 return CRYPTO_memcmp(cbs->data, data, len) == 0;
90}
91
92static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
93 uint32_t result = 0;
94 size_t i;
95 const uint8_t *data;
96
97 if (!cbs_get(cbs, &data, len)) {
98 return 0;
99 }
100 for (i = 0; i < len; i++) {
101 result <<= 8;
102 result |= data[i];
103 }
104 *out = result;
105 return 1;
106}
107
108int CBS_get_u8(CBS *cbs, uint8_t *out) {
109 const uint8_t *v;
110 if (!cbs_get(cbs, &v, 1)) {
111 return 0;
112 }
113 *out = *v;
114 return 1;
115}
116
117int CBS_get_u16(CBS *cbs, uint16_t *out) {
118 uint32_t v;
119 if (!cbs_get_u(cbs, &v, 2)) {
120 return 0;
121 }
122 *out = v;
123 return 1;
124}
125
126int CBS_get_u24(CBS *cbs, uint32_t *out) {
127 return cbs_get_u(cbs, out, 3);
128}
129
130int CBS_get_u32(CBS *cbs, uint32_t *out) {
131 return cbs_get_u(cbs, out, 4);
132}
133
134int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
135 const uint8_t *v;
136 if (!cbs_get(cbs, &v, len)) {
137 return 0;
138 }
139 CBS_init(out, v, len);
140 return 1;
141}
142
143static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
144 uint32_t len;
145 if (!cbs_get_u(cbs, &len, len_len)) {
146 return 0;
147 }
148 return CBS_get_bytes(cbs, out, len);
149}
150
151int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
152 return cbs_get_length_prefixed(cbs, out, 1);
153}
154
155int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
156 return cbs_get_length_prefixed(cbs, out, 2);
157}
158
159int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
160 return cbs_get_length_prefixed(cbs, out, 3);
161}
162
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
164 size_t *out_header_len) {
165 uint8_t tag, length_byte;
166 CBS header = *cbs;
167 CBS throwaway;
168
169 if (out == NULL) {
170 out = &throwaway;
171 }
172
173 if (!CBS_get_u8(&header, &tag) ||
174 !CBS_get_u8(&header, &length_byte)) {
175 return 0;
176 }
177
178 if ((tag & 0x1f) == 0x1f) {
179 /* Long form tags are not supported. */
180 return 0;
181 }
182
183 if (out_tag != NULL) {
184 *out_tag = tag;
185 }
186
187 size_t len;
188 if ((length_byte & 0x80) == 0) {
189 /* Short form length. */
190 len = ((size_t) length_byte) + 2;
191 if (out_header_len != NULL) {
192 *out_header_len = 2;
193 }
194 } else {
195 /* Long form length. */
196 const size_t num_bytes = length_byte & 0x7f;
197 uint32_t len32;
198
199 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
200 /* indefinite length */
201 *out_header_len = 2;
202 return CBS_get_bytes(cbs, out, 2);
203 }
204
205 if (num_bytes == 0 || num_bytes > 4) {
206 return 0;
207 }
208 if (!cbs_get_u(&header, &len32, num_bytes)) {
209 return 0;
210 }
211 if (len32 < 128) {
212 /* Length should have used short-form encoding. */
213 return 0;
214 }
215 if ((len32 >> ((num_bytes-1)*8)) == 0) {
216 /* Length should have been at least one byte shorter. */
217 return 0;
218 }
219 len = len32;
220 if (len + 2 + num_bytes < len) {
221 /* Overflow. */
222 return 0;
223 }
224 len += 2 + num_bytes;
225 if (out_header_len != NULL) {
226 *out_header_len = 2 + num_bytes;
227 }
228 }
229
230 return CBS_get_bytes(cbs, out, len);
231}
232
233static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
234 int skip_header) {
235 size_t header_len;
236 unsigned tag;
237 CBS throwaway;
238
239 if (out == NULL) {
240 out = &throwaway;
241 }
242
243 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
244 tag != tag_value ||
245 (header_len > 0 &&
246 /* This ensures that the tag is either zero length or
247 * indefinite-length. */
248 CBS_len(out) == header_len &&
249 CBS_data(out)[header_len - 1] == 0x80)) {
250 return 0;
251 }
252
253 if (skip_header && !CBS_skip(out, header_len)) {
254 assert(0);
255 return 0;
256 }
257
258 return 1;
259}
260
261int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
262 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
263}
264
265int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
266 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
267}
268
269int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
270 if (CBS_len(cbs) < 1) {
271 return 0;
272 }
273 return CBS_data(cbs)[0] == tag_value;
274}
275
276int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
277 CBS bytes;
278 const uint8_t *data;
279 size_t i, len;
280
281 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
282 return 0;
283 }
284
285 *out = 0;
286 data = CBS_data(&bytes);
287 len = CBS_len(&bytes);
288
289 if (len == 0) {
290 /* An INTEGER is encoded with at least one octet. */
291 return 0;
292 }
293
294 if ((data[0] & 0x80) != 0) {
295 /* negative number */
296 return 0;
297 }
298
299 for (i = 0; i < len; i++) {
300 if ((*out >> 56) != 0) {
301 /* Too large to represent as a uint64_t. */
302 return 0;
303 }
304 *out <<= 8;
305 *out |= data[i];
306 }
307
308 return 1;
309}
310
311int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
312 if (CBS_peek_asn1_tag(cbs, tag)) {
313 if (!CBS_get_asn1(cbs, out, tag)) {
314 return 0;
315 }
316 *out_present = 1;
317 } else {
318 *out_present = 0;
319 }
320 return 1;
321}
322
323int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
324 unsigned tag) {
325 CBS child;
326 int present;
327 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
328 return 0;
329 }
330 if (present) {
331 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
332 CBS_len(&child) != 0) {
333 return 0;
334 }
335 } else {
336 CBS_init(out, NULL, 0);
337 }
338 if (out_present) {
339 *out_present = present;
340 }
341 return 1;
342}
343
344int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
345 uint64_t default_value) {
346 CBS child;
347 int present;
348 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
349 return 0;
350 }
351 if (present) {
352 if (!CBS_get_asn1_uint64(&child, out) ||
353 CBS_len(&child) != 0) {
354 return 0;
355 }
356 } else {
357 *out = default_value;
358 }
359 return 1;
360}
361
362int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
363 int default_value) {
364 CBS child, child2;
365 int present;
366 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
367 return 0;
368 }
369 if (present) {
370 uint8_t boolean;
371
372 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
373 CBS_len(&child2) != 1 ||
374 CBS_len(&child) != 0) {
375 return 0;
376 }
377
378 boolean = CBS_data(&child2)[0];
379 if (boolean == 0) {
380 *out = 0;
381 } else if (boolean == 0xff) {
382 *out = 1;
383 } else {
384 return 0;
385 }
386 } else {
387 *out = default_value;
388 }
389 return 1;
390}
diff --git a/src/lib/libssl/bytestring.h b/src/lib/libssl/bytestring.h
new file mode 100644
index 0000000000..3c4e8eaaf3
--- /dev/null
+++ b/src/lib/libssl/bytestring.h
@@ -0,0 +1,346 @@
1/* $OpenBSD: bytestring.h,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#ifndef OPENSSL_HEADER_BYTESTRING_H
18#define OPENSSL_HEADER_BYTESTRING_H
19
20#if defined(__cplusplus)
21extern "C" {
22#endif
23
24#include <sys/types.h>
25#include <stdint.h>
26
27#include <openssl/opensslconf.h>
28
29/* Bytestrings are used for parsing and building TLS and ASN.1 messages.
30 *
31 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
32 * provides utility functions for safely parsing length-prefixed structures
33 * like TLS and ASN.1 from it.
34 *
35 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
36 * provides utility functions for building length-prefixed messages. */
37
38
39/* CRYPTO ByteString */
40
41typedef struct cbs_st {
42 const uint8_t *data;
43 size_t len;
44} CBS;
45
46/* CBS_init sets |cbs| to point to |data|. It does not take ownership of
47 * |data|. */
48void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
49
50/* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
51 * otherwise. */
52int CBS_skip(CBS *cbs, size_t len);
53
54/* CBS_data returns a pointer to the contains of |cbs|. */
55const uint8_t *CBS_data(const CBS *cbs);
56
57/* CBS_len returns the number of bytes remaining in |cbs|. */
58size_t CBS_len(const CBS *cbs);
59
60/* CBS_stow copies the current contents of |cbs| into |*out_ptr| and
61 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
62 * OPENSSL_free. It returns one on success and zero on allocation failure. On
63 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty,
64 * |*out_ptr| will be NULL. */
65int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
66
67/* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
68 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
69 * with OPENSSL_free. It returns one on success and zero on allocation
70 * failure. On success, |*out_ptr| should be freed with OPENSSL_free.
71 *
72 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
73 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. */
74int CBS_strdup(const CBS *cbs, char **out_ptr);
75
76/* CBS_contains_zero_byte returns one if the current contents of |cbs| contains
77 * a NUL byte and zero otherwise. */
78int CBS_contains_zero_byte(const CBS *cbs);
79
80/* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
81 * starting at |data|. If they're equal, it returns one, otherwise zero. If the
82 * lengths match, it uses a constant-time comparison. */
83int CBS_mem_equal(const CBS *cbs, const uint8_t *data,
84 size_t len);
85
86/* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
87 * returns one on success and zero on error. */
88int CBS_get_u8(CBS *cbs, uint8_t *out);
89
90/* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
91 * advances |cbs|. It returns one on success and zero on error. */
92int CBS_get_u16(CBS *cbs, uint16_t *out);
93
94/* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
95 * advances |cbs|. It returns one on success and zero on error. */
96int CBS_get_u24(CBS *cbs, uint32_t *out);
97
98/* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
99 * and advances |cbs|. It returns one on success and zero on error. */
100int CBS_get_u32(CBS *cbs, uint32_t *out);
101
102/* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
103 * |cbs|. It returns one on success and zero on error. */
104int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
105
106/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
107 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one
108 * on success and zero on error. */
109int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
110
111/* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
112 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
113 * returns one on success and zero on error. */
114int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
115
116/* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
117 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
118 * returns one on success and zero on error. */
119int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
120
121
122/* Parsing ASN.1 */
123
124#define CBS_ASN1_BOOLEAN 0x1
125#define CBS_ASN1_INTEGER 0x2
126#define CBS_ASN1_BITSTRING 0x3
127#define CBS_ASN1_OCTETSTRING 0x4
128#define CBS_ASN1_OBJECT 0x6
129#define CBS_ASN1_ENUMERATED 0xa
130#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
131#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
132
133#define CBS_ASN1_CONSTRUCTED 0x20
134#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
135
136/* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
137 * including tag and length bytes) and advances |cbs| over it. The ASN.1
138 * element must match |tag_value|. It returns one on success and zero
139 * on error.
140 *
141 * Tag numbers greater than 31 are not supported. */
142int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
143
144/* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
145 * ASN.1 header bytes too. */
146int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
147
148/* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
149 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If
150 * |cbs| is empty or the tag does not match, it returns zero. Note: if
151 * it returns one, CBS_get_asn1 may still fail if the rest of the
152 * element is malformed. */
153int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
154
155/* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
156 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
157 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
158 * the element has indefinite length then |*out| will only contain the
159 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
160 * the value.
161 *
162 * Tag numbers greater than 31 are not supported. */
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
164 unsigned *out_tag,
165 size_t *out_header_len);
166
167/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
168 * and sets |*out| to its value. It returns one on success and zero on error,
169 * where error includes the integer being negative, or too large to represent
170 * in 64 bits. */
171int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
172
173/* CBS_get_optional_asn1 gets an optional explicitly-tagged element
174 * from |cbs| tagged with |tag| and sets |*out| to its contents. If
175 * present, it sets |*out_present| to one, otherwise zero. It returns
176 * one on success, whether or not the element was present, and zero on
177 * decode failure. */
178int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
179 unsigned tag);
180
181/* CBS_get_optional_asn1_octet_string gets an optional
182 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets
183 * |*out| to the string and |*out_present| to one. Otherwise, it sets
184 * |*out| to empty and |*out_present| to zero. |out_present| may be
185 * NULL. It returns one on success, whether or not the element was
186 * present, and zero on decode failure. */
187int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out,
188 int *out_present,
189 unsigned tag);
190
191/* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
192 * INTEGER from |cbs|. If present, it sets |*out| to the
193 * value. Otherwise, it sets |*out| to |default_value|. It returns one
194 * on success, whether or not the element was present, and zero on
195 * decode failure. */
196int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out,
197 unsigned tag,
198 uint64_t default_value);
199
200/* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
201 * |cbs|. If present, it sets |*out| to either zero or one, based on the
202 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
203 * success, whether or not the element was present, and zero on decode
204 * failure. */
205int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
206 int default_value);
207
208
209/* CRYPTO ByteBuilder.
210 *
211 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
212 * object is associated with a buffer and new buffers are created with
213 * |CBB_init|. Several |CBB| objects can point at the same buffer when a
214 * length-prefix is pending, however only a single |CBB| can be 'current' at
215 * any one time. For example, if one calls |CBB_add_u8_length_prefixed| then
216 * the new |CBB| points at the same buffer as the original. But if the original
217 * |CBB| is used then the length prefix is written out and the new |CBB| must
218 * not be used again.
219 *
220 * If one needs to force a length prefix to be written out because a |CBB| is
221 * going out of scope, use |CBB_flush|. */
222
223struct cbb_buffer_st {
224 uint8_t *buf;
225 size_t len; /* The number of valid bytes. */
226 size_t cap; /* The size of buf. */
227 char can_resize; /* One iff |buf| is owned by this object. If not then |buf|
228 cannot be resized. */
229};
230
231typedef struct cbb_st {
232 struct cbb_buffer_st *base;
233 /* offset is the offset from the start of |base->buf| to the position of any
234 * pending length-prefix. */
235 size_t offset;
236 /* child points to a child CBB if a length-prefix is pending. */
237 struct cbb_st *child;
238 /* pending_len_len contains the number of bytes in a pending length-prefix,
239 * or zero if no length-prefix is pending. */
240 uint8_t pending_len_len;
241 char pending_is_asn1;
242 /* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
243 * |CBB|). Top-level objects are valid arguments for |CBB_finish|. */
244 char is_top_level;
245} CBB;
246
247/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
248 * needed, the |initial_capacity| is just a hint. It returns one on success or
249 * zero on error. */
250int CBB_init(CBB *cbb, size_t initial_capacity);
251
252/* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
253 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB
254 * functions to fail. It returns one on success or zero on error. */
255int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
256
257/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
258 * writing to the same buffer. This should be used in an error case where a
259 * serialisation is abandoned. */
260void CBB_cleanup(CBB *cbb);
261
262/* CBB_finish completes any pending length prefix and sets |*out_data| to a
263 * malloced buffer and |*out_len| to the length of that buffer. The caller
264 * takes ownership of the buffer and, unless the buffer was fixed with
265 * |CBB_init_fixed|, must call |OPENSSL_free| when done.
266 *
267 * It can only be called on a "top level" |CBB|, i.e. one initialised with
268 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
269 * error. */
270int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
271
272/* CBB_flush causes any pending length prefixes to be written out and any child
273 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
274 * on error. */
275int CBB_flush(CBB *cbb);
276
277/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
278 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
279 * length. It returns one on success or zero on error. */
280int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
281
282/* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
283 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
284 * big-endian length. It returns one on success or zero on error. */
285int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
286
287/* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
288 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
289 * big-endian length. It returns one on success or zero on error. */
290int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
291
292/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
293 * ASN.1 object can be written. The |tag| argument will be used as the tag for
294 * the object. It returns one on success or zero on error. */
295int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
296
297/* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
298 * success and zero otherwise. */
299int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
300
301/* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
302 * the beginning of that space. The caller must then write |len| bytes of
303 * actual contents to |*out_data|. It returns one on success and zero
304 * otherwise. */
305int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
306
307/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
308 * success and zero otherwise. */
309int CBB_add_u8(CBB *cbb, uint8_t value);
310
311/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
312 * returns one on success and zero otherwise. */
313int CBB_add_u16(CBB *cbb, uint16_t value);
314
315/* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
316 * returns one on success and zero otherwise. */
317int CBB_add_u24(CBB *cbb, uint32_t value);
318
319/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
320 * and writes |value| in its contents. It returns one on success and zero on
321 * error. */
322int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
323
324#ifdef LIBRESSL_INTERNAL
325/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
326 * indefinite-length elements then it attempts to convert the BER data to DER
327 * and sets |*out| and |*out_length| to describe a malloced buffer containing
328 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
329 *
330 * If it doesn't find any indefinite-length elements then it sets |*out| to
331 * NULL and |*in| is unmodified.
332 *
333 * A sufficiently complex ASN.1 structure will break this function because it's
334 * not possible to generically convert BER to DER without knowledge of the
335 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
336 * from NSS.
337 *
338 * It returns one on success and zero otherwise. */
339int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
340#endif /* LIBRESSL_INTERNAL */
341
342#if defined(__cplusplus)
343} /* extern C */
344#endif
345
346#endif /* OPENSSL_HEADER_BYTESTRING_H */
diff --git a/src/lib/libssl/src/ssl/bs_ber.c b/src/lib/libssl/src/ssl/bs_ber.c
new file mode 100644
index 0000000000..b94b63e37e
--- /dev/null
+++ b/src/lib/libssl/src/ssl/bs_ber.c
@@ -0,0 +1,220 @@
1/* $OpenBSD: bs_ber.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <string.h>
18
19#include <openssl/opensslconf.h>
20
21#include "bytestring.h"
22
23/* kMaxDepth is a just a sanity limit. The code should be such that the length
24 * of the input being processes always decreases. None the less, a very large
25 * input could otherwise cause the stack to overflow. */
26static const unsigned kMaxDepth = 2048;
27
28/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
29 * depending on whether an indefinite length element was found. The value of
30 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
31 * and zero on error. */
32static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
33 CBS in;
34
35 if (depth > kMaxDepth) {
36 return 0;
37 }
38
39 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
40 *ber_found = 0;
41
42 while (CBS_len(&in) > 0) {
43 CBS contents;
44 unsigned tag;
45 size_t header_len;
46
47 if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) {
48 return 0;
49 }
50 if (CBS_len(&contents) == header_len &&
51 header_len > 0 &&
52 CBS_data(&contents)[header_len-1] == 0x80) {
53 *ber_found = 1;
54 return 1;
55 }
56 if (tag & CBS_ASN1_CONSTRUCTED) {
57 if (!CBS_skip(&contents, header_len) ||
58 !cbs_find_ber(&contents, ber_found, depth + 1)) {
59 return 0;
60 }
61 }
62 }
63
64 return 1;
65}
66
67/* is_primitive_type returns true if |tag| likely a primitive type. Normally
68 * one can just test the "constructed" bit in the tag but, in BER, even
69 * primitive tags can have the constructed bit if they have indefinite
70 * length. */
71static char is_primitive_type(unsigned tag) {
72 return (tag & 0xc0) == 0 &&
73 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
74 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
75}
76
77/* is_eoc returns true if |header_len| and |contents|, as returned by
78 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */
79static char is_eoc(size_t header_len, CBS *contents) {
80 return header_len == 2 && CBS_len(contents) == 2 &&
81 memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
82}
83
84/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
85 * |squash_header| is set then the top-level of elements from |in| will not
86 * have their headers written. This is used when concatenating the fragments of
87 * an indefinite length, primitive value. If |looking_for_eoc| is set then any
88 * EOC elements found will cause the function to return after consuming it.
89 * It returns one on success and zero on error. */
90static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
91 char looking_for_eoc, unsigned depth) {
92 if (depth > kMaxDepth) {
93 return 0;
94 }
95
96 while (CBS_len(in) > 0) {
97 CBS contents;
98 unsigned tag;
99 size_t header_len;
100 CBB *out_contents, out_contents_storage;
101
102 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) {
103 return 0;
104 }
105 out_contents = out;
106
107 if (CBS_len(&contents) == header_len) {
108 if (is_eoc(header_len, &contents)) {
109 return looking_for_eoc;
110 }
111
112 if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
113 /* This is an indefinite length element. If it's a SEQUENCE or SET then
114 * we just need to write the out the contents as normal, but with a
115 * concrete length prefix.
116 *
117 * If it's a something else then the contents will be a series of BER
118 * elements of the same type which need to be concatenated. */
119 const char context_specific = (tag & 0xc0) == 0x80;
120 char squash_child_headers = is_primitive_type(tag);
121
122 /* This is a hack, but it sufficies to handle NSS's output. If we find
123 * an indefinite length, context-specific tag with a definite, primtive
124 * tag inside it, then we assume that the context-specific tag is
125 * implicit and the tags within are fragments of a primitive type that
126 * need to be concatenated. */
127 if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
128 CBS in_copy, inner_contents;
129 unsigned inner_tag;
130 size_t inner_header_len;
131
132 CBS_init(&in_copy, CBS_data(in), CBS_len(in));
133 if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag,
134 &inner_header_len)) {
135 return 0;
136 }
137 if (CBS_len(&inner_contents) > inner_header_len &&
138 is_primitive_type(inner_tag)) {
139 squash_child_headers = 1;
140 }
141 }
142
143 if (!squash_header) {
144 unsigned out_tag = tag;
145 if (squash_child_headers) {
146 out_tag &= ~CBS_ASN1_CONSTRUCTED;
147 }
148 if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
149 return 0;
150 }
151 out_contents = &out_contents_storage;
152 }
153
154 if (!cbs_convert_ber(in, out_contents,
155 squash_child_headers,
156 1 /* looking for eoc */, depth + 1)) {
157 return 0;
158 }
159 if (out_contents != out && !CBB_flush(out)) {
160 return 0;
161 }
162 continue;
163 }
164 }
165
166 if (!squash_header) {
167 if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
168 return 0;
169 }
170 out_contents = &out_contents_storage;
171 }
172
173 if (!CBS_skip(&contents, header_len)) {
174 return 0;
175 }
176
177 if (tag & CBS_ASN1_CONSTRUCTED) {
178 if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
179 0 /* not looking for eoc */, depth + 1)) {
180 return 0;
181 }
182 } else {
183 if (!CBB_add_bytes(out_contents, CBS_data(&contents),
184 CBS_len(&contents))) {
185 return 0;
186 }
187 }
188
189 if (out_contents != out && !CBB_flush(out)) {
190 return 0;
191 }
192 }
193
194 return looking_for_eoc == 0;
195}
196
197int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) {
198 CBB cbb;
199
200 /* First, do a quick walk to find any indefinite-length elements. Most of the
201 * time we hope that there aren't any and thus we can quickly return. */
202 char conversion_needed;
203 if (!cbs_find_ber(in, &conversion_needed, 0)) {
204 return 0;
205 }
206
207 if (!conversion_needed) {
208 *out = NULL;
209 *out_len = 0;
210 return 1;
211 }
212
213 CBB_init(&cbb, CBS_len(in));
214 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
215 CBB_cleanup(&cbb);
216 return 0;
217 }
218
219 return CBB_finish(&cbb, out, out_len);
220}
diff --git a/src/lib/libssl/src/ssl/bs_cbb.c b/src/lib/libssl/src/ssl/bs_cbb.c
new file mode 100644
index 0000000000..668231c1c7
--- /dev/null
+++ b/src/lib/libssl/src/ssl/bs_cbb.c
@@ -0,0 +1,387 @@
1/* $OpenBSD: bs_cbb.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <assert.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <openssl/opensslconf.h>
22
23#include "bytestring.h"
24
25static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
26 struct cbb_buffer_st *base;
27
28 base = malloc(sizeof(struct cbb_buffer_st));
29 if (base == NULL) {
30 free(buf);
31 return 0;
32 }
33
34 base->buf = buf;
35 base->len = 0;
36 base->cap = cap;
37 base->can_resize = 1;
38
39 memset(cbb, 0, sizeof(CBB));
40 cbb->base = base;
41 cbb->is_top_level = 1;
42 return 1;
43}
44
45int CBB_init(CBB *cbb, size_t initial_capacity) {
46 uint8_t *buf;
47
48 buf = malloc(initial_capacity);
49 if (initial_capacity > 0 && buf == NULL) {
50 return 0;
51 }
52
53 return cbb_init(cbb, buf, initial_capacity);
54}
55
56int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
57 if (!cbb_init(cbb, buf, len)) {
58 return 0;
59 }
60
61 cbb->base->can_resize = 0;
62 return 1;
63}
64
65void CBB_cleanup(CBB *cbb) {
66 if (cbb->base) {
67 if (cbb->base->buf && cbb->base->can_resize) {
68 free(cbb->base->buf);
69 }
70 free(cbb->base);
71 }
72 cbb->base = NULL;
73}
74
75static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
76 size_t len) {
77 size_t newlen;
78
79 if (base == NULL) {
80 return 0;
81 }
82
83#if 0
84 // XXX Added for boringssl patch testing
85 if (len == 0) {
86 if (out) {
87 *out = NULL;
88 }
89 return 1;
90 }
91#endif
92
93 newlen = base->len + len;
94 if (newlen < base->len) {
95 /* Overflow */
96 return 0;
97 }
98
99 if (newlen > base->cap) {
100 size_t newcap = base->cap * 2;
101 uint8_t *newbuf;
102
103 if (!base->can_resize) {
104 return 0;
105 }
106
107 if (newcap < base->cap || newcap < newlen) {
108 newcap = newlen;
109 }
110 newbuf = realloc(base->buf, newcap);
111 if (newbuf == NULL) {
112 return 0;
113 }
114
115 base->buf = newbuf;
116 base->cap = newcap;
117 }
118
119 if (out) {
120 *out = base->buf + base->len;
121 }
122 base->len = newlen;
123 return 1;
124}
125
126static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v,
127 size_t len_len) {
128 uint8_t *buf;
129 size_t i;
130
131 if (len_len == 0) {
132 return 1;
133 }
134 if (!cbb_buffer_add(base, &buf, len_len)) {
135 return 0;
136 }
137
138 for (i = len_len - 1; i < len_len; i--) {
139 buf[i] = v;
140 v >>= 8;
141 }
142 return 1;
143}
144
145int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
146 if (!cbb->is_top_level) {
147 return 0;
148 }
149
150 if (!CBB_flush(cbb)) {
151 return 0;
152 }
153
154 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) {
155 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */
156 return 0;
157 }
158
159 if (out_data != NULL) {
160 *out_data = cbb->base->buf;
161 }
162 if (out_len != NULL) {
163 *out_len = cbb->base->len;
164 }
165 cbb->base->buf = NULL;
166 CBB_cleanup(cbb);
167 return 1;
168}
169
170/* CBB_flush recurses and then writes out any pending length prefix. The
171 * current length of the underlying base is taken to be the length of the
172 * length-prefixed data. */
173int CBB_flush(CBB *cbb) {
174 size_t child_start, i, len;
175
176 if (cbb->base == NULL) {
177 return 0;
178 }
179
180 if (cbb->child == NULL || cbb->pending_len_len == 0) {
181 return 1;
182 }
183
184 child_start = cbb->offset + cbb->pending_len_len;
185
186 if (!CBB_flush(cbb->child) ||
187 child_start < cbb->offset ||
188 cbb->base->len < child_start) {
189 return 0;
190 }
191
192 len = cbb->base->len - child_start;
193
194 if (cbb->pending_is_asn1) {
195 /* For ASN.1 we assume that we'll only need a single byte for the length.
196 * If that turned out to be incorrect, we have to move the contents along
197 * in order to make space. */
198 size_t len_len;
199 uint8_t initial_length_byte;
200
201 assert (cbb->pending_len_len == 1);
202
203 if (len > 0xfffffffe) {
204 /* Too large. */
205 return 0;
206 } else if (len > 0xffffff) {
207 len_len = 5;
208 initial_length_byte = 0x80 | 4;
209 } else if (len > 0xffff) {
210 len_len = 4;
211 initial_length_byte = 0x80 | 3;
212 } else if (len > 0xff) {
213 len_len = 3;
214 initial_length_byte = 0x80 | 2;
215 } else if (len > 0x7f) {
216 len_len = 2;
217 initial_length_byte = 0x80 | 1;
218 } else {
219 len_len = 1;
220 initial_length_byte = len;
221 len = 0;
222 }
223
224 if (len_len != 1) {
225 /* We need to move the contents along in order to make space. */
226 size_t extra_bytes = len_len - 1;
227 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) {
228 return 0;
229 }
230 memmove(cbb->base->buf + child_start + extra_bytes,
231 cbb->base->buf + child_start, len);
232 }
233 cbb->base->buf[cbb->offset++] = initial_length_byte;
234 cbb->pending_len_len = len_len - 1;
235 }
236
237 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
238 cbb->base->buf[cbb->offset + i] = len;
239 len >>= 8;
240 }
241 if (len != 0) {
242 return 0;
243 }
244
245 cbb->child->base = NULL;
246 cbb->child = NULL;
247 cbb->pending_len_len = 0;
248 cbb->pending_is_asn1 = 0;
249 cbb->offset = 0;
250
251 return 1;
252}
253
254
255static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
256 size_t len_len) {
257 uint8_t *prefix_bytes;
258
259 if (!CBB_flush(cbb)) {
260 return 0;
261 }
262
263 cbb->offset = cbb->base->len;
264 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
265 return 0;
266 }
267
268 memset(prefix_bytes, 0, len_len);
269 memset(out_contents, 0, sizeof(CBB));
270 out_contents->base = cbb->base;
271 cbb->child = out_contents;
272 cbb->pending_len_len = len_len;
273 cbb->pending_is_asn1 = 0;
274
275 return 1;
276}
277
278int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) {
279 return cbb_add_length_prefixed(cbb, out_contents, 1);
280}
281
282int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) {
283 return cbb_add_length_prefixed(cbb, out_contents, 2);
284}
285
286int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
287 return cbb_add_length_prefixed(cbb, out_contents, 3);
288}
289
290int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
291 if (!CBB_flush(cbb) ||
292 !CBB_add_u8(cbb, tag)) {
293 return 0;
294 }
295
296 cbb->offset = cbb->base->len;
297 if (!CBB_add_u8(cbb, 0)) {
298 return 0;
299 }
300
301 memset(out_contents, 0, sizeof(CBB));
302 out_contents->base = cbb->base;
303 cbb->child = out_contents;
304 cbb->pending_len_len = 1;
305 cbb->pending_is_asn1 = 1;
306
307 return 1;
308}
309
310int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
311 uint8_t *dest;
312
313 if (!CBB_flush(cbb) ||
314 !cbb_buffer_add(cbb->base, &dest, len)) {
315 return 0;
316 }
317 memcpy(dest, data, len);
318 return 1;
319}
320
321int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
322 if (!CBB_flush(cbb) ||
323 !cbb_buffer_add(cbb->base, out_data, len)) {
324 return 0;
325 }
326 return 1;
327}
328
329int CBB_add_u8(CBB *cbb, uint8_t value) {
330 if (!CBB_flush(cbb)) {
331 return 0;
332 }
333
334 return cbb_buffer_add_u(cbb->base, value, 1);
335}
336
337int CBB_add_u16(CBB *cbb, uint16_t value) {
338 if (!CBB_flush(cbb)) {
339 return 0;
340 }
341
342 return cbb_buffer_add_u(cbb->base, value, 2);
343}
344
345int CBB_add_u24(CBB *cbb, uint32_t value) {
346 if (!CBB_flush(cbb)) {
347 return 0;
348 }
349
350 return cbb_buffer_add_u(cbb->base, value, 3);
351}
352
353int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
354 CBB child;
355 size_t i;
356 int started = 0;
357
358 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
359 return 0;
360 }
361
362 for (i = 0; i < 8; i++) {
363 uint8_t byte = (value >> 8*(7-i)) & 0xff;
364 if (!started) {
365 if (byte == 0) {
366 /* Don't encode leading zeros. */
367 continue;
368 }
369 /* If the high bit is set, add a padding byte to make it
370 * unsigned. */
371 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) {
372 return 0;
373 }
374 started = 1;
375 }
376 if (!CBB_add_u8(&child, byte)) {
377 return 0;
378 }
379 }
380
381 /* 0 is encoded as a single 0, not the empty string. */
382 if (!started && !CBB_add_u8(&child, 0)) {
383 return 0;
384 }
385
386 return CBB_flush(cbb);
387}
diff --git a/src/lib/libssl/src/ssl/bs_cbs.c b/src/lib/libssl/src/ssl/bs_cbs.c
new file mode 100644
index 0000000000..7edfe65288
--- /dev/null
+++ b/src/lib/libssl/src/ssl/bs_cbs.c
@@ -0,0 +1,390 @@
1/* $OpenBSD: bs_cbs.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#include <assert.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <openssl/opensslconf.h>
22#include <openssl/buffer.h>
23#include <openssl/crypto.h>
24
25#include "bytestring.h"
26
27void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
28 cbs->data = data;
29 cbs->len = len;
30}
31
32static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
33 if (cbs->len < n) {
34 return 0;
35 }
36
37 *p = cbs->data;
38 cbs->data += n;
39 cbs->len -= n;
40 return 1;
41}
42
43int CBS_skip(CBS *cbs, size_t len) {
44 const uint8_t *dummy;
45 return cbs_get(cbs, &dummy, len);
46}
47
48const uint8_t *CBS_data(const CBS *cbs) {
49 return cbs->data;
50}
51
52size_t CBS_len(const CBS *cbs) {
53 return cbs->len;
54}
55
56int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
57 if (*out_ptr != NULL) {
58 free(*out_ptr);
59 *out_ptr = NULL;
60 }
61 *out_len = 0;
62
63 if (cbs->len == 0) {
64 return 1;
65 }
66 *out_ptr = BUF_memdup(cbs->data, cbs->len);
67 if (*out_ptr == NULL) {
68 return 0;
69 }
70 *out_len = cbs->len;
71 return 1;
72}
73
74int CBS_strdup(const CBS *cbs, char **out_ptr) {
75 if (*out_ptr != NULL) {
76 free(*out_ptr);
77 }
78 *out_ptr = strndup((const char*)cbs->data, cbs->len);
79 return (*out_ptr != NULL);
80}
81
82int CBS_contains_zero_byte(const CBS *cbs) {
83 return memchr(cbs->data, 0, cbs->len) != NULL;
84}
85
86int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
87 if (len != cbs->len)
88 return 0;
89 return CRYPTO_memcmp(cbs->data, data, len) == 0;
90}
91
92static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
93 uint32_t result = 0;
94 size_t i;
95 const uint8_t *data;
96
97 if (!cbs_get(cbs, &data, len)) {
98 return 0;
99 }
100 for (i = 0; i < len; i++) {
101 result <<= 8;
102 result |= data[i];
103 }
104 *out = result;
105 return 1;
106}
107
108int CBS_get_u8(CBS *cbs, uint8_t *out) {
109 const uint8_t *v;
110 if (!cbs_get(cbs, &v, 1)) {
111 return 0;
112 }
113 *out = *v;
114 return 1;
115}
116
117int CBS_get_u16(CBS *cbs, uint16_t *out) {
118 uint32_t v;
119 if (!cbs_get_u(cbs, &v, 2)) {
120 return 0;
121 }
122 *out = v;
123 return 1;
124}
125
126int CBS_get_u24(CBS *cbs, uint32_t *out) {
127 return cbs_get_u(cbs, out, 3);
128}
129
130int CBS_get_u32(CBS *cbs, uint32_t *out) {
131 return cbs_get_u(cbs, out, 4);
132}
133
134int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
135 const uint8_t *v;
136 if (!cbs_get(cbs, &v, len)) {
137 return 0;
138 }
139 CBS_init(out, v, len);
140 return 1;
141}
142
143static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
144 uint32_t len;
145 if (!cbs_get_u(cbs, &len, len_len)) {
146 return 0;
147 }
148 return CBS_get_bytes(cbs, out, len);
149}
150
151int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
152 return cbs_get_length_prefixed(cbs, out, 1);
153}
154
155int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
156 return cbs_get_length_prefixed(cbs, out, 2);
157}
158
159int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
160 return cbs_get_length_prefixed(cbs, out, 3);
161}
162
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
164 size_t *out_header_len) {
165 uint8_t tag, length_byte;
166 CBS header = *cbs;
167 CBS throwaway;
168
169 if (out == NULL) {
170 out = &throwaway;
171 }
172
173 if (!CBS_get_u8(&header, &tag) ||
174 !CBS_get_u8(&header, &length_byte)) {
175 return 0;
176 }
177
178 if ((tag & 0x1f) == 0x1f) {
179 /* Long form tags are not supported. */
180 return 0;
181 }
182
183 if (out_tag != NULL) {
184 *out_tag = tag;
185 }
186
187 size_t len;
188 if ((length_byte & 0x80) == 0) {
189 /* Short form length. */
190 len = ((size_t) length_byte) + 2;
191 if (out_header_len != NULL) {
192 *out_header_len = 2;
193 }
194 } else {
195 /* Long form length. */
196 const size_t num_bytes = length_byte & 0x7f;
197 uint32_t len32;
198
199 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
200 /* indefinite length */
201 *out_header_len = 2;
202 return CBS_get_bytes(cbs, out, 2);
203 }
204
205 if (num_bytes == 0 || num_bytes > 4) {
206 return 0;
207 }
208 if (!cbs_get_u(&header, &len32, num_bytes)) {
209 return 0;
210 }
211 if (len32 < 128) {
212 /* Length should have used short-form encoding. */
213 return 0;
214 }
215 if ((len32 >> ((num_bytes-1)*8)) == 0) {
216 /* Length should have been at least one byte shorter. */
217 return 0;
218 }
219 len = len32;
220 if (len + 2 + num_bytes < len) {
221 /* Overflow. */
222 return 0;
223 }
224 len += 2 + num_bytes;
225 if (out_header_len != NULL) {
226 *out_header_len = 2 + num_bytes;
227 }
228 }
229
230 return CBS_get_bytes(cbs, out, len);
231}
232
233static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
234 int skip_header) {
235 size_t header_len;
236 unsigned tag;
237 CBS throwaway;
238
239 if (out == NULL) {
240 out = &throwaway;
241 }
242
243 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
244 tag != tag_value ||
245 (header_len > 0 &&
246 /* This ensures that the tag is either zero length or
247 * indefinite-length. */
248 CBS_len(out) == header_len &&
249 CBS_data(out)[header_len - 1] == 0x80)) {
250 return 0;
251 }
252
253 if (skip_header && !CBS_skip(out, header_len)) {
254 assert(0);
255 return 0;
256 }
257
258 return 1;
259}
260
261int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
262 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
263}
264
265int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
266 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
267}
268
269int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
270 if (CBS_len(cbs) < 1) {
271 return 0;
272 }
273 return CBS_data(cbs)[0] == tag_value;
274}
275
276int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
277 CBS bytes;
278 const uint8_t *data;
279 size_t i, len;
280
281 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
282 return 0;
283 }
284
285 *out = 0;
286 data = CBS_data(&bytes);
287 len = CBS_len(&bytes);
288
289 if (len == 0) {
290 /* An INTEGER is encoded with at least one octet. */
291 return 0;
292 }
293
294 if ((data[0] & 0x80) != 0) {
295 /* negative number */
296 return 0;
297 }
298
299 for (i = 0; i < len; i++) {
300 if ((*out >> 56) != 0) {
301 /* Too large to represent as a uint64_t. */
302 return 0;
303 }
304 *out <<= 8;
305 *out |= data[i];
306 }
307
308 return 1;
309}
310
311int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
312 if (CBS_peek_asn1_tag(cbs, tag)) {
313 if (!CBS_get_asn1(cbs, out, tag)) {
314 return 0;
315 }
316 *out_present = 1;
317 } else {
318 *out_present = 0;
319 }
320 return 1;
321}
322
323int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
324 unsigned tag) {
325 CBS child;
326 int present;
327 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
328 return 0;
329 }
330 if (present) {
331 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
332 CBS_len(&child) != 0) {
333 return 0;
334 }
335 } else {
336 CBS_init(out, NULL, 0);
337 }
338 if (out_present) {
339 *out_present = present;
340 }
341 return 1;
342}
343
344int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
345 uint64_t default_value) {
346 CBS child;
347 int present;
348 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
349 return 0;
350 }
351 if (present) {
352 if (!CBS_get_asn1_uint64(&child, out) ||
353 CBS_len(&child) != 0) {
354 return 0;
355 }
356 } else {
357 *out = default_value;
358 }
359 return 1;
360}
361
362int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
363 int default_value) {
364 CBS child, child2;
365 int present;
366 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
367 return 0;
368 }
369 if (present) {
370 uint8_t boolean;
371
372 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
373 CBS_len(&child2) != 1 ||
374 CBS_len(&child) != 0) {
375 return 0;
376 }
377
378 boolean = CBS_data(&child2)[0];
379 if (boolean == 0) {
380 *out = 0;
381 } else if (boolean == 0xff) {
382 *out = 1;
383 } else {
384 return 0;
385 }
386 } else {
387 *out = default_value;
388 }
389 return 1;
390}
diff --git a/src/lib/libssl/src/ssl/bytestring.h b/src/lib/libssl/src/ssl/bytestring.h
new file mode 100644
index 0000000000..3c4e8eaaf3
--- /dev/null
+++ b/src/lib/libssl/src/ssl/bytestring.h
@@ -0,0 +1,346 @@
1/* $OpenBSD: bytestring.h,v 1.1 2015/02/06 09:36:16 doug Exp $ */
2/*
3 * Copyright (c) 2014, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17#ifndef OPENSSL_HEADER_BYTESTRING_H
18#define OPENSSL_HEADER_BYTESTRING_H
19
20#if defined(__cplusplus)
21extern "C" {
22#endif
23
24#include <sys/types.h>
25#include <stdint.h>
26
27#include <openssl/opensslconf.h>
28
29/* Bytestrings are used for parsing and building TLS and ASN.1 messages.
30 *
31 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
32 * provides utility functions for safely parsing length-prefixed structures
33 * like TLS and ASN.1 from it.
34 *
35 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
36 * provides utility functions for building length-prefixed messages. */
37
38
39/* CRYPTO ByteString */
40
41typedef struct cbs_st {
42 const uint8_t *data;
43 size_t len;
44} CBS;
45
46/* CBS_init sets |cbs| to point to |data|. It does not take ownership of
47 * |data|. */
48void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
49
50/* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
51 * otherwise. */
52int CBS_skip(CBS *cbs, size_t len);
53
54/* CBS_data returns a pointer to the contains of |cbs|. */
55const uint8_t *CBS_data(const CBS *cbs);
56
57/* CBS_len returns the number of bytes remaining in |cbs|. */
58size_t CBS_len(const CBS *cbs);
59
60/* CBS_stow copies the current contents of |cbs| into |*out_ptr| and
61 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
62 * OPENSSL_free. It returns one on success and zero on allocation failure. On
63 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty,
64 * |*out_ptr| will be NULL. */
65int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
66
67/* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
68 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
69 * with OPENSSL_free. It returns one on success and zero on allocation
70 * failure. On success, |*out_ptr| should be freed with OPENSSL_free.
71 *
72 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
73 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. */
74int CBS_strdup(const CBS *cbs, char **out_ptr);
75
76/* CBS_contains_zero_byte returns one if the current contents of |cbs| contains
77 * a NUL byte and zero otherwise. */
78int CBS_contains_zero_byte(const CBS *cbs);
79
80/* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
81 * starting at |data|. If they're equal, it returns one, otherwise zero. If the
82 * lengths match, it uses a constant-time comparison. */
83int CBS_mem_equal(const CBS *cbs, const uint8_t *data,
84 size_t len);
85
86/* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
87 * returns one on success and zero on error. */
88int CBS_get_u8(CBS *cbs, uint8_t *out);
89
90/* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
91 * advances |cbs|. It returns one on success and zero on error. */
92int CBS_get_u16(CBS *cbs, uint16_t *out);
93
94/* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
95 * advances |cbs|. It returns one on success and zero on error. */
96int CBS_get_u24(CBS *cbs, uint32_t *out);
97
98/* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
99 * and advances |cbs|. It returns one on success and zero on error. */
100int CBS_get_u32(CBS *cbs, uint32_t *out);
101
102/* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
103 * |cbs|. It returns one on success and zero on error. */
104int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
105
106/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
107 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one
108 * on success and zero on error. */
109int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
110
111/* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
112 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
113 * returns one on success and zero on error. */
114int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
115
116/* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
117 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
118 * returns one on success and zero on error. */
119int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
120
121
122/* Parsing ASN.1 */
123
124#define CBS_ASN1_BOOLEAN 0x1
125#define CBS_ASN1_INTEGER 0x2
126#define CBS_ASN1_BITSTRING 0x3
127#define CBS_ASN1_OCTETSTRING 0x4
128#define CBS_ASN1_OBJECT 0x6
129#define CBS_ASN1_ENUMERATED 0xa
130#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
131#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
132
133#define CBS_ASN1_CONSTRUCTED 0x20
134#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
135
136/* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
137 * including tag and length bytes) and advances |cbs| over it. The ASN.1
138 * element must match |tag_value|. It returns one on success and zero
139 * on error.
140 *
141 * Tag numbers greater than 31 are not supported. */
142int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
143
144/* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
145 * ASN.1 header bytes too. */
146int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
147
148/* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
149 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If
150 * |cbs| is empty or the tag does not match, it returns zero. Note: if
151 * it returns one, CBS_get_asn1 may still fail if the rest of the
152 * element is malformed. */
153int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
154
155/* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
156 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
157 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
158 * the element has indefinite length then |*out| will only contain the
159 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
160 * the value.
161 *
162 * Tag numbers greater than 31 are not supported. */
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
164 unsigned *out_tag,
165 size_t *out_header_len);
166
167/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
168 * and sets |*out| to its value. It returns one on success and zero on error,
169 * where error includes the integer being negative, or too large to represent
170 * in 64 bits. */
171int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
172
173/* CBS_get_optional_asn1 gets an optional explicitly-tagged element
174 * from |cbs| tagged with |tag| and sets |*out| to its contents. If
175 * present, it sets |*out_present| to one, otherwise zero. It returns
176 * one on success, whether or not the element was present, and zero on
177 * decode failure. */
178int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
179 unsigned tag);
180
181/* CBS_get_optional_asn1_octet_string gets an optional
182 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets
183 * |*out| to the string and |*out_present| to one. Otherwise, it sets
184 * |*out| to empty and |*out_present| to zero. |out_present| may be
185 * NULL. It returns one on success, whether or not the element was
186 * present, and zero on decode failure. */
187int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out,
188 int *out_present,
189 unsigned tag);
190
191/* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
192 * INTEGER from |cbs|. If present, it sets |*out| to the
193 * value. Otherwise, it sets |*out| to |default_value|. It returns one
194 * on success, whether or not the element was present, and zero on
195 * decode failure. */
196int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out,
197 unsigned tag,
198 uint64_t default_value);
199
200/* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
201 * |cbs|. If present, it sets |*out| to either zero or one, based on the
202 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
203 * success, whether or not the element was present, and zero on decode
204 * failure. */
205int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
206 int default_value);
207
208
209/* CRYPTO ByteBuilder.
210 *
211 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
212 * object is associated with a buffer and new buffers are created with
213 * |CBB_init|. Several |CBB| objects can point at the same buffer when a
214 * length-prefix is pending, however only a single |CBB| can be 'current' at
215 * any one time. For example, if one calls |CBB_add_u8_length_prefixed| then
216 * the new |CBB| points at the same buffer as the original. But if the original
217 * |CBB| is used then the length prefix is written out and the new |CBB| must
218 * not be used again.
219 *
220 * If one needs to force a length prefix to be written out because a |CBB| is
221 * going out of scope, use |CBB_flush|. */
222
223struct cbb_buffer_st {
224 uint8_t *buf;
225 size_t len; /* The number of valid bytes. */
226 size_t cap; /* The size of buf. */
227 char can_resize; /* One iff |buf| is owned by this object. If not then |buf|
228 cannot be resized. */
229};
230
231typedef struct cbb_st {
232 struct cbb_buffer_st *base;
233 /* offset is the offset from the start of |base->buf| to the position of any
234 * pending length-prefix. */
235 size_t offset;
236 /* child points to a child CBB if a length-prefix is pending. */
237 struct cbb_st *child;
238 /* pending_len_len contains the number of bytes in a pending length-prefix,
239 * or zero if no length-prefix is pending. */
240 uint8_t pending_len_len;
241 char pending_is_asn1;
242 /* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
243 * |CBB|). Top-level objects are valid arguments for |CBB_finish|. */
244 char is_top_level;
245} CBB;
246
247/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
248 * needed, the |initial_capacity| is just a hint. It returns one on success or
249 * zero on error. */
250int CBB_init(CBB *cbb, size_t initial_capacity);
251
252/* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
253 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB
254 * functions to fail. It returns one on success or zero on error. */
255int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
256
257/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
258 * writing to the same buffer. This should be used in an error case where a
259 * serialisation is abandoned. */
260void CBB_cleanup(CBB *cbb);
261
262/* CBB_finish completes any pending length prefix and sets |*out_data| to a
263 * malloced buffer and |*out_len| to the length of that buffer. The caller
264 * takes ownership of the buffer and, unless the buffer was fixed with
265 * |CBB_init_fixed|, must call |OPENSSL_free| when done.
266 *
267 * It can only be called on a "top level" |CBB|, i.e. one initialised with
268 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
269 * error. */
270int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
271
272/* CBB_flush causes any pending length prefixes to be written out and any child
273 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
274 * on error. */
275int CBB_flush(CBB *cbb);
276
277/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
278 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
279 * length. It returns one on success or zero on error. */
280int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
281
282/* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
283 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
284 * big-endian length. It returns one on success or zero on error. */
285int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
286
287/* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
288 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
289 * big-endian length. It returns one on success or zero on error. */
290int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
291
292/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
293 * ASN.1 object can be written. The |tag| argument will be used as the tag for
294 * the object. It returns one on success or zero on error. */
295int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
296
297/* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
298 * success and zero otherwise. */
299int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
300
301/* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
302 * the beginning of that space. The caller must then write |len| bytes of
303 * actual contents to |*out_data|. It returns one on success and zero
304 * otherwise. */
305int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
306
307/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
308 * success and zero otherwise. */
309int CBB_add_u8(CBB *cbb, uint8_t value);
310
311/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
312 * returns one on success and zero otherwise. */
313int CBB_add_u16(CBB *cbb, uint16_t value);
314
315/* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
316 * returns one on success and zero otherwise. */
317int CBB_add_u24(CBB *cbb, uint32_t value);
318
319/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
320 * and writes |value| in its contents. It returns one on success and zero on
321 * error. */
322int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
323
324#ifdef LIBRESSL_INTERNAL
325/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
326 * indefinite-length elements then it attempts to convert the BER data to DER
327 * and sets |*out| and |*out_length| to describe a malloced buffer containing
328 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
329 *
330 * If it doesn't find any indefinite-length elements then it sets |*out| to
331 * NULL and |*in| is unmodified.
332 *
333 * A sufficiently complex ASN.1 structure will break this function because it's
334 * not possible to generically convert BER to DER without knowledge of the
335 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
336 * from NSS.
337 *
338 * It returns one on success and zero otherwise. */
339int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
340#endif /* LIBRESSL_INTERNAL */
341
342#if defined(__cplusplus)
343} /* extern C */
344#endif
345
346#endif /* OPENSSL_HEADER_BYTESTRING_H */
diff --git a/src/lib/libssl/ssl/Makefile b/src/lib/libssl/ssl/Makefile
index 226ba681b6..c8f954d43e 100644
--- a/src/lib/libssl/ssl/Makefile
+++ b/src/lib/libssl/ssl/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.47 2014/07/12 03:27:23 deraadt Exp $ 1# $OpenBSD: Makefile,v 1.48 2015/02/06 09:36:16 doug Exp $
2 2
3LIB= ssl 3LIB= ssl
4 4
@@ -27,6 +27,7 @@ SRCS=\
27 bio_ssl.c ssl_err.c t1_reneg.c \ 27 bio_ssl.c ssl_err.c t1_reneg.c \
28 pqueue.c 28 pqueue.c
29SRCS+= s3_cbc.c 29SRCS+= s3_cbc.c
30SRCS+= bs_ber.c bs_cbb.c bs_cbs.c
30 31
31HDRS= srtp.h ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h 32HDRS= srtp.h ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h
32 33