Coverage Report

Created: 2026-10-27 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/bytestring/cbs.cc
Line
Count
Source
1
// Copyright 2014 The BoringSSL Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/asn1.h>
16
#include <openssl/bytestring.h>
17
#include <openssl/mem.h>
18
19
#include <assert.h>
20
#include <ctype.h>
21
#include <string.h>
22
23
#include "../asn1/internal.h"
24
#include "../internal.h"
25
#include "internal.h"
26
27
28
using namespace bssl;
29
30
1.57G
static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
31
1.57G
  if (cbs->len < n) {
32
8.07M
    return 0;
33
8.07M
  }
34
35
1.56G
  *p = cbs->data;
36
1.56G
  cbs->data += n;
37
1.56G
  cbs->len -= n;
38
1.56G
  return 1;
39
1.57G
}
40
41
25.4M
int CBS_skip(CBS *cbs, size_t len) {
42
25.4M
  const uint8_t *dummy;
43
25.4M
  return cbs_get(cbs, &dummy, len);
44
25.4M
}
45
46
0
int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
47
0
  OPENSSL_free(*out_ptr);
48
0
  *out_ptr = nullptr;
49
0
  *out_len = 0;
50
51
0
  if (cbs->len == 0) {
52
0
    return 1;
53
0
  }
54
0
  *out_ptr = reinterpret_cast<uint8_t *>(OPENSSL_memdup(cbs->data, cbs->len));
55
0
  if (*out_ptr == nullptr) {
56
0
    return 0;
57
0
  }
58
0
  *out_len = cbs->len;
59
0
  return 1;
60
0
}
61
62
14.6k
int CBS_strdup(const CBS *cbs, char **out_ptr) {
63
14.6k
  if (*out_ptr != nullptr) {
64
0
    OPENSSL_free(*out_ptr);
65
0
  }
66
14.6k
  *out_ptr = OPENSSL_strndup((const char *)cbs->data, cbs->len);
67
14.6k
  return (*out_ptr != nullptr);
68
14.6k
}
69
70
14.6k
int CBS_contains_zero_byte(const CBS *cbs) {
71
14.6k
  return OPENSSL_memchr(cbs->data, 0, cbs->len) != nullptr;
72
14.6k
}
73
74
78.0k
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
75
78.0k
  if (len != cbs->len) {
76
1.25k
    return 0;
77
1.25k
  }
78
76.7k
  return CRYPTO_memcmp(cbs->data, data, len) == 0;
79
78.0k
}
80
81
61.2M
static int cbs_get_u(CBS *cbs, uint64_t *out, size_t len) {
82
61.2M
  uint64_t result = 0;
83
61.2M
  const uint8_t *data;
84
85
61.2M
  if (!cbs_get(cbs, &data, len)) {
86
50.5k
    return 0;
87
50.5k
  }
88
185M
  for (size_t i = 0; i < len; i++) {
89
124M
    result <<= 8;
90
124M
    result |= data[i];
91
124M
  }
92
61.2M
  *out = result;
93
61.2M
  return 1;
94
61.2M
}
95
96
1.44G
int CBS_get_u8(CBS *cbs, uint8_t *out) {
97
1.44G
  const uint8_t *v;
98
1.44G
  if (!cbs_get(cbs, &v, 1)) {
99
6.60M
    return 0;
100
6.60M
  }
101
1.44G
  *out = *v;
102
1.44G
  return 1;
103
1.44G
}
104
105
50.2M
int CBS_get_u16(CBS *cbs, uint16_t *out) {
106
50.2M
  uint64_t v;
107
50.2M
  if (!cbs_get_u(cbs, &v, 2)) {
108
21.7k
    return 0;
109
21.7k
  }
110
50.2M
  *out = v;
111
50.2M
  return 1;
112
50.2M
}
113
114
0
int CBS_get_u16le(CBS *cbs, uint16_t *out) {
115
0
  if (!CBS_get_u16(cbs, out)) {
116
0
    return 0;
117
0
  }
118
0
  *out = CRYPTO_bswap2(*out);
119
0
  return 1;
120
0
}
121
122
2.14M
int CBS_get_u24(CBS *cbs, uint32_t *out) {
123
2.14M
  uint64_t v;
124
2.14M
  if (!cbs_get_u(cbs, &v, 3)) {
125
15.1k
    return 0;
126
15.1k
  }
127
2.12M
  *out = (uint32_t)v;
128
2.12M
  return 1;
129
2.14M
}
130
131
262k
int CBS_get_u32(CBS *cbs, uint32_t *out) {
132
262k
  uint64_t v;
133
262k
  if (!cbs_get_u(cbs, &v, 4)) {
134
370
    return 0;
135
370
  }
136
261k
  *out = (uint32_t)v;
137
261k
  return 1;
138
262k
}
139
140
0
int CBS_get_u32le(CBS *cbs, uint32_t *out) {
141
0
  if (!CBS_get_u32(cbs, out)) {
142
0
    return 0;
143
0
  }
144
0
  *out = CRYPTO_bswap4(*out);
145
0
  return 1;
146
0
}
147
148
0
int CBS_get_u48(CBS *cbs, uint64_t *out) { return cbs_get_u(cbs, out, 6); }
149
150
83.5k
int CBS_get_u64(CBS *cbs, uint64_t *out) { return cbs_get_u(cbs, out, 8); }
151
152
0
int CBS_get_u64le(CBS *cbs, uint64_t *out) {
153
0
  if (!cbs_get_u(cbs, out, 8)) {
154
0
    return 0;
155
0
  }
156
0
  *out = CRYPTO_bswap8(*out);
157
0
  return 1;
158
0
}
159
160
387k
int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
161
387k
  if (cbs->len == 0) {
162
139
    return 0;
163
139
  }
