Coverage Report

Created: 2026-08-28 07:25

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
679M
static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
31
679M
  if (cbs->len < n) {
32
8.08M
    return 0;
33
8.08M
  }
34
35
671M
  *p = cbs->data;
36
671M
  cbs->data += n;
37
671M
  cbs->len -= n;
38
671M
  return 1;
39
679M
}
40
41
25.5M
int CBS_skip(CBS *cbs, size_t len) {
42
25.5M
  const uint8_t *dummy;
43
25.5M
  return cbs_get(cbs, &dummy, len);
44
25.5M
}
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
15.4k
int CBS_strdup(const CBS *cbs, char **out_ptr) {
63
15.4k
  if (*out_ptr != nullptr) {
64
0
    OPENSSL_free(*out_ptr);
65
0
  }
66
15.4k
  *out_ptr = OPENSSL_strndup((const char *)cbs->data, cbs->len);
67
15.4k
  return (*out_ptr != nullptr);
68
15.4k
}
69
70
15.4k
int CBS_contains_zero_byte(const CBS *cbs) {
71
15.4k
  return OPENSSL_memchr(cbs->data, 0, cbs->len) != nullptr;
72
15.4k
}
73
74
71.5k
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
75
71.5k
  if (len != cbs->len) {
76
1.22k
    return 0;
77
1.22k
  }
78
70.3k
  return CRYPTO_memcmp(cbs->data, data, len) == 0;
79
71.5k
}
80
81
54.7M
static int cbs_get_u(CBS *cbs, uint64_t *out, size_t len) {
82
54.7M
  uint64_t result = 0;
83
54.7M
  const uint8_t *data;
84
85
54.7M
  if (!cbs_get(cbs, &data, len)) {
86
49.2k
    return 0;
87
49.2k
  }
88
166M
  for (size_t i = 0; i < len; i++) {
89
111M
    result <<= 8;
90
111M
    result |= data[i];
91
111M
  }
92
54.6M
  *out = result;
93
54.6M
  return 1;
94
54.7M
}
95
96
564M
int CBS_get_u8(CBS *cbs, uint8_t *out) {
97
564M
  const uint8_t *v;
98
564M
  if (!cbs_get(cbs, &v, 1)) {
99
6.39M
    return 0;
100
6.39M
  }
101
558M
  *out = *v;
102
558M
  return 1;
103
564M
}
104
105
44.7M
int CBS_get_u16(CBS *cbs, uint16_t *out) {
106
44.7M
  uint64_t v;
107
44.7M
  if (!cbs_get_u(cbs, &v, 2)) {
108
22.2k
    return 0;
109
22.2k
  }
110
44.7M
  *out = v;
111
44.7M
  return 1;
112
44.7M
}
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.22M
int CBS_get_u24(CBS *cbs, uint32_t *out) {
123
2.22M
  uint64_t v;
124
2.22M
  if (!cbs_get_u(cbs, &v, 3)) {
125
14.0k
    return 0;
126
14.0k
  }
127
2.20M
  *out = (uint32_t)v;
128
2.20M
  return 1;
129
2.22M
}
130
131
188k
int CBS_get_u32(CBS *cbs, uint32_t *out) {
132
188k
  uint64_t v;
133
188k
  if (!cbs_get_u(cbs, &v, 4)) {
134
378
    return 0;
135
378
  }
136
188k
  *out = (uint32_t)v;
137
188k
  return 1;
138
188k
}
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
80.0k
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
178k
int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
161
178k
  if (cbs->len == 0) {
162
131
    return 0;
163
131
  }
164
177k
  *out = cbs->data[cbs->len - 1];
165
177k
  cbs->len--;
166
177k
  return 1;
167
178k
}
168
169
34.3M
int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
170
34.3M
  const uint8_t *v;
171
34.3M
  if (!cbs_get(cbs, &v, len)) {
172
1.64M
    return 0;
173
1.64M
  }
174
32.6M
  CBS_init(out, v, len);
175
32.6M
  return 1;
176
34.3M
}
177
178
701
int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
179
701
  const uint8_t *v;
