Coverage Report

Created: 2022-08-24 06:30

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