Merge branch 'vendor/DHCPCD'
[dragonfly.git] / crypto / libressl / ssl / bs_cbs.c
1 /*      $OpenBSD: bs_cbs.c,v 1.18 2019/01/23 22:20:40 beck 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 <stdlib.h>
18 #include <string.h>
19
20 #include <openssl/opensslconf.h>
21 #include <openssl/buffer.h>
22 #include <openssl/crypto.h>
23
24 #include "bytestring.h"
25
26 void
27 CBS_init(CBS *cbs, const uint8_t *data, size_t len)
28 {
29         cbs->data = data;
30         cbs->initial_len = len;
31         cbs->len = len;
32 }
33
34 void
35 CBS_dup(const CBS *cbs, CBS *out)
36 {
37         CBS_init(out, CBS_data(cbs), CBS_len(cbs));
38         out->initial_len = cbs->initial_len;
39 }
40
41 static int
42 cbs_get(CBS *cbs, const uint8_t **p, size_t n)
43 {
44         if (cbs->len < n)
45                 return 0;
46
47         *p = cbs->data;
48         cbs->data += n;
49         cbs->len -= n;
50         return 1;
51 }
52
53 size_t
54 CBS_offset(const CBS *cbs)
55 {
56         return cbs->initial_len - cbs->len;
57 }
58
59 int
60 CBS_skip(CBS *cbs, size_t len)
61 {
62         const uint8_t *dummy;
63         return cbs_get(cbs, &dummy, len);
64 }
65
66 const uint8_t *
67 CBS_data(const CBS *cbs)
68 {
69         return cbs->data;
70 }
71
72 size_t
73 CBS_len(const CBS *cbs)
74 {
75         return cbs->len;
76 }
77
78 int
79 CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
80 {
81         free(*out_ptr);
82         *out_ptr = NULL;
83         *out_len = 0;
84
85         if (cbs->len == 0)
86                 return 1;
87
88         if ((*out_ptr = malloc(cbs->len)) == NULL)
89                 return 0;
90
91         memcpy(*out_ptr, cbs->data, cbs->len);
92
93         *out_len = cbs->len;
94         return 1;
95 }
96
97 int
98 CBS_strdup(const CBS *cbs, char **out_ptr)
99 {
100         free(*out_ptr);
101         *out_ptr = strndup((const char *)cbs->data, cbs->len);
102         return (*out_ptr != NULL);
103 }
104
105 int
106 CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied)
107 {
108         if (dst_len < cbs->len)
109                 return 0;
110
111         memmove(dst, cbs->data, cbs->len);
112
113         if (copied != NULL)
114                 *copied = cbs->len;
115
116         return 1;
117 }
118
119 int
120 CBS_contains_zero_byte(const CBS *cbs)
121 {
122         return memchr(cbs->data, 0, cbs->len) != NULL;
123 }
124
125 int
126 CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
127 {
128         if (len != cbs->len)
129                 return 0;
130
131         return timingsafe_memcmp(cbs->data, data, len) == 0;
132 }
133
134 static int
135 cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
136 {
137         uint32_t result = 0;
138         size_t i;
139         const uint8_t *data;
140
141         if (len < 1 || len > 4)
142                 return 0;
143
144         if (!cbs_get(cbs, &data, len))
145                 return 0;
146
147         for (i = 0; i < len; i++) {
148                 result <<= 8;
149                 result |= data[i];
150         }
151         *out = result;
152         return 1;
153 }
154
155 int
156 CBS_get_u8(CBS *cbs, uint8_t *out)
157 {
158         const uint8_t *v;
159
160         if (!cbs_get(cbs, &v, 1))
161                 return 0;
162
163         *out = *v;
164         return 1;
165 }
166
167 int
168 CBS_get_u16(CBS *cbs, uint16_t *out)
169 {
170         uint32_t v;
171
172         if (!cbs_get_u(cbs, &v, 2))
173                 return 0;
174
175         *out = v;
176         return 1;
177 }
178
179 int
180 CBS_get_u24(CBS *cbs, uint32_t *out)
181 {
182         return cbs_get_u(cbs, out, 3);
183 }
184
185 int
186 CBS_get_u32(CBS *cbs, uint32_t *out)
187 {
188         return cbs_get_u(cbs, out, 4);
189 }
190
191 int
192 CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
193 {
194         const uint8_t *v;
195
196         if (!cbs_get(cbs, &v, len))
197                 return 0;
198
199         CBS_init(out, v, len);
200         return 1;
201 }
202
203 static int
204 cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
205 {
206         uint32_t len;
207
208         if (!cbs_get_u(cbs, &len, len_len))
209                 return 0;
210
211         return CBS_get_bytes(cbs, out, len);
212 }
213
214 int
215 CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
216 {
217         return cbs_get_length_prefixed(cbs, out, 1);
218 }
219
220 int
221 CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
222 {
223         return cbs_get_length_prefixed(cbs, out, 2);
224 }
225
226 int
227 CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
228 {
229         return cbs_get_length_prefixed(cbs, out, 3);
230 }
231
232 int
233 CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
234     size_t *out_header_len)
235 {
236         return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
237             out_header_len, 1);
238 }
239
240 /*
241  * Review X.690 for details on ASN.1 DER encoding.
242  *
243  * If non-strict mode is enabled, then DER rules are relaxed
244  * for indefinite constructs (violates DER but a little closer to BER).
245  * Non-strict mode should only be used by bs_ber.c
246  *
247  * Sections 8, 10 and 11 for DER encoding
248  */
249 int
250 cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
251     size_t *out_header_len, int strict)
252 {
253         uint8_t tag, length_byte;
254         CBS header = *cbs;
255         CBS throwaway;
256         size_t len;
257
258         if (out == NULL)
259                 out = &throwaway;
260
261         /*
262          * Get identifier octet and length octet.  Only 1 octet for each
263          * is a CBS limitation.
264          */
265         if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
266                 return 0;
267
268         /* CBS limitation: long form tags are not supported. */
269         if ((tag & 0x1f) == 0x1f)
270                 return 0;
271
272         if (out_tag != NULL)
273                 *out_tag = tag;
274
275         if ((length_byte & 0x80) == 0) {
276                 /* Short form length. */
277                 len = ((size_t) length_byte) + 2;
278                 if (out_header_len != NULL)
279                         *out_header_len = 2;
280
281         } else {
282                 /* Long form length. */
283                 const size_t num_bytes = length_byte & 0x7f;
284                 uint32_t len32;
285
286                 /* ASN.1 reserved value for future extensions */
287                 if (num_bytes == 0x7f)
288                         return 0;
289
290                 /* Handle indefinite form length */
291                 if (num_bytes == 0) {
292                         /* DER encoding doesn't allow for indefinite form. */
293                         if (strict)
294                                 return 0;
295
296                         /* Primitive cannot use indefinite in BER or DER. */
297                         if ((tag & CBS_ASN1_CONSTRUCTED) == 0)
298                                 return 0;
299
300                         /* Constructed, indefinite length allowed in BER. */
301                         if (out_header_len != NULL)
302                                 *out_header_len = 2;
303                         return CBS_get_bytes(cbs, out, 2);
304                 }
305
306                 /* CBS limitation. */
307                 if (num_bytes > 4)
308                         return 0;
309
310                 if (!cbs_get_u(&header, &len32, num_bytes))
311                         return 0;
312
313                 /* DER has a minimum length octet requirement. */
314                 if (len32 < 128)
315                         /* Should have used short form instead */
316                         return 0;
317
318                 if ((len32 >> ((num_bytes - 1) * 8)) == 0)
319                         /* Length should have been at least one byte shorter. */
320                         return 0;
321
322                 len = len32;
323                 if (len + 2 + num_bytes < len)
324                         /* Overflow. */
325                         return 0;
326
327                 len += 2 + num_bytes;
328                 if (out_header_len != NULL)
329                         *out_header_len = 2 + num_bytes;
330         }
331
332         return CBS_get_bytes(cbs, out, len);
333 }
334
335 static int
336 cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header)
337 {
338         size_t header_len;
339         unsigned int tag;
340         CBS throwaway;
341
342         if (out == NULL)
343                 out = &throwaway;
344
345         if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
346             tag != tag_value)
347                 return 0;
348
349         if (skip_header && !CBS_skip(out, header_len))
350                 return 0;
351
352         return 1;
353 }
354
355 int
356 CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value)
357 {
358         return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
359 }
360
361 int
362 CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value)
363 {
364         return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
365 }
366
367 int
368 CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value)
369 {
370         if (CBS_len(cbs) < 1)
371                 return 0;
372
373         /*
374          * Tag number 31 indicates the start of a long form number.
375          * This is valid in ASN.1, but CBS only supports short form.
376          */
377         if ((tag_value & 0x1f) == 0x1f)
378                 return 0;
379
380         return CBS_data(cbs)[0] == tag_value;
381 }
382
383 /* Encoding details are in ASN.1: X.690 section 8.3 */
384 int
385 CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
386 {
387         CBS bytes;
388         const uint8_t *data;
389         size_t i, len;
390
391         if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
392                 return 0;
393
394         *out = 0;
395         data = CBS_data(&bytes);
396         len = CBS_len(&bytes);
397
398         if (len == 0)
399                 /* An INTEGER is encoded with at least one content octet. */
400                 return 0;
401
402         if ((data[0] & 0x80) != 0)
403                 /* Negative number. */
404                 return 0;
405
406         if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0)
407                 /* Violates smallest encoding rule: excessive leading zeros. */
408                 return 0;
409
410         for (i = 0; i < len; i++) {
411                 if ((*out >> 56) != 0)
412                         /* Too large to represent as a uint64_t. */
413                         return 0;
414
415                 *out <<= 8;
416                 *out |= data[i];
417         }
418
419         return 1;
420 }
421
422 int
423 CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag)
424 {
425         if (CBS_peek_asn1_tag(cbs, tag)) {
426                 if (!CBS_get_asn1(cbs, out, tag))
427                         return 0;
428
429                 *out_present = 1;
430         } else {
431                 *out_present = 0;
432         }
433         return 1;
434 }
435
436 int
437 CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
438     unsigned int tag)
439 {
440         CBS child;
441         int present;
442
443         if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
444                 return 0;
445
446         if (present) {
447                 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
448                     CBS_len(&child) != 0)
449                         return 0;
450         } else {
451                 CBS_init(out, NULL, 0);
452         }
453         if (out_present)
454                 *out_present = present;
455
456         return 1;
457 }
458
459 int
460 CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
461     uint64_t default_value)
462 {
463         CBS child;
464         int present;
465
466         if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
467                 return 0;
468
469         if (present) {
470                 if (!CBS_get_asn1_uint64(&child, out) ||
471                     CBS_len(&child) != 0)
472                         return 0;
473         } else {
474                 *out = default_value;
475         }
476         return 1;
477 }
478
479 int
480 CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
481     int default_value)
482 {
483         CBS child, child2;
484         int present;
485
486         if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
487                 return 0;
488
489         if (present) {
490                 uint8_t boolean;
491
492                 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
493                     CBS_len(&child2) != 1 || CBS_len(&child) != 0)
494                         return 0;
495
496                 boolean = CBS_data(&child2)[0];
497                 if (boolean == 0)
498                         *out = 0;
499                 else if (boolean == 0xff)
500                         *out = 1;
501                 else
502                         return 0;
503
504         } else {
505                 *out = default_value;
506         }
507         return 1;
508 }