180
701
  if (!cbs_get(cbs, &v, len)) {
181
14
    return 0;
182
14
  }
183
687
  OPENSSL_memcpy(out, v, len);
184
687
  return 1;
185
701
}
186
187
4.36M
static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
188
4.36M
  uint64_t len;
189
4.36M
  if (!cbs_get_u(cbs, &len, len_len)) {
190
9.29k
    return 0;
191
9.29k
  }
192
  // If `len_len` <= 3 then we know that `len` will fit into a `size_t`, even on
193
  // 32-bit systems.
194
4.36M
  assert(len_len <= 3);
195
4.35M
  return CBS_get_bytes(cbs, out, len);
196
4.35M
}
197
198
442k
int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
199
442k
  return cbs_get_length_prefixed(cbs, out, 1);
200
442k
}
201
202
3.43M
int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
203
3.43M
  return cbs_get_length_prefixed(cbs, out, 2);
204
3.43M
}
205
206
493k
int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
207
493k
  return cbs_get_length_prefixed(cbs, out, 3);
208
493k
}
209
210
154k
int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) {
211
154k
  const uint8_t *split = reinterpret_cast<const uint8_t *>(
212
154k
      OPENSSL_memchr(CBS_data(cbs), c, CBS_len(cbs)));
213
154k
  if (split == nullptr) {
214
3.28k
    return 0;
215
3.28k
  }
216
150k
  return CBS_get_bytes(cbs, out, split - CBS_data(cbs));
217
154k
}
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
52.3k
int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) {
256
52.3k
  uint64_t v = 0;
257
52.3k
  int seen_digit = 0;
258
187k
  while (CBS_len(cbs) != 0) {
259
171k
    uint8_t c = CBS_data(cbs)[0];
260
171k
    if (!OPENSSL_isdigit(c)) {
261
35.6k
      break;
262
35.6k
    }
263
135k
    CBS_skip(cbs, 1);
264
135k
    if (/* Forbid stray leading zeros */
265
135k
        (v == 0 && seen_digit) ||
266
        // Check for overflow.
267
135k
        v > UINT64_MAX / 10 ||  //
268
135k
        v * 10 > UINT64_MAX - (c - '0')) {
269
175
      return 0;
270
175
    }
271
135k
    v = v * 10 + (c - '0');
272
135k
    seen_digit = 1;
273
135k
  }
274
275
52.1k
  *out = v;
276
52.1k
  return seen_digit;
277
52.3k
}
278
279
309k
int CBS_get_asn1_oid_component(CBS *cbs, uint64_t *out) {
280
309k
  uint64_t v = 0;
281
309k
  uint8_t b;
282
771k
  do {
283
771k
    if (!CBS_get_u8(cbs, &b)) {
284
26.3k
      return 0;
285
26.3k
    }
286
744k
    if ((v >> (64 - 7)) != 0) {
287
      // The value is too large.
288
1.45k
      return 0;
289
1.45k
    }
290
743k
    if (v == 0 && b == 0x80) {
291
      // The value must be minimally encoded.
292
2.96k
      return 0;
293
2.96k
    }
294
740k
    v = (v << 7) | (b & 0x7f);
295
296
    // Values end at an octet with the high bit cleared.
297
740k
  } while (b & 0x80);
298
299
278k
  *out = v;
300
278k
  return 1;
301
309k
}
302
303
34.0M
static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) {
304
34.0M
  uint8_t tag_byte;
305
34.0M
  if (!CBS_get_u8(cbs, &tag_byte)) {
306
1.78M
    return 0;
307
1.78M
  }
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.3M
  CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
316
32.3M
  CBS_ASN1_TAG tag_number = tag_byte & 0x1f;
317
32.3M
  if (tag_number == 0x1f) {
318
    // High tag numbers are encoded in the same format as OID components.
319
183k
    uint64_t v;
320
183k
    if (!CBS_get_asn1_oid_component(cbs, &v) ||
321
        // Check the tag number is within our supported bounds.
322
153k
        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
58.6k
      return 0;
326
58.6k
    }
327
124k
    tag_number = (CBS_ASN1_TAG)v;
328
124k
  }
329
330
32.2M
  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.2M
  if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) {
336
27.2k
    return 0;
337
27.2k
  }