164
387k
  *out = cbs->data[cbs->len - 1];
165
387k
  cbs->len--;
166
387k
  return 1;
167
387k
}
168
169
35.5M
int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
170
35.5M
  const uint8_t *v;
171
35.5M
  if (!cbs_get(cbs, &v, len)) {
172
1.42M
    return 0;
173
1.42M
  }
174
34.1M
  CBS_init(out, v, len);
175
34.1M
  return 1;
176
35.5M
}
177
178
791
int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
179
791
  const uint8_t *v;
180
791
  if (!cbs_get(cbs, &v, len)) {
181
15
    return 0;
182
15
  }
183
776
  OPENSSL_memcpy(out, v, len);
184
776
  return 1;
185
791
}
186
187
4.52M
static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
188
4.52M
  uint64_t len;
189
4.52M
  if (!cbs_get_u(cbs, &len, len_len)) {
190
9.59k
    return 0;
191
9.59k
  }
192
  // If `len_len` <= 3 then we know that `len` will fit into a `size_t`, even on
193
  // 32-bit systems.
194
4.52M
  assert(len_len <= 3);
195
4.51M
  return CBS_get_bytes(cbs, out, len);
196
4.51M
}
197
198
443k
int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
199
443k
  return cbs_get_length_prefixed(cbs, out, 1);
200
443k
}
201
202
3.55M
int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
203
3.55M
  return cbs_get_length_prefixed(cbs, out, 2);
204
3.55M
}
205
206
523k
int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
207
523k
  return cbs_get_length_prefixed(cbs, out, 3);
