summaryrefslogtreecommitdiff
path: root/src/lib/libssl/bs_cbs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/bs_cbs.c')
-rw-r--r--src/lib/libssl/bs_cbs.c439
1 files changed, 0 insertions, 439 deletions
diff --git a/src/lib/libssl/bs_cbs.c b/src/lib/libssl/bs_cbs.c
deleted file mode 100644
index c3d3a8abf2..0000000000
--- a/src/lib/libssl/bs_cbs.c
+++ /dev/null
@@ -1,439 +0,0 @@
1/* $OpenBSD: bs_cbs.c,v 1.2 2015/02/06 22:22:33 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
28CBS_init(CBS *cbs, const uint8_t *data, size_t len)
29{
30 cbs->data = data;
31 cbs->len = len;
32}
33
34static int
35cbs_get(CBS *cbs, const uint8_t **p, size_t n)
36{
37 if (cbs->len < n)
38 return 0;
39
40 *p = cbs->data;
41 cbs->data += n;
42 cbs->len -= n;
43 return 1;
44}
45
46int
47CBS_skip(CBS *cbs, size_t len)
48{
49 const uint8_t *dummy;
50 return cbs_get(cbs, &dummy, len);
51}
52
53const uint8_t *
54CBS_data(const CBS *cbs)
55{
56 return cbs->data;
57}
58
59size_t
60CBS_len(const CBS *cbs)
61{
62 return cbs->len;
63}
64
65int
66CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
67{
68 if (*out_ptr != NULL) {
69 free(*out_ptr);
70 *out_ptr = NULL;
71 }
72 *out_len = 0;
73
74 if (cbs->len == 0)
75 return 1;
76
77 *out_ptr = BUF_memdup(cbs->data, cbs->len);
78 if (*out_ptr == NULL)
79 return 0;
80
81 *out_len = cbs->len;
82 return 1;
83}
84
85int
86CBS_strdup(const CBS *cbs, char **out_ptr)
87{
88 if (*out_ptr != NULL)
89 free(*out_ptr);
90
91 *out_ptr = strndup((const char*)cbs->data, cbs->len);
92 return (*out_ptr != NULL);
93}
94
95int
96CBS_contains_zero_byte(const CBS *cbs)
97{
98 return memchr(cbs->data, 0, cbs->len) != NULL;
99}
100
101int
102CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
103{
104 if (len != cbs->len)
105 return 0;
106
107 return CRYPTO_memcmp(cbs->data, data, len) == 0;
108}
109
110static int
111cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
112{
113 uint32_t result = 0;
114 size_t i;
115 const uint8_t *data;
116
117 if (!cbs_get(cbs, &data, len))
118 return 0;
119
120 for (i = 0; i < len; i++) {
121 result <<= 8;
122 result |= data[i];
123 }
124 *out = result;
125 return 1;
126}
127
128int
129CBS_get_u8(CBS *cbs, uint8_t *out)
130{
131 const uint8_t *v;
132
133 if (!cbs_get(cbs, &v, 1))
134 return 0;
135
136 *out = *v;
137 return 1;
138}
139
140int
141CBS_get_u16(CBS *cbs, uint16_t *out)
142{
143 uint32_t v;
144
145 if (!cbs_get_u(cbs, &v, 2))
146 return 0;
147
148 *out = v;
149 return 1;
150}
151
152int
153CBS_get_u24(CBS *cbs, uint32_t *out)
154{
155 return cbs_get_u(cbs, out, 3);
156}
157
158int
159CBS_get_u32(CBS *cbs, uint32_t *out)
160{
161 return cbs_get_u(cbs, out, 4);
162}
163
164int
165CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
166{
167 const uint8_t *v;
168
169 if (!cbs_get(cbs, &v, len))
170 return 0;
171
172 CBS_init(out, v, len);
173 return 1;
174}
175
176static int
177cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
178{
179 uint32_t len;
180
181 if (!cbs_get_u(cbs, &len, len_len))
182 return 0;
183
184 return CBS_get_bytes(cbs, out, len);
185}
186
187int
188CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
189{
190 return cbs_get_length_prefixed(cbs, out, 1);
191}
192
193int
194CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
195{
196 return cbs_get_length_prefixed(cbs, out, 2);
197}
198
199int
200CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
201{
202 return cbs_get_length_prefixed(cbs, out, 3);
203}
204
205int
206CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
207 size_t *out_header_len)
208{
209 uint8_t tag, length_byte;
210 CBS header = *cbs;
211 CBS throwaway;
212
213 if (out == NULL)
214 out = &throwaway;
215
216 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
217 return 0;
218
219 if ((tag & 0x1f) == 0x1f)
220 /* Long form tags are not supported. */
221 return 0;
222
223 if (out_tag != NULL)
224 *out_tag = tag;
225
226 size_t len;
227 if ((length_byte & 0x80) == 0) {
228 /* Short form length. */
229 len = ((size_t) length_byte) + 2;
230 if (out_header_len != NULL)
231 *out_header_len = 2;
232
233 } else {
234 /* Long form length. */
235 const size_t num_bytes = length_byte & 0x7f;
236 uint32_t len32;
237
238 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
239 /* indefinite length */
240 *out_header_len = 2;
241 return CBS_get_bytes(cbs, out, 2);
242 }
243
244 if (num_bytes == 0 || num_bytes > 4)
245 return 0;
246
247 if (!cbs_get_u(&header, &len32, num_bytes))
248 return 0;
249
250 if (len32 < 128)
251 /* Length should have used short-form encoding. */
252 return 0;
253
254 if ((len32 >> ((num_bytes-1)*8)) == 0)
255 /* Length should have been at least one byte shorter. */
256 return 0;
257
258 len = len32;
259 if (len + 2 + num_bytes < len)
260 /* Overflow. */
261 return 0;
262
263 len += 2 + num_bytes;
264 if (out_header_len != NULL)
265 *out_header_len = 2 + num_bytes;
266 }
267
268 return CBS_get_bytes(cbs, out, len);
269}
270
271static int
272cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, int skip_header)
273{
274 size_t header_len;
275 unsigned tag;
276 CBS throwaway;
277
278 if (out == NULL)
279 out = &throwaway;
280
281 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
282 tag != tag_value || (header_len > 0 &&
283 /*
284 * This ensures that the tag is either zero length or
285 * indefinite-length.
286 */
287 CBS_len(out) == header_len &&
288 CBS_data(out)[header_len - 1] == 0x80))
289 return 0;
290
291 if (skip_header && !CBS_skip(out, header_len)) {
292 assert(0);
293 return 0;
294 }
295
296 return 1;
297}
298
299int
300CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value)
301{
302 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
303}
304
305int
306CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value)
307{
308 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
309}
310
311int
312CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value)
313{
314 if (CBS_len(cbs) < 1)
315 return 0;
316
317 return CBS_data(cbs)[0] == tag_value;
318}
319
320int
321CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
322{
323 CBS bytes;
324 const uint8_t *data;
325 size_t i, len;
326
327 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
328 return 0;
329
330 *out = 0;
331 data = CBS_data(&bytes);
332 len = CBS_len(&bytes);
333
334 if (len == 0)
335 /* An INTEGER is encoded with at least one octet. */
336 return 0;
337
338 if ((data[0] & 0x80) != 0)
339 /* negative number */
340 return 0;
341
342 for (i = 0; i < len; i++) {
343 if ((*out >> 56) != 0)
344 /* Too large to represent as a uint64_t. */
345 return 0;
346
347 *out <<= 8;
348 *out |= data[i];
349 }
350
351 return 1;
352}
353
354int
355CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag)
356{
357 if (CBS_peek_asn1_tag(cbs, tag)) {
358 if (!CBS_get_asn1(cbs, out, tag))
359 return 0;
360
361 *out_present = 1;
362 } else {
363 *out_present = 0;
364 }
365 return 1;
366}
367
368int
369CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
370 unsigned tag)
371{
372 CBS child;
373 int present;
374
375 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
376 return 0;
377
378 if (present) {
379 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
380 CBS_len(&child) != 0)
381 return 0;
382 } else {
383 CBS_init(out, NULL, 0);
384 }
385 if (out_present)
386 *out_present = present;
387
388 return 1;
389}
390
391int
392CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
393 uint64_t default_value)
394{
395 CBS child;
396 int present;
397
398 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
399 return 0;
400
401 if (present) {
402 if (!CBS_get_asn1_uint64(&child, out) ||
403 CBS_len(&child) != 0)
404 return 0;
405 } else {
406 *out = default_value;
407 }
408 return 1;
409}
410
411int
412CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, int default_value)
413{
414 CBS child, child2;
415 int present;
416
417 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
418 return 0;
419
420 if (present) {
421 uint8_t boolean;
422
423 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
424 CBS_len(&child2) != 1 || CBS_len(&child) != 0)
425 return 0;
426
427 boolean = CBS_data(&child2)[0];
428 if (boolean == 0)
429 *out = 0;
430 else if (boolean == 0xff)
431 *out = 1;
432 else
433 return 0;
434
435 } else {
436 *out = default_value;
437 }
438 return 1;
439}