338
339
32.2M
  *out = tag;
340
32.2M
  return 1;
341
32.2M
}
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
26.2M
                                    int *out_indefinite, int ber_ok) {
346
26.2M
  CBS header = *cbs;
347
26.2M
  CBS throwaway;
348
349
26.2M
  if (out == nullptr) {
350
2.92M
    out = &throwaway;
351
2.92M
  }
352
26.2M
  if (ber_ok) {
353
1.88M
    *out_ber_found = 0;
354
1.88M
    *out_indefinite = 0;
355
24.3M
  } else {
356
24.3M
    assert(out_ber_found == nullptr);
357
24.3M
    assert(out_indefinite == nullptr);
358
24.3M
  }
359
360
26.2M
  CBS_ASN1_TAG tag;
361
26.2M
  if (!parse_asn1_tag(&header, &tag)) {
362
36.5k
    return 0;
363
36.5k
  }
364
26.2M
  if (out_tag != nullptr) {
365
21.9M
    *out_tag = tag;
366
21.9M
  }
367
368
26.2M
  uint8_t length_byte;
369
26.2M
  if (!CBS_get_u8(&header, &length_byte)) {
370
13.0k
    return 0;
371
13.0k
  }
372
373
26.2M
  size_t header_len = CBS_len(cbs) - CBS_len(&header);
374
375
26.2M
  size_t len;
376
  // The format for the length encoding is specified in ITU-T X.690 section
377
  // 8.1.3.
378
26.2M
  if ((length_byte & 0x80) == 0) {
379
    // Short form length.
380
23.0M
    len = ((size_t)length_byte) + header_len;
381
23.0M
    if (out_header_len != nullptr) {
382
19.5M
      *out_header_len = header_len;
383
19.5M
    }
384
23.0M
  } 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
3.12M
    const size_t num_bytes = length_byte & 0x7f;
389
3.12M
    uint64_t len64;
390
391
3.12M
    if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
392
      // indefinite length
393
21.9k
      if (out_header_len != nullptr) {
394
21.9k
        *out_header_len = header_len;
395
21.9k
      }
396
21.9k
      *out_ber_found = 1;
397
21.9k
      *out_indefinite = 1;
398
21.9k
      return CBS_get_bytes(cbs, out, header_len);
399
21.9k
    }
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
3.10M
    if (num_bytes == 0 || num_bytes > 4) {
405
9.39k
      return 0;
406
9.39k
    }
407
3.09M
    if (!cbs_get_u(&header, &len64, num_bytes)) {
408
1.08k
      return 0;
409
1.08k
    }
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.09M
    if (len64 < 128) {
415
      // Length should have used short-form encoding.
416
4.82k
      if (ber_ok) {
417
2.25k
        *out_ber_found = 1;
418
2.56k
      } else {
419
2.56k
        return 0;
420
2.56k
      }
421
4.82k
    }
422
3.08M
    if ((len64 >> ((num_bytes - 1) * 8)) == 0) {
423
      // Length should have been at least one byte shorter.
424
3.45k
      if (ber_ok) {
425
1.48k
        *out_ber_found = 1;
426
1.97k
      } else {
427
1.97k
        return 0;
428
1.97k
      }
429
3.45k
    }
430
3.08M
    len = len64;
431
3.08M
    if (len + header_len + num_bytes < len) {
432
      // Overflow.
433
0
      return 0;
434
0
    }
435
3.08M
    len += header_len + num_bytes;
436
3.08M
    if (out_header_len != nullptr) {
437
2.29M
      *out_header_len = header_len + num_bytes;
438
2.29M
    }
439
3.08M
  }
440
441
26.1M
  return CBS_get_bytes(cbs, out, len);
442
26.2M
}
443
444
1.21k
int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) {
445
1.21k
  size_t header_len;
446
1.21k
  if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
447
455
    return 0;
448
455
  }
449
450
756
  if (out && !CBS_skip(out, header_len)) {
451
0
    assert(0);
452
0
    return 0;
453
0
  }
454
455
756
  return 1;