208
523k
}
209
210
361k
int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) {
211
361k
  const uint8_t *split = reinterpret_cast<const uint8_t *>(
212
361k
      OPENSSL_memchr(CBS_data(cbs), c, CBS_len(cbs)));
213
361k
  if (split == nullptr) {
214
3.31k
    return 0;
215
3.31k
  }
216
358k
  return CBS_get_bytes(cbs, out, split - CBS_data(cbs));
217
361k
}
218
219
0
int CBS_get_until_first_of(CBS *cbs, CBS *out, const char *chars) {
220
0
  size_t pos = 0;
221
0
  while (pos < CBS_len(cbs)) {
222
0
    uint8_t c = CBS_data(cbs)[pos];
223
    // Special-case for \0 characters. We don't want to match on a null byte,
224
    // even though strchr will happily return the \0 at the end of `chars`.
225
0
    if (!c || !strchr(chars, c)) {
226
0
      pos++;
227
0
    } else {
228
0
      break;
229
0
    }
230
0
  }
231
0
  if (pos == CBS_len(cbs)) {
232
0
    return 0;
233
0
  }
234
0
  return CBS_get_bytes(cbs, out, pos);
235
0
}
236
237
0
int CBS_get_until_first_not_of(CBS *cbs, CBS *out, const char *chars) {
238
0
  size_t pos = 0;
239
0
  while (pos < CBS_len(cbs)) {
240
0
    uint8_t c = CBS_data(cbs)[pos];
241
    // Special-case for \0 characters. We don't want to match on a null byte,
242
    // even though strchr will happily return the \0 at the end of `chars`.
243
0
    if (c && strchr(chars, c)) {
244
0
      pos++;
245
0
    } else {
246
0
      break;
247
0
    }
248
0
  }
249
0
  if (pos == CBS_len(cbs)) {
250
0
    return 0;
251
0
  }
252
0
  return CBS_get_bytes(cbs, out, pos);
253
0
}
254
255
63.7k
int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) {
256
63.7k
  uint64_t v = 0;
257
63.7k
  int seen_digit = 0;
258
213k
  while (CBS_len(cbs) != 0) {
259
188k
    uint8_t c = CBS_data(cbs)[0];
260
188k
    if (!OPENSSL_isdigit(c)) {
261
39.0k
      break;
262
39.0k
    }
263
149k
    CBS_skip(cbs, 1);
264
149k
    if (/* Forbid stray leading zeros */
265
149k
        (v == 0 && seen_digit) ||
266
        // Check for overflow.
267
149k
        v > UINT64_MAX / 10 ||  //
268
149k
        v * 10 > UINT64_MAX - (c - '0')) {
269
172
      return 0;
270
172
    }
271
149k
    v = v * 10 + (c - '0');
272
149k
    seen_digit = 1;
273
149k
  }
274
275
63.6k
  *out = v;
276
63.6k
  return seen_digit;
277
63.7k
}
278
279
314k
int CBS_get_asn1_oid_component(CBS *cbs, uint64_t *out) {
280
314k
  uint64_t v = 0;
281
314k
  uint8_t b;
282
798k
  do {
283
798k
    if (!CBS_get_u8(cbs, &b)) {
284
27.6k
      return 0;
285
27.6k
    }
286
770k
    if ((v >> (64 - 7)) != 0) {
287
      // The value is too large.
288
1.68k
      return 0;
289
1.68k
    }
290
768k
    if (v == 0 && b == 0x80) {
291
      // The value must be minimally encoded.
292
2.58k
      return 0;
293
2.58k
    }
294
766k
    v = (v << 7) | (b & 0x7f);
295
296
    // Values end at an octet with the high bit cleared.
297
766k
  } while (b & 0x80);
298
299
282k
  *out = v;
300
282k
  return 1;
301
314k
}
302
303
34.5M
static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) {
304
34.5M
  uint8_t tag_byte;
305
34.5M
  if (!CBS_get_u8(cbs, &tag_byte)) {
306
1.90M
    return 0;
307
1.90M
  }
308
309
  // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
310
  // number no greater than 30.
311
  //
312
  // If the number portion is 31 (0x1f, the largest value that fits in the
313
  // allotted bits), then the tag is more than one byte long and the
314
  // continuation bytes contain the tag number.
315
32.6M
  CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
316
32.6M
  CBS_ASN1_TAG tag_number = tag_byte & 0x1f;
317
32.6M
  if (tag_number == 0x1f) {
318
    // High tag numbers are encoded in the same format as OID components.
319
186k
    uint64_t v;
320
186k
    if (!CBS_get_asn1_oid_component(cbs, &v) ||
321
        // Check the tag number is within our supported bounds.
322
154k
        v > CBS_ASN1_TAG_NUMBER_MASK ||
323
        // Small tag numbers should have used low tag number form, even in BER.
324
132k
        v < 0x1f) {
325
61.2k
      return 0;
326
61.2k
    }
327
124k
    tag_number = (CBS_ASN1_TAG)v;
328
124k
  }
329
330
32.5M
  tag |= tag_number;
331
332
  // Tag [UNIVERSAL 0] is reserved for use by the encoding. Reject it here to
333
  // avoid some ambiguity around ANY values and BER indefinite-length EOCs. See
334
  // https://crbug.com/boringssl/455.
335
32.5M
  if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) {
336
25.7k
    return 0;
337
25.7k
  }
338
339
32.5M
  *out = tag;
340
32.5M
  return 1;
341
32.5M
}
342
343
static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
344
                                    size_t *out_header_len, int *out_ber_found,