456
756
}
457
458
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
459
24.3M
                             size_t *out_header_len) {
460
24.3M
  return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, nullptr,
461
24.3M
                                  nullptr,
462
24.3M
                                  /*ber_ok=*/0);
463
24.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.88M
                                 int *out_indefinite) {
468
1.88M
  int ber_found_temp;
469
1.88M
  return cbs_get_any_asn1_element(
470
1.88M
      cbs, out, out_tag, out_header_len,
471
1.88M
      out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite,
472
1.88M
      /*ber_ok=*/1);
473
1.88M
}
474
475
static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value,
476
15.9M
                        int skip_header) {
477
15.9M
  size_t header_len;
478
15.9M
  CBS_ASN1_TAG tag;
479
15.9M
  CBS throwaway;
480
481
15.9M
  if (out == nullptr) {
482
645k
    out = &throwaway;
483
645k
  }
484
485
15.9M
  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
125k
int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
503
125k
  return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
504
125k
}
505
506
7.83M
CBS_ASN1_TAG CBS_peek_any_asn1_tag(const CBS *cbs) {
507
7.83M
  CBS copy = *cbs;
508
7.83M
  CBS_ASN1_TAG tag;
509
7.83M
  if (!parse_asn1_tag(&copy, &tag)) {
510
1.82M
    return 0;
511
1.82M
  }
512
6.00M
  return tag;
513
7.83M
}
514
515
7.83M
int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) {
516
7.83M
  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.83M
  return actual_tag != 0 && actual_tag == tag_value;
520
7.83M
}
521
522
998k
int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
523
998k
  return CBS_get_asn1_uint64_with_tag(cbs, out, CBS_ASN1_INTEGER);
524
998k
}
525
526
998k
int CBS_get_asn1_uint64_with_tag(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag) {
527
998k
  CBS bytes;
528
998k
  if (!CBS_get_asn1(cbs, &bytes, tag) ||
529
990k
      !CBS_is_unsigned_asn1_integer(&bytes)) {
530
10.8k
    return 0;
531
10.8k
  }
532
533
987k
  *out = 0;
534
987k
  const uint8_t *data = CBS_data(&bytes);
535
987k
  size_t len = CBS_len(&bytes);
536
2.63M
  for (size_t i = 0; i < len; i++) {
537
1.65M
    if ((*out >> 56) != 0) {
538
      // Too large to represent as a uint64_t.
539
1.39k
      return 0;
540
1.39k
    }
541
1.64M
    *out <<= 8;
542
1.64M
    *out |= data[i];
543
1.64M
  }
544
545
986k
  return 1;
546
987k
}
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.36k
int CBS_get_asn1_bool(CBS *cbs, int *out) {
572
1.36k
  CBS bytes;
573
1.36k
  if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || CBS_len(&bytes) != 1) {
574
166
    return 0;
575
166
  }
576
577
1.19k
  const uint8_t value = *CBS_data(&bytes);
578
1.19k
  if (value != 0 && value != 0xff) {
579
46
    return 0;
580
46
  }
581
582
1.15k
  *out = !!value;
583
1.15k
  return 1;
584
1.19k
}
585
586
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
587
3.67M
                          CBS_ASN1_TAG tag) {
588
3.67M
  int present = 0;
589
590
3.67M
  if (CBS_peek_asn1_tag(cbs, tag)) {
591
917k
    if (!CBS_get_asn1(cbs, out, tag)) {
592
9.08k
      return 0;
593
9.08k
    }
594
908k
    present = 1;
595
908k
  }
596
597
3.66M
  if (out_present != nullptr) {
598
3.35M
    *out_present = present;
599
3.35M
  }
600
601
3.66M
  return 1;
602
3.67M
}
603
604
int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
605
1.17M
                                       CBS_ASN1_TAG tag) {
606
1.17M
  CBS child;
607
1.17M
  int present;
608
1.17M
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
609
82
    return 0;
610
82
  }
611
1.17M
  if (present) {
612
260k
    assert(out);
613
260k
    if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
614
259k
        CBS_len(&child) != 0) {
615
393
      return 0;
616
393
    }