345
27.1M
                                    int *out_indefinite, int ber_ok) {
346
27.1M
  CBS header = *cbs;
347
27.1M
  CBS throwaway;
348
349
27.1M
  if (out == nullptr) {
350
3.53M
    out = &throwaway;
351
3.53M
  }
352
27.1M
  if (ber_ok) {
353
1.87M
    *out_ber_found = 0;
354
1.87M
    *out_indefinite = 0;
355
25.3M
  } else {
356
25.3M
    assert(out_ber_found == nullptr);
357
25.3M
    assert(out_indefinite == nullptr);
358
25.3M
  }
359
360
27.1M
  CBS_ASN1_TAG tag;
361
27.1M
  if (!parse_asn1_tag(&header, &tag)) {
362
38.1k
    return 0;
363
38.1k
  }
364
27.1M
  if (out_tag != nullptr) {
365
21.8M
    *out_tag = tag;
366
21.8M
  }
367
368
27.1M
  uint8_t length_byte;
369
27.1M
  if (!CBS_get_u8(&header, &length_byte)) {
370
13.6k
    return 0;
371
13.6k
  }
372
373
27.1M
  size_t header_len = CBS_len(cbs) - CBS_len(&header);
374
375
27.1M
  size_t len;
376
  // The format for the length encoding is specified in ITU-T X.690 section
377
  // 8.1.3.
378
27.1M
  if ((length_byte & 0x80) == 0) {
379
    // Short form length.
380
23.1M
    len = ((size_t)length_byte) + header_len;
381
23.1M
    if (out_header_len != nullptr) {
382
19.4M
      *out_header_len = header_len;
383
19.4M
    }
384
23.1M
  } else {
385
    // The high bit indicate that this is the long form, while the next 7 bits
386
    // encode the number of subsequent octets used to encode the length (ITU-T
387
    // X.690 clause 8.1.3.5.b).
388
4.02M
    const size_t num_bytes = length_byte & 0x7f;
389
4.02M
    uint64_t len64;
390
391
4.02M
    if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
392
      // indefinite length
393
23.6k
      if (out_header_len != nullptr) {
394
23.6k
        *out_header_len = header_len;
395
23.6k
      }
396
23.6k
      *out_ber_found = 1;
397
23.6k
      *out_indefinite = 1;
398
23.6k
      return CBS_get_bytes(cbs, out, header_len);
399
23.6k
    }
400
401
    // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
402
    // used as the first byte of the length. If this parser encounters that
403
    // value, num_bytes will be parsed as 127, which will fail this check.
404
4.00M
    if (num_bytes == 0 || num_bytes > 4) {
405
9.98k
      return 0;
406
9.98k
    }
407
3.99M
    if (!cbs_get_u(&header, &len64, num_bytes)) {
408
1.26k
      return 0;
409
1.26k
    }
410
    // ITU-T X.690 section 10.1 (DER length forms) requires encoding the
411
    // length with the minimum number of octets. BER could, technically, have
412
    // 125 superfluous zero bytes. We do not attempt to handle that and still
413
    // require that the length fit in a `uint32_t` for BER.
414
3.98M
    if (len64 < 128) {
415
      // Length should have used short-form encoding.
416
4.74k
      if (ber_ok) {
417
2.21k
        *out_ber_found = 1;
418
2.53k
      } else {
419
2.53k
        return 0;
420
2.53k
      }
421
4.74k
    }
422
3.98M
    if ((len64 >> ((num_bytes - 1) * 8)) == 0) {
423
      // Length should have been at least one byte shorter.
424
3.55k
      if (ber_ok) {
425
1.42k
        *out_ber_found = 1;
426
2.12k
      } else {
427
2.12k
        return 0;
428
2.12k
      }
429
3.55k
    }
430
3.98M
    len = len64;
431
3.98M
    if (len + header_len + num_bytes < len) {
432
      // Overflow.
433
0
      return 0;
434
0
    }
435
3.98M
    len += header_len + num_bytes;
436
3.98M
    if (out_header_len != nullptr) {
437
2.34M
      *out_header_len = header_len + num_bytes;
438
2.34M
    }
439
3.98M
  }
440
441
27.1M
  return CBS_get_bytes(cbs, out, len);
442
27.1M
}
443
444
1.19k
int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) {
445
1.19k
  size_t header_len;
446
1.19k
  if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
447
448
    return 0;
448
448
  }
449
450
746
  if (out && !CBS_skip(out, header_len)) {
451
0
    assert(0);
452
0
    return 0;
453
0
  }
454
455
746
  return 1;
456
746
}
457
458
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
459
25.3M
                             size_t *out_header_len) {
460
25.3M
  return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, nullptr,
461
25.3M
                                  nullptr,
462
25.3M
                                  /*ber_ok=*/0);
463
25.3M
}
464
465
int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
466
                                 size_t *out_header_len, int *out_ber_found,
467
1.87M
                                 int *out_indefinite) {
468
1.87M
  int ber_found_temp;
469
1.87M
  return cbs_get_any_asn1_element(
470
1.87M
      cbs, out, out_tag, out_header_len,
471
1.87M
      out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite,
472
1.87M
      /*ber_ok=*/1);
473
1.87M
}
474
475
static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value,
476
15.8M
                        int skip_header) {
477
15.8M
  size_t header_len;
478
15.8M
  CBS_ASN1_TAG tag;
479
15.8M
  CBS throwaway;
480
481
15.8M
  if (out == nullptr) {
482
724k
    out = &throwaway;
483
724k
  }
484
485
15.8M
  if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
486
15.8M
      tag != tag_value) {
487
116k
    return 0;
488
116k
  }
489
490
15.7M
  if (skip_header && !CBS_skip(out, header_len)) {
491
0
    assert(0);
492
0
    return 0;
493
0
  }
494
495
15.7M
  return 1;
496
15.7M
}
497
498
15.7M
int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
499
15.7M
  return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
500
15.7M
}
501
502
136k
int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
503
136k
  return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