617
913k
  } else {
618
913k
    CBS_init(out, nullptr, 0);
619
913k
  }
620
1.17M
  if (out_present) {
621
520k
    *out_present = present;
622
520k
  }
623
1.17M
  return 1;
624
1.17M
}
625
626
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag,
627
785k
                                 uint64_t default_value) {
628
785k
  CBS child;
629
785k
  int present;
630
785k
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
631
47
    return 0;
632
47
  }
633
785k
  if (present) {
634
210k
    if (!CBS_get_asn1_uint64(&child, out) || CBS_len(&child) != 0) {
635
53
      return 0;
636
53
    }
637
575k
  } else {
638
575k
    *out = default_value;
639
575k
  }
640
785k
  return 1;
641
785k
}
642
643
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag,
644
519k
                               int default_value) {
645
519k
  CBS child, child2;
646
519k
  int present;
647
519k
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
648
32
    return 0;
649
32
  }
650
519k
  if (present) {
651
142k
    uint8_t boolean;
652
653
142k
    if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
654
141k
        CBS_len(&child2) != 1 || CBS_len(&child) != 0) {
655
437
      return 0;
656
437
    }
657
658
141k
    boolean = CBS_data(&child2)[0];
659
141k
    if (boolean == 0) {
660
67.4k
      *out = 0;
661
74.3k
    } else if (boolean == 0xff) {
662
74.2k
      *out = 1;
663
74.2k
    } else {
664
63
      return 0;
665
63
    }
666
377k
  } else {
667
377k
    *out = default_value;
668
377k
  }
669
519k
  return 1;
670
519k
}
671
672
438
int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
673
438
  CBS in = *cbs;
674
438
  uint8_t num_unused_bits;
675
438
  if (!CBS_get_u8(&in, &num_unused_bits) || num_unused_bits > 7) {
676
11
    return 0;
677
11
  }
678
679
427
  if (num_unused_bits == 0) {
680
34
    return 1;
681
34
  }
682
683
  // All num_unused_bits bits must exist and be zeros.
684
393
  uint8_t last;
685
393
  if (!CBS_get_last_u8(&in, &last) ||
686
393
      (last & ((1 << num_unused_bits) - 1)) != 0) {
687
9
    return 0;
688
9
  }
689
690
384
  return 1;
691
393
}
692
693
209
int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
694
209
  if (!CBS_is_valid_asn1_bitstring(cbs)) {
695
0
    return 0;
696
0
  }
697
698
209
  const unsigned byte_num = (bit >> 3) + 1;
699
209
  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
209
  return byte_num < CBS_len(cbs) &&
705
209
         (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
706
209
}
707
708
1.56M
int CBS_is_valid_asn1_integer(const CBS *cbs, int *out_is_negative) {
709
1.56M
  CBS copy = *cbs;
710
1.56M
  uint8_t first_byte, second_byte;
711
1.56M
  if (!CBS_get_u8(&copy, &first_byte)) {
712
7.43k
    return 0;  // INTEGERs may not be empty.
713
7.43k
  }
714
1.55M
  if (out_is_negative != nullptr) {
715
1.55M
    *out_is_negative = (first_byte & 0x80) != 0;
716
1.55M
  }
717
1.55M
  if (!CBS_get_u8(&copy, &second_byte)) {
718
534k
    return 1;  // One byte INTEGERs are always minimal.
719
534k
  }
720
1.02M
  if ((first_byte == 0x00 && (second_byte & 0x80) == 0) ||
721
1.02M
      (first_byte == 0xff && (second_byte & 0x80) != 0)) {
722
4.96k
    return 0;  // The value is minimal iff the first 9 bits are not all equal.
723
4.96k
  }
724
1.01M
  return 1;
725
1.02M
}
726
727
994k
int CBS_is_unsigned_asn1_integer(const CBS *cbs) {
728
994k
  int is_negative;
729
994k
  return CBS_is_valid_asn1_integer(cbs, &is_negative) && !is_negative;
730
994k
}
731
732
2.17M
int CBS_is_valid_asn1_oid(const CBS *cbs) {
733
2.17M
  if (CBS_len(cbs) == 0) {
734
68
    return 0;  // OID encodings cannot be empty.
735
68
  }
736
737
2.17M
  CBS copy = *cbs;
738
2.17M
  uint8_t v, prev = 0;
739
16.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
13.8M
    if ((prev & 0x80) == 0 && v == 0x80) {
746
54
      return 0;
747
54
    }
748
13.8M
    prev = v;
749
13.8M
  }