504
136k
}
505
506
7.34M
CBS_ASN1_TAG CBS_peek_any_asn1_tag(const CBS *cbs) {
507
7.34M
  CBS copy = *cbs;
508
7.34M
  CBS_ASN1_TAG tag;
509
7.34M
  if (!parse_asn1_tag(&copy, &tag)) {
510
1.95M
    return 0;
511
1.95M
  }
512
5.38M
  return tag;
513
7.34M
}
514
515
7.33M
int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) {
516
7.33M
  CBS_ASN1_TAG actual_tag = CBS_peek_any_asn1_tag(cbs);
517
  // The caller should never pass zero as |tag_value|, but return zero if they
518
  // did.
519
7.33M
  return actual_tag != 0 && actual_tag == tag_value;
520
7.33M
}
521
522
1.03M
int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
523
1.03M
  return CBS_get_asn1_uint64_with_tag(cbs, out, CBS_ASN1_INTEGER);
524
1.03M
}
525
526
1.03M
int CBS_get_asn1_uint64_with_tag(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag) {
527
1.03M
  CBS bytes;
528
1.03M
  if (!CBS_get_asn1(cbs, &bytes, tag) ||
529
1.02M
      !CBS_is_unsigned_asn1_integer(&bytes)) {
530
11.6k
    return 0;
531
11.6k
  }
532
533
1.02M
  *out = 0;
534
1.02M
  const uint8_t *data = CBS_data(&bytes);
535
1.02M
  size_t len = CBS_len(&bytes);
536
2.73M
  for (size_t i = 0; i < len; i++) {
537
1.71M
    if ((*out >> 56) != 0) {
538
      // Too large to represent as a uint64_t.
539
1.38k
      return 0;
540
1.38k
    }
541
1.71M
    *out <<= 8;
542
1.71M
    *out |= data[i];
543
1.71M
  }
544
545
1.02M
  return 1;
546
1.02M
}
547
548
0
int CBS_get_asn1_int64(CBS *cbs, int64_t *out) {
549
0
  return CBS_get_asn1_int64_with_tag(cbs, out, CBS_ASN1_INTEGER);
550
0
}
551
552
0
int CBS_get_asn1_int64_with_tag(CBS *cbs, int64_t *out, CBS_ASN1_TAG tag) {
553
0
  int is_negative;
554
0
  CBS bytes;
555
0
  if (!CBS_get_asn1(cbs, &bytes, tag) ||
556
0
      !CBS_is_valid_asn1_integer(&bytes, &is_negative)) {
557
0
    return 0;
558
0
  }
559
0
  const uint8_t *data = CBS_data(&bytes);
560
0
  const size_t len = CBS_len(&bytes);
561
0
  if (len > sizeof(int64_t)) {
562
0
    return 0;
563
0
  }
564
0
  uint8_t sign_extend[sizeof(int64_t)];
565
0
  OPENSSL_memset(sign_extend, is_negative ? 0xff : 0, sizeof(sign_extend));
566
0
  OPENSSL_memcpy(sign_extend + sizeof(int64_t) - len, data, len);
567
0
  *out = CRYPTO_load_u64_be(sign_extend);
568
0
  return 1;
569
0
}
570
571
1.41k
int CBS_get_asn1_bool(CBS *cbs, int *out) {
572
1.41k
  CBS bytes;
573
1.41k
  if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || CBS_len(&bytes) != 1) {
574
183
    return 0;
575
183
  }
576
577
1.23k
  const uint8_t value = *CBS_data(&bytes);
578
1.23k
  if (value != 0 && value != 0xff) {
579
94
    return 0;
580
94
  }
581
582
1.13k
  *out = !!value;
583
1.13k
  return 1;
584
1.23k
}
585
586
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
587
3.87M
                          CBS_ASN1_TAG tag) {
588
3.87M
  int present = 0;
589
590
3.87M
  if (CBS_peek_asn1_tag(cbs, tag)) {
591
961k
    if (!CBS_get_asn1(cbs, out, tag)) {
592
9.54k
      return 0;
593
9.54k
    }
594
952k
    present = 1;
595
952k
  }
596
597
3.86M
  if (out_present != nullptr) {
598
3.52M
    *out_present = present;
599
3.52M
  }
600
601
3.86M
  return 1;
602
3.87M
}
603
604
int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
605
1.24M
                                       CBS_ASN1_TAG tag) {
606
1.24M
  CBS child;
607
1.24M
  int present;
608
1.24M
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
609
80
    return 0;
610
80
  }
611
1.24M
  if (present) {
612
270k
    assert(out);
613
270k
    if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
614
270k
        CBS_len(&child) != 0) {
615
420
      return 0;
616
420
    }
617
969k
  } else {
618
969k
    CBS_init(out, nullptr, 0);
619
969k
  }
620
1.24M
  if (out_present) {
621
549k
    *out_present = present;
622
549k
  }
623
1.24M
  return 1;
624
1.24M
}
625
626
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag,
627
830k
                                 uint64_t default_value) {
628
830k
  CBS child;
629
830k
  int present;
630
830k
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
631
47
    return 0;
632
47
  }
633
830k
  if (present) {
634
220k
    if (!CBS_get_asn1_uint64(&child, out) || CBS_len(&child) != 0) {
635
60
      return 0;
636
60
    }
637
609k
  } else {
638
609k
    *out = default_value;
639
609k
  }
640
830k
  return 1;
641
830k
}
642
643
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag,
644
549k
                               int default_value) {
645
549k
  CBS child, child2;
646
549k
  int present;
647
549k
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
648
28
    return 0;
649
28
  }
650
549k
  if (present) {
651
146k
    uint8_t boolean;
652
653
146k
    if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
654
146k
        CBS_len(&child2) != 1 || CBS_len(&child) != 0) {
655
410
      return 0;
656
410
    }
657
658
146k
    boolean = CBS_data(&child2)[0];
659
146k
    if (boolean == 0) {
660
70.8k
      *out = 0;
661
75.2k
    } else if (boolean == 0xff) {
662
75.2k
      *out = 1;
663
75.2k
    } else {
664
61
      return 0;
665
61
    }
666
403k
  } else {
667
403k
    *out = default_value;
668
403k
  }
669
549k
  return 1;
670
549k
}
671
672
461
int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
673
461
  CBS in = *cbs;
674
461
  uint8_t num_unused_bits;
675
461
  if (!CBS_get_u8(&in, &num_unused_bits) || num_unused_bits > 7) {
676
11
    return 0;
677
11
  }
678
679
450
  if (num_unused_bits == 0) {
680
34
    return 1;
681
34
  }
682
683
  // All num_unused_bits bits must exist and be zeros.
684
416
  uint8_t last;
685
416
  if (!CBS_get_last_u8(&in, &last) ||
686
416
      (last & ((1 << num_unused_bits) - 1)) != 0) {
687
8
    return 0;
688
8
  }
689
690
408
  return 1;
691
416
}
692
693
221
int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
694
221
  if (!CBS_is_valid_asn1_bitstring(cbs)) {
695
0
    return 0;
696
0
  }
697
698
221
  const unsigned byte_num = (bit >> 3) + 1;
699
221
  const unsigned bit_num = 7 - (bit & 7);
700
701
  // Unused bits are zero, and this function does not distinguish between
702
  // missing and unset bits. Thus it is sufficient to do a byte-level length
703
  // check.
704
221
  return byte_num < CBS_len(cbs) &&
705
221
         (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
706
221
}
707
708
1.58M
int CBS_is_valid_asn1_integer(const CBS *cbs, int *out_is_negative) {
709
1.58M
  CBS copy = *cbs;
710
1.58M
  uint8_t first_byte, second_byte;
711
1.58M
  if (!CBS_get_u8(&copy, &first_byte)) {
712
8.14k
    return 0;  // INTEGERs may not be empty.
713
8.14k
  }
714
1.57M
  if (out_is_negative != nullptr) {
715
1.57M
    *out_is_negative = (first_byte & 0x80) != 0;
716
1.57M
  }
717
1.57M
  if (!CBS_get_u8(&copy, &second_byte)) {
718
548k
    return 1;  // One byte INTEGERs are always minimal.
719
548k
  }
720
1.02M
  if ((first_byte == 0x00 && (second_byte & 0x80) == 0) ||
721
1.02M
      (first_byte == 0xff && (second_byte & 0x80) != 0)) {
722
5.27k
    return 0;  // The value is minimal iff the first 9 bits are not all equal.
723
5.27k
  }
724
1.02M
  return 1;
725
1.02M
}
726
727
1.02M
int CBS_is_unsigned_asn1_integer(const CBS *cbs) {
728
1.02M
  int is_negative;
729
1.02M
  return CBS_is_valid_asn1_integer(cbs, &is_negative) && !is_negative;
730
1.02M
}
731
732
2.13M
int CBS_is_valid_asn1_oid(const CBS *cbs) {
733
2.13M
  if (CBS_len(cbs) == 0) {
734
91
    return 0;  // OID encodings cannot be empty.
735
91
  }
736
737
2.13M
  CBS copy = *cbs;
738
2.13M
  uint8_t v, prev = 0;
739
15.0M
  while (CBS_get_u8(&copy, &v)) {
740
    // OID encodings are a sequence of minimally-encoded base-128 integers (see
741
    // `CBS_get_asn1_oid_component`). If `prev`'s MSB was clear, it was the last
742
    // byte of an integer (or `v` is the first byte). `v` is then the first byte
743
    // of the next integer. If first byte of an integer is 0x80, it is not
744
    // minimally-encoded.
745
12.8M
    if ((prev & 0x80) == 0 && v == 0x80) {
746
112
      return 0;
747
112
    }
748
12.8M
    prev = v;
749
12.8M
  }
750
751
  // The last byte should must end an integer encoding.
752
2.13M
  return (prev & 0x80) == 0;
753
2.13M
}
754
755
26.8k
char *CBS_asn1_oid_to_text(const CBS *cbs) {
756
26.8k
  CBS copy = *cbs;
757
26.8k
  CBB cbb;
758
26.8k
  if (!CBB_init(&cbb, 32)) {
759
0
    goto err;
760
0
  }
761
762
  // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2.
763
26.8k
  uint64_t v;
764
26.8k
  if (!CBS_get_asn1_oid_component(&copy, &v)) {
765
160
    goto err;
766
160
  }
767
768
26.6k
  if (v >= 80) {
769
15.3k
    if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
770
15.3k
        !cbb_add_decimal_ascii(&cbb, v - 80)) {
771
0
      goto err;
772
0
    }
773
15.3k
  } else if (!cbb_add_decimal_ascii(&cbb, v / 40) || !CBB_add_u8(&cbb, '.') ||
774
11.2k
             !cbb_add_decimal_ascii(&cbb, v % 40)) {
775
0
    goto err;
776
0
  }