750
751
  // The last byte should must end an integer encoding.
752
2.17M
  return (prev & 0x80) == 0;
753
2.17M
}
754
755
27.1k
char *CBS_asn1_oid_to_text(const CBS *cbs) {
756
27.1k
  CBS copy = *cbs;
757
27.1k
  CBB cbb;
758
27.1k
  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
27.1k
  uint64_t v;
764
27.1k
  if (!CBS_get_asn1_oid_component(&copy, &v)) {
765
166
    goto err;
766
166
  }
767
768
27.0k
  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.6k
             !cbb_add_decimal_ascii(&cbb, v % 40)) {
775
0
    goto err;
776
0
  }
777
778
125k
  while (CBS_len(&copy) != 0) {
779
98.7k
    if (!CBS_get_asn1_oid_component(&copy, &v) || !CBB_add_u8(&cbb, '.') ||
780
98.4k
        !cbb_add_decimal_ascii(&cbb, v)) {
781
235
      goto err;
782
235
    }
783
98.7k
  }
784
785
26.7k
  uint8_t *txt;
786
26.7k
  size_t txt_len;
787
26.7k
  if (!CBB_add_u8(&cbb, '\0') || !CBB_finish(&cbb, &txt, &txt_len)) {
788
0
    goto err;
789
0
  }
790
791
26.7k
  return (char *)txt;
792
793
401
err:
794
401
  CBB_cleanup(&cbb);
795
401
  return nullptr;
796
26.7k
}
797
798
0
int CBS_is_valid_asn1_relative_oid(const CBS *cbs) {
799
0
  return CBS_is_valid_asn1_oid(cbs);
800
0
}
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.35M
static int cbs_get_two_digits(CBS *cbs, int *out) {
822
2.35M
  uint8_t first_digit, second_digit;
823
2.35M
  if (!CBS_get_u8(cbs, &first_digit)) {
824
514
    return 0;
825
514
  }
826
2.35M
  if (!OPENSSL_isdigit(first_digit)) {
827
1.11k
    return 0;
828
1.11k
  }
829
2.35M
  if (!CBS_get_u8(cbs, &second_digit)) {
830
356
    return 0;
831
356
  }
832
2.35M
  if (!OPENSSL_isdigit(second_digit)) {
833
902
    return 0;
834
902
  }
835
2.35M
  *out = (first_digit - '0') * 10 + (second_digit - '0');
836
2.35M
  return 1;
837
2.35M
}
838
839
390k
static int is_valid_day(int year, int month, int day) {
840
390k
  if (day < 1) {
841
40
    return 0;
842
40
  }
843
390k
  switch (month) {
844
5.28k
    case 1:
845
10.0k
    case 3:
846
58.2k
    case 5:
847
65.3k
    case 7:
848
71.8k
    case 8:
849
77.5k
    case 10:
850
142k
    case 12:
851
142k
      return day <= 31;
852
83.3k
    case 4:
853
87.7k
    case 6:
854
89.9k
    case 9:
855
172k
    case 11:
856
172k
      return day <= 30;
857
75.9k
    case 2:
858
75.9k
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
859
36.3k
        return day <= 29;
860
39.5k
      } else {
861
39.5k
        return day <= 28;
862
39.5k
      }
863
0
    default:
864
0
      return 0;
865
390k
  }
866
390k
}
867
868
static int CBS_parse_rfc5280_time_internal(const CBS *cbs, int is_gentime,
869
                                           int allow_timezone_offset,
870
393k
                                           struct tm *out_tm) {
871
393k
  int year, month, day, hour, min, sec, tmp;
872
393k
  CBS copy = *cbs;
873
393k
  uint8_t tz;
874
875
393k
  if (is_gentime) {
876
3.49k
    if (!cbs_get_two_digits(&copy, &tmp)) {
877
545
      return 0;
878
545
    }
879
2.94k
    year = tmp * 100;
880
2.94k
    if (!cbs_get_two_digits(&copy, &tmp)) {
881
570
      return 0;
882
570
    }
883
2.37k
    year += tmp;
884
389k
  } else {
885
389k
    year = 1900;
886
389k
    if (!cbs_get_two_digits(&copy, &tmp)) {
887
214
      return 0;
888
214
    }
889
389k
    year += tmp;
890
389k
    if (year < 1950) {
891
372k
      year += 100;
892
372k
    }
893
389k
    if (year >= 2050) {
894
0
      return 0;  // A Generalized time must be used.
895
0
    }
896
389k
  }
897
391k
  if (!cbs_get_two_digits(&copy, &month) || month < 1 ||
898
391k
      month > 12 ||  // Reject invalid months.
899
391k
      !cbs_get_two_digits(&copy, &day) ||
900
390k
      !is_valid_day(year, month, day) ||  // Reject invalid days.
901
390k
      !cbs_get_two_digits(&copy, &hour) ||
902
390k
      hour > 23 ||  // Reject invalid hours.
903
390k
      !cbs_get_two_digits(&copy, &min) ||
904
390k
      min > 59 ||  // Reject invalid minutes.
905
390k
      !cbs_get_two_digits(&copy, &sec) || sec > 59 || !CBS_get_u8(&copy, &tz)) {
906
2.14k
    return 0;
907
2.14k
  }
908
909
389k
  int offset_sign = 0;
910
389k
  switch (tz) {
911
388k
    case 'Z':
912
388k
      break;  // We correctly have 'Z' on the end as per spec.
913
984
    case '+':
914
984
      offset_sign = -1;
915
984
      break;  // Should not be allowed per RFC 5280.
916
658
    case '-':
917
658
      offset_sign = 1;
918
658
      break;  // Should not be allowed per RFC 5280.
919
148
    default:
920
148
      return 0;  // Reject anything else after the time.
921
389k
  }
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
389k
  int offset_seconds = 0;
936
389k
  if (offset_sign != 0) {
937
1.64k
    if (!allow_timezone_offset) {
938
27
      return 0;
939
27
    }
940
1.61k
    int offset_hours, offset_minutes;
941
1.61k
    if (!cbs_get_two_digits(&copy, &offset_hours) ||
942
1.55k
        offset_hours > 23 ||  // Reject invalid hours.
943
1.52k
        !cbs_get_two_digits(&copy, &offset_minutes) ||
944
1.48k
        offset_minutes > 59) {  // Reject invalid minutes.
945
160
      return 0;
946
160
    }
947
1.45k
    offset_seconds = offset_sign * (offset_hours * 3600 + offset_minutes * 60);
948
1.45k
  }
949
950
389k
  if (CBS_len(&copy) != 0) {
951
115
    return 0;  // Reject invalid lengths.
952
115
  }
953
954
389k
  if (out_tm != nullptr) {
955
    // Fill in the tm fields corresponding to what we validated.
956
5.73k
    out_tm->tm_year = year - 1900;
957
5.73k
    out_tm->tm_mon = month - 1;
958
5.73k
    out_tm->tm_mday = day;
959
5.73k
    out_tm->tm_hour = hour;
960
5.73k
    out_tm->tm_min = min;
961
5.73k
    out_tm->tm_sec = sec;
962
5.73k
    if (offset_seconds && !OPENSSL_gmtime_adj(out_tm, 0, offset_seconds)) {
963
0
      return 0;
964
0
    }
965
5.73k
  }
966
389k
  return 1;
967
389k
}
968
969
int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm,
970
3.49k
                               int allow_timezone_offset) {
971
3.49k
  return CBS_parse_rfc5280_time_internal(cbs, 1, allow_timezone_offset, out_tm);
972
3.49k
}
973
974
int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm,
975
389k
                       int allow_timezone_offset) {
976
389k
  return CBS_parse_rfc5280_time_internal(cbs, 0, allow_timezone_offset, out_tm);
977
389k
}