777
778
127k
  while (CBS_len(&copy) != 0) {
779
101k
    if (!CBS_get_asn1_oid_component(&copy, &v) || !CBB_add_u8(&cbb, '.') ||
780
100k
        !cbb_add_decimal_ascii(&cbb, v)) {
781
209
      goto err;
782
209
    }
783
101k
  }
784
785
26.4k
  uint8_t *txt;
786
26.4k
  size_t txt_len;
787
26.4k
  if (!CBB_add_u8(&cbb, '\0') || !CBB_finish(&cbb, &txt, &txt_len)) {
788
0
    goto err;
789
0
  }
790
791
26.4k
  return (char *)txt;
792
793
369
err:
794
369
  CBB_cleanup(&cbb);
795
369
  return nullptr;
796
26.4k
}
797
798
2.47k
int CBS_is_valid_asn1_relative_oid(const CBS *cbs) {
799
2.47k
  return CBS_is_valid_asn1_oid(cbs);
800
2.47k
}
801
802
0
char *CBS_asn1_relative_oid_to_text(const CBS *cbs) {
803
0
  ScopedCBB cbb;
804
0
  if (!CBB_init(cbb.get(), 32)) {
805
0
    return nullptr;
806
0
  }
807
0
  if (!CBB_add_asn1_relative_oid_from_der_to_text(cbb.get(), CBS_data(cbs),
808
0
                                                  CBS_len(cbs))) {
809
0
    return nullptr;
810
0
  }
811
812
0
  uint8_t *txt;
813
0
  size_t txt_len;
814
0
  if (!CBB_add_u8(cbb.get(), '\0') || !CBB_finish(cbb.get(), &txt, &txt_len)) {
815
0
    return nullptr;
816
0
  }
817
818
0
  return reinterpret_cast<char *>(txt);
819
0
}
820
821
2.28M
static int cbs_get_two_digits(CBS *cbs, int *out) {
822
2.28M
  uint8_t first_digit, second_digit;
823
2.28M
  if (!CBS_get_u8(cbs, &first_digit)) {
824
482
    return 0;
825
482
  }
826
2.28M
  if (!OPENSSL_isdigit(first_digit)) {
827
1.36k
    return 0;
828
1.36k
  }
829
2.28M
  if (!CBS_get_u8(cbs, &second_digit)) {
830
372
    return 0;
831
372
  }
832
2.28M
  if (!OPENSSL_isdigit(second_digit)) {
833
917
    return 0;
834
917
  }
835
2.28M
  *out = (first_digit - '0') * 10 + (second_digit - '0');
836
2.28M
  return 1;
837
2.28M
}
838
839
379k
static int is_valid_day(int year, int month, int day) {
840
379k
  if (day < 1) {
841
38
    return 0;
842
38
  }
843
379k
  switch (month) {
844
6.57k
    case 1:
845
11.2k
    case 3:
846
59.2k
    case 5:
847
65.1k
    case 7:
848
71.3k
    case 8:
849
76.9k
    case 10:
850
157k
    case 12:
851
157k
      return day <= 31;
852
89.1k
    case 4:
853
93.7k
    case 6:
854
95.8k
    case 9:
855
156k
    case 11:
856
156k
      return day <= 30;
857
66.3k
    case 2:
858
66.3k
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
859
31.3k
        return day <= 29;
860
35.0k
      } else {
861
35.0k
        return day <= 28;
862
35.0k
      }
863
0
    default:
864
0
      return 0;
865
379k
  }
866
379k
}
867
868
static int CBS_parse_rfc5280_time_internal(const CBS *cbs, int is_gentime,
869
                                           int allow_timezone_offset,
870
382k
                                           struct tm *out_tm) {
871
382k
  int year, month, day, hour, min, sec, tmp;
872
382k
  CBS copy = *cbs;
873
382k
  uint8_t tz;
874
875
382k
  if (is_gentime) {
876
3.69k
    if (!cbs_get_two_digits(&copy, &tmp)) {
877
550
      return 0;
878
550
    }
879
3.14k
    year = tmp * 100;
880
3.14k
    if (!cbs_get_two_digits(&copy, &tmp)) {
881
607
      return 0;
882
607
    }
883
2.54k
    year += tmp;
884
378k
  } else {
885
378k
    year = 1900;
886
378k
    if (!cbs_get_two_digits(&copy, &tmp)) {
887
215
      return 0;
888
215
    }
889
378k
    year += tmp;
890
378k
    if (year < 1950) {
891
363k
      year += 100;
892
363k
    }
893
378k
    if (year >= 2050) {
894
0
      return 0;  // A Generalized time must be used.
895
0
    }
896
378k
  }
897
381k
  if (!cbs_get_two_digits(&copy, &month) || month < 1 ||
898
380k
      month > 12 ||  // Reject invalid months.
899
380k
      !cbs_get_two_digits(&copy, &day) ||
900
379k
      !is_valid_day(year, month, day) ||  // Reject invalid days.
901
379k
      !cbs_get_two_digits(&copy, &hour) ||
902
379k
      hour > 23 ||  // Reject invalid hours.
903
379k
      !cbs_get_two_digits(&copy, &min) ||
904
379k
      min > 59 ||  // Reject invalid minutes.
905
379k
      !cbs_get_two_digits(&copy, &sec) || sec > 59 || !CBS_get_u8(&copy, &tz)) {
906
2.33k
    return 0;
907
2.33k
  }
908
909
378k
  int offset_sign = 0;
910
378k
  switch (tz) {
911
376k
    case 'Z':
912
376k
      break;  // We correctly have 'Z' on the end as per spec.
913
1.07k
    case '+':
914
1.07k
      offset_sign = -1;
915
1.07k
      break;  // Should not be allowed per RFC 5280.
916
605
    case '-':
917
605
      offset_sign = 1;
918
605
      break;  // Should not be allowed per RFC 5280.
919
132
    default:
920
132
      return 0;  // Reject anything else after the time.
921
378k
  }
922
923
  // If allow_timezone_offset is non-zero, allow for a four digit timezone
924
  // offset to be specified even though this is not allowed by RFC 5280. We are
925
  // permissive of this for UTCTimes due to the unfortunate existence of
926
  // artisanally rolled long lived certificates that were baked into places that
927
  // are now difficult to change. These certificates were generated with the
928
  // 'openssl' command that permissively allowed the creation of certificates
929
  // with notBefore and notAfter times specified as strings for direct
930
  // certificate inclusion on the command line. For context see cl/237068815.
931
  //
932
  // TODO(bbe): This has been expunged from public web-pki as the ecosystem has
933
  // managed to encourage CA compliance with standards. We should find a way to
934
  // get rid of this or make it off by default.
935
378k
  int offset_seconds = 0;
936
378k
  if (offset_sign != 0) {
937
1.68k
    if (!allow_timezone_offset) {
938
24
      return 0;
939
24
    }
940
1.66k
    int offset_hours, offset_minutes;
941
1.66k
    if (!cbs_get_two_digits(&copy, &offset_hours) ||
942
1.60k
        offset_hours > 23 ||  // Reject invalid hours.
943
1.57k
        !cbs_get_two_digits(&copy, &offset_minutes) ||
944
1.53k
        offset_minutes > 59) {  // Reject invalid minutes.
945
155
      return 0;
946
155
    }
947
1.50k
    offset_seconds = offset_sign * (offset_hours * 3600 + offset_minutes * 60);
948
1.50k
  }
949
950
378k
  if (CBS_len(&copy) != 0) {
951
121
    return 0;  // Reject invalid lengths.
952
121
  }
953
954
378k
  if (out_tm != nullptr) {
955
    // Fill in the tm fields corresponding to what we validated.
956
5.51k
    out_tm->tm_year = year - 1900;
957
5.51k
    out_tm->tm_mon = month - 1;
958
5.51k
    out_tm->tm_mday = day;
959
5.51k
    out_tm->tm_hour = hour;
960
5.51k
    out_tm->tm_min = min;
961
5.51k
    out_tm->tm_sec = sec;
962
5.51k
    if (offset_seconds && !OPENSSL_gmtime_adj(out_tm, 0, offset_seconds)) {
963
0
      return 0;
964
0
    }
965
5.51k
  }
966
378k
  return 1;
967
378k
}
968
969
int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm,
970
3.69k
                               int allow_timezone_offset) {
971
3.69k
  return CBS_parse_rfc5280_time_internal(cbs, 1, allow_timezone_offset, out_tm);
972
3.69k
}
973
974
int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm,
975
378k
                       int allow_timezone_offset) {
976
378k
  return CBS_parse_rfc5280_time_internal(cbs, 0, allow_timezone_offset, out_tm);
977
378k
}