xref: /aosp_15_r20/external/boringssl/src/crypto/bytestring/cbs.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
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 <inttypes.h>
22 #include <string.h>
23 
24 #include "../asn1/internal.h"
25 #include "../internal.h"
26 #include "internal.h"
27 
28 
cbs_get(CBS * cbs,const uint8_t ** p,size_t n)29 static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
30   if (cbs->len < n) {
31     return 0;
32   }
33 
34   *p = cbs->data;
35   cbs->data += n;
36   cbs->len -= n;
37   return 1;
38 }
39 
CBS_skip(CBS * cbs,size_t len)40 int CBS_skip(CBS *cbs, size_t len) {
41   const uint8_t *dummy;
42   return cbs_get(cbs, &dummy, len);
43 }
44 
CBS_stow(const CBS * cbs,uint8_t ** out_ptr,size_t * out_len)45 int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
46   OPENSSL_free(*out_ptr);
47   *out_ptr = NULL;
48   *out_len = 0;
49 
50   if (cbs->len == 0) {
51     return 1;
52   }
53   *out_ptr = OPENSSL_memdup(cbs->data, cbs->len);
54   if (*out_ptr == NULL) {
55     return 0;
56   }
57   *out_len = cbs->len;
58   return 1;
59 }
60 
CBS_strdup(const CBS * cbs,char ** out_ptr)61 int CBS_strdup(const CBS *cbs, char **out_ptr) {
62   if (*out_ptr != NULL) {
63     OPENSSL_free(*out_ptr);
64   }
65   *out_ptr = OPENSSL_strndup((const char*)cbs->data, cbs->len);
66   return (*out_ptr != NULL);
67 }
68 
CBS_contains_zero_byte(const CBS * cbs)69 int CBS_contains_zero_byte(const CBS *cbs) {
70   return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
71 }
72 
CBS_mem_equal(const CBS * cbs,const uint8_t * data,size_t len)73 int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
74   if (len != cbs->len) {
75     return 0;
76   }
77   return CRYPTO_memcmp(cbs->data, data, len) == 0;
78 }
79 
cbs_get_u(CBS * cbs,uint64_t * out,size_t len)80 static int cbs_get_u(CBS *cbs, uint64_t *out, size_t len) {
81   uint64_t result = 0;
82   const uint8_t *data;
83 
84   if (!cbs_get(cbs, &data, len)) {
85     return 0;
86   }
87   for (size_t i = 0; i < len; i++) {
88     result <<= 8;
89     result |= data[i];
90   }
91   *out = result;
92   return 1;
93 }
94 
CBS_get_u8(CBS * cbs,uint8_t * out)95 int CBS_get_u8(CBS *cbs, uint8_t *out) {
96   const uint8_t *v;
97   if (!cbs_get(cbs, &v, 1)) {
98     return 0;
99   }
100   *out = *v;
101   return 1;
102 }
103 
CBS_get_u16(CBS * cbs,uint16_t * out)104 int CBS_get_u16(CBS *cbs, uint16_t *out) {
105   uint64_t v;
106   if (!cbs_get_u(cbs, &v, 2)) {
107     return 0;
108   }
109   *out = v;
110   return 1;
111 }
112 
CBS_get_u16le(CBS * cbs,uint16_t * out)113 int CBS_get_u16le(CBS *cbs, uint16_t *out) {
114   if (!CBS_get_u16(cbs, out)) {
115     return 0;
116   }
117   *out = CRYPTO_bswap2(*out);
118   return 1;
119 }
120 
CBS_get_u24(CBS * cbs,uint32_t * out)121 int CBS_get_u24(CBS *cbs, uint32_t *out) {
122   uint64_t v;
123   if (!cbs_get_u(cbs, &v, 3)) {
124     return 0;
125   }
126   *out = (uint32_t)v;
127   return 1;
128 }
129 
CBS_get_u32(CBS * cbs,uint32_t * out)130 int CBS_get_u32(CBS *cbs, uint32_t *out) {
131   uint64_t v;
132   if (!cbs_get_u(cbs, &v, 4)) {
133     return 0;
134   }
135   *out = (uint32_t)v;
136   return 1;
137 }
138 
CBS_get_u32le(CBS * cbs,uint32_t * out)139 int CBS_get_u32le(CBS *cbs, uint32_t *out) {
140   if (!CBS_get_u32(cbs, out)) {
141     return 0;
142   }
143   *out = CRYPTO_bswap4(*out);
144   return 1;
145 }
146 
CBS_get_u64(CBS * cbs,uint64_t * out)147 int CBS_get_u64(CBS *cbs, uint64_t *out) {
148   return cbs_get_u(cbs, out, 8);
149 }
150 
CBS_get_u64le(CBS * cbs,uint64_t * out)151 int CBS_get_u64le(CBS *cbs, uint64_t *out) {
152   if (!cbs_get_u(cbs, out, 8)) {
153     return 0;
154   }
155   *out = CRYPTO_bswap8(*out);
156   return 1;
157 }
158 
CBS_get_last_u8(CBS * cbs,uint8_t * out)159 int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
160   if (cbs->len == 0) {
161     return 0;
162   }
163   *out = cbs->data[cbs->len - 1];
164   cbs->len--;
165   return 1;
166 }
167 
CBS_get_bytes(CBS * cbs,CBS * out,size_t len)168 int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
169   const uint8_t *v;
170   if (!cbs_get(cbs, &v, len)) {
171     return 0;
172   }
173   CBS_init(out, v, len);
174   return 1;
175 }
176 
CBS_copy_bytes(CBS * cbs,uint8_t * out,size_t len)177 int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
178   const uint8_t *v;
179   if (!cbs_get(cbs, &v, len)) {
180     return 0;
181   }
182   OPENSSL_memcpy(out, v, len);
183   return 1;
184 }
185 
cbs_get_length_prefixed(CBS * cbs,CBS * out,size_t len_len)186 static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
187   uint64_t len;
188   if (!cbs_get_u(cbs, &len, len_len)) {
189     return 0;
190   }
191   // If |len_len| <= 3 then we know that |len| will fit into a |size_t|, even on
192   // 32-bit systems.
193   assert(len_len <= 3);
194   return CBS_get_bytes(cbs, out, len);
195 }
196 
CBS_get_u8_length_prefixed(CBS * cbs,CBS * out)197 int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
198   return cbs_get_length_prefixed(cbs, out, 1);
199 }
200 
CBS_get_u16_length_prefixed(CBS * cbs,CBS * out)201 int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
202   return cbs_get_length_prefixed(cbs, out, 2);
203 }
204 
CBS_get_u24_length_prefixed(CBS * cbs,CBS * out)205 int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
206   return cbs_get_length_prefixed(cbs, out, 3);
207 }
208 
CBS_get_until_first(CBS * cbs,CBS * out,uint8_t c)209 int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) {
210   const uint8_t *split = OPENSSL_memchr(CBS_data(cbs), c, CBS_len(cbs));
211   if (split == NULL) {
212     return 0;
213   }
214   return CBS_get_bytes(cbs, out, split - CBS_data(cbs));
215 }
216 
CBS_get_u64_decimal(CBS * cbs,uint64_t * out)217 int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) {
218   uint64_t v = 0;
219   int seen_digit = 0;
220   while (CBS_len(cbs) != 0) {
221     uint8_t c = CBS_data(cbs)[0];
222     if (!OPENSSL_isdigit(c)) {
223       break;
224     }
225     CBS_skip(cbs, 1);
226     if (// Forbid stray leading zeros.
227         (v == 0 && seen_digit) ||
228         // Check for overflow.
229         v > UINT64_MAX / 10 ||  //
230         v * 10 > UINT64_MAX - (c - '0')) {
231       return 0;
232     }
233     v = v * 10 + (c - '0');
234     seen_digit = 1;
235   }
236 
237   *out = v;
238   return seen_digit;
239 }
240 
241 // parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets
242 // |*out| to the result. This is the encoding used in DER for both high tag
243 // number form and OID components.
parse_base128_integer(CBS * cbs,uint64_t * out)244 static int parse_base128_integer(CBS *cbs, uint64_t *out) {
245   uint64_t v = 0;
246   uint8_t b;
247   do {
248     if (!CBS_get_u8(cbs, &b)) {
249       return 0;
250     }
251     if ((v >> (64 - 7)) != 0) {
252       // The value is too large.
253       return 0;
254     }
255     if (v == 0 && b == 0x80) {
256       // The value must be minimally encoded.
257       return 0;
258     }
259     v = (v << 7) | (b & 0x7f);
260 
261     // Values end at an octet with the high bit cleared.
262   } while (b & 0x80);
263 
264   *out = v;
265   return 1;
266 }
267 
parse_asn1_tag(CBS * cbs,CBS_ASN1_TAG * out)268 static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) {
269   uint8_t tag_byte;
270   if (!CBS_get_u8(cbs, &tag_byte)) {
271     return 0;
272   }
273 
274   // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
275   // number no greater than 30.
276   //
277   // If the number portion is 31 (0x1f, the largest value that fits in the
278   // allotted bits), then the tag is more than one byte long and the
279   // continuation bytes contain the tag number.
280   CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
281   CBS_ASN1_TAG tag_number = tag_byte & 0x1f;
282   if (tag_number == 0x1f) {
283     uint64_t v;
284     if (!parse_base128_integer(cbs, &v) ||
285         // Check the tag number is within our supported bounds.
286         v > CBS_ASN1_TAG_NUMBER_MASK ||
287         // Small tag numbers should have used low tag number form, even in BER.
288         v < 0x1f) {
289       return 0;
290     }
291     tag_number = (CBS_ASN1_TAG)v;
292   }
293 
294   tag |= tag_number;
295 
296   // Tag [UNIVERSAL 0] is reserved for use by the encoding. Reject it here to
297   // avoid some ambiguity around ANY values and BER indefinite-length EOCs. See
298   // https://crbug.com/boringssl/455.
299   if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) {
300     return 0;
301   }
302 
303   *out = tag;
304   return 1;
305 }
306 
cbs_get_any_asn1_element(CBS * cbs,CBS * out,CBS_ASN1_TAG * out_tag,size_t * out_header_len,int * out_ber_found,int * out_indefinite,int ber_ok)307 static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
308                                     size_t *out_header_len, int *out_ber_found,
309                                     int *out_indefinite, int ber_ok) {
310   CBS header = *cbs;
311   CBS throwaway;
312 
313   if (out == NULL) {
314     out = &throwaway;
315   }
316   if (ber_ok) {
317     *out_ber_found = 0;
318     *out_indefinite = 0;
319   } else {
320     assert(out_ber_found == NULL);
321     assert(out_indefinite == NULL);
322   }
323 
324   CBS_ASN1_TAG tag;
325   if (!parse_asn1_tag(&header, &tag)) {
326     return 0;
327   }
328   if (out_tag != NULL) {
329     *out_tag = tag;
330   }
331 
332   uint8_t length_byte;
333   if (!CBS_get_u8(&header, &length_byte)) {
334     return 0;
335   }
336 
337   size_t header_len = CBS_len(cbs) - CBS_len(&header);
338 
339   size_t len;
340   // The format for the length encoding is specified in ITU-T X.690 section
341   // 8.1.3.
342   if ((length_byte & 0x80) == 0) {
343     // Short form length.
344     len = ((size_t) length_byte) + header_len;
345     if (out_header_len != NULL) {
346       *out_header_len = header_len;
347     }
348   } else {
349     // The high bit indicate that this is the long form, while the next 7 bits
350     // encode the number of subsequent octets used to encode the length (ITU-T
351     // X.690 clause 8.1.3.5.b).
352     const size_t num_bytes = length_byte & 0x7f;
353     uint64_t len64;
354 
355     if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
356       // indefinite length
357       if (out_header_len != NULL) {
358         *out_header_len = header_len;
359       }
360       *out_ber_found = 1;
361       *out_indefinite = 1;
362       return CBS_get_bytes(cbs, out, header_len);
363     }
364 
365     // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
366     // used as the first byte of the length. If this parser encounters that
367     // value, num_bytes will be parsed as 127, which will fail this check.
368     if (num_bytes == 0 || num_bytes > 4) {
369       return 0;
370     }
371     if (!cbs_get_u(&header, &len64, num_bytes)) {
372       return 0;
373     }
374     // ITU-T X.690 section 10.1 (DER length forms) requires encoding the
375     // length with the minimum number of octets. BER could, technically, have
376     // 125 superfluous zero bytes. We do not attempt to handle that and still
377     // require that the length fit in a |uint32_t| for BER.
378     if (len64 < 128) {
379       // Length should have used short-form encoding.
380       if (ber_ok) {
381         *out_ber_found = 1;
382       } else {
383         return 0;
384       }
385     }
386     if ((len64 >> ((num_bytes - 1) * 8)) == 0) {
387       // Length should have been at least one byte shorter.
388       if (ber_ok) {
389         *out_ber_found = 1;
390       } else {
391         return 0;
392       }
393     }
394     len = len64;
395     if (len + header_len + num_bytes < len) {
396       // Overflow.
397       return 0;
398     }
399     len += header_len + num_bytes;
400     if (out_header_len != NULL) {
401       *out_header_len = header_len + num_bytes;
402     }
403   }
404 
405   return CBS_get_bytes(cbs, out, len);
406 }
407 
CBS_get_any_asn1(CBS * cbs,CBS * out,CBS_ASN1_TAG * out_tag)408 int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) {
409   size_t header_len;
410   if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
411     return 0;
412   }
413 
414   if (!CBS_skip(out, header_len)) {
415     assert(0);
416     return 0;
417   }
418 
419   return 1;
420 }
421 
CBS_get_any_asn1_element(CBS * cbs,CBS * out,CBS_ASN1_TAG * out_tag,size_t * out_header_len)422 int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
423                                     size_t *out_header_len) {
424   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL,
425                                   /*ber_ok=*/0);
426 }
427 
CBS_get_any_ber_asn1_element(CBS * cbs,CBS * out,CBS_ASN1_TAG * out_tag,size_t * out_header_len,int * out_ber_found,int * out_indefinite)428 int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
429                                  size_t *out_header_len, int *out_ber_found,
430                                  int *out_indefinite) {
431   int ber_found_temp;
432   return cbs_get_any_asn1_element(
433       cbs, out, out_tag, out_header_len,
434       out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite,
435       /*ber_ok=*/1);
436 }
437 
cbs_get_asn1(CBS * cbs,CBS * out,CBS_ASN1_TAG tag_value,int skip_header)438 static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value,
439                         int skip_header) {
440   size_t header_len;
441   CBS_ASN1_TAG tag;
442   CBS throwaway;
443 
444   if (out == NULL) {
445     out = &throwaway;
446   }
447 
448   if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
449       tag != tag_value) {
450     return 0;
451   }
452 
453   if (skip_header && !CBS_skip(out, header_len)) {
454     assert(0);
455     return 0;
456   }
457 
458   return 1;
459 }
460 
CBS_get_asn1(CBS * cbs,CBS * out,CBS_ASN1_TAG tag_value)461 int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
462   return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
463 }
464 
CBS_get_asn1_element(CBS * cbs,CBS * out,CBS_ASN1_TAG tag_value)465 int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
466   return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
467 }
468 
CBS_peek_asn1_tag(const CBS * cbs,CBS_ASN1_TAG tag_value)469 int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) {
470   CBS copy = *cbs;
471   CBS_ASN1_TAG actual_tag;
472   return parse_asn1_tag(&copy, &actual_tag) && tag_value == actual_tag;
473 }
474 
CBS_get_asn1_uint64(CBS * cbs,uint64_t * out)475 int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
476   CBS bytes;
477   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) ||
478       !CBS_is_unsigned_asn1_integer(&bytes)) {
479     return 0;
480   }
481 
482   *out = 0;
483   const uint8_t *data = CBS_data(&bytes);
484   size_t len = CBS_len(&bytes);
485   for (size_t i = 0; i < len; i++) {
486     if ((*out >> 56) != 0) {
487       // Too large to represent as a uint64_t.
488       return 0;
489     }
490     *out <<= 8;
491     *out |= data[i];
492   }
493 
494   return 1;
495 }
496 
CBS_get_asn1_int64(CBS * cbs,int64_t * out)497 int CBS_get_asn1_int64(CBS *cbs, int64_t *out) {
498   int is_negative;
499   CBS bytes;
500   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) ||
501       !CBS_is_valid_asn1_integer(&bytes, &is_negative)) {
502     return 0;
503   }
504   const uint8_t *data = CBS_data(&bytes);
505   const size_t len = CBS_len(&bytes);
506   if (len > sizeof(int64_t)) {
507     return 0;
508   }
509   uint8_t sign_extend[sizeof(int64_t)];
510   OPENSSL_memset(sign_extend, is_negative ? 0xff : 0, sizeof(sign_extend));
511   OPENSSL_memcpy(sign_extend + sizeof(int64_t) - len, data, len);
512   *out = CRYPTO_load_u64_be(sign_extend);
513   return 1;
514 }
515 
CBS_get_asn1_bool(CBS * cbs,int * out)516 int CBS_get_asn1_bool(CBS *cbs, int *out) {
517   CBS bytes;
518   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) ||
519       CBS_len(&bytes) != 1) {
520     return 0;
521   }
522 
523   const uint8_t value = *CBS_data(&bytes);
524   if (value != 0 && value != 0xff) {
525     return 0;
526   }
527 
528   *out = !!value;
529   return 1;
530 }
531 
CBS_get_optional_asn1(CBS * cbs,CBS * out,int * out_present,CBS_ASN1_TAG tag)532 int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, CBS_ASN1_TAG tag) {
533   int present = 0;
534 
535   if (CBS_peek_asn1_tag(cbs, tag)) {
536     if (!CBS_get_asn1(cbs, out, tag)) {
537       return 0;
538     }
539     present = 1;
540   }
541 
542   if (out_present != NULL) {
543     *out_present = present;
544   }
545 
546   return 1;
547 }
548 
CBS_get_optional_asn1_octet_string(CBS * cbs,CBS * out,int * out_present,CBS_ASN1_TAG tag)549 int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
550                                        CBS_ASN1_TAG tag) {
551   CBS child;
552   int present;
553   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
554     return 0;
555   }
556   if (present) {
557     assert(out);
558     if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
559         CBS_len(&child) != 0) {
560       return 0;
561     }
562   } else {
563     CBS_init(out, NULL, 0);
564   }
565   if (out_present) {
566     *out_present = present;
567   }
568   return 1;
569 }
570 
CBS_get_optional_asn1_uint64(CBS * cbs,uint64_t * out,CBS_ASN1_TAG tag,uint64_t default_value)571 int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag,
572                                  uint64_t default_value) {
573   CBS child;
574   int present;
575   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
576     return 0;
577   }
578   if (present) {
579     if (!CBS_get_asn1_uint64(&child, out) ||
580         CBS_len(&child) != 0) {
581       return 0;
582     }
583   } else {
584     *out = default_value;
585   }
586   return 1;
587 }
588 
CBS_get_optional_asn1_bool(CBS * cbs,int * out,CBS_ASN1_TAG tag,int default_value)589 int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag,
590                                int default_value) {
591   CBS child, child2;
592   int present;
593   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
594     return 0;
595   }
596   if (present) {
597     uint8_t boolean;
598 
599     if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
600         CBS_len(&child2) != 1 ||
601         CBS_len(&child) != 0) {
602       return 0;
603     }
604 
605     boolean = CBS_data(&child2)[0];
606     if (boolean == 0) {
607       *out = 0;
608     } else if (boolean == 0xff) {
609       *out = 1;
610     } else {
611       return 0;
612     }
613   } else {
614     *out = default_value;
615   }
616   return 1;
617 }
618 
CBS_is_valid_asn1_bitstring(const CBS * cbs)619 int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
620   CBS in = *cbs;
621   uint8_t num_unused_bits;
622   if (!CBS_get_u8(&in, &num_unused_bits) ||
623       num_unused_bits > 7) {
624     return 0;
625   }
626 
627   if (num_unused_bits == 0) {
628     return 1;
629   }
630 
631   // All num_unused_bits bits must exist and be zeros.
632   uint8_t last;
633   if (!CBS_get_last_u8(&in, &last) ||
634       (last & ((1 << num_unused_bits) - 1)) != 0) {
635     return 0;
636   }
637 
638   return 1;
639 }
640 
CBS_asn1_bitstring_has_bit(const CBS * cbs,unsigned bit)641 int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
642   if (!CBS_is_valid_asn1_bitstring(cbs)) {
643     return 0;
644   }
645 
646   const unsigned byte_num = (bit >> 3) + 1;
647   const unsigned bit_num = 7 - (bit & 7);
648 
649   // Unused bits are zero, and this function does not distinguish between
650   // missing and unset bits. Thus it is sufficient to do a byte-level length
651   // check.
652   return byte_num < CBS_len(cbs) &&
653          (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
654 }
655 
CBS_is_valid_asn1_integer(const CBS * cbs,int * out_is_negative)656 int CBS_is_valid_asn1_integer(const CBS *cbs, int *out_is_negative) {
657   CBS copy = *cbs;
658   uint8_t first_byte, second_byte;
659   if (!CBS_get_u8(&copy, &first_byte)) {
660     return 0;  // INTEGERs may not be empty.
661   }
662   if (out_is_negative != NULL) {
663     *out_is_negative = (first_byte & 0x80) != 0;
664   }
665   if (!CBS_get_u8(&copy, &second_byte)) {
666     return 1;  // One byte INTEGERs are always minimal.
667   }
668   if ((first_byte == 0x00 && (second_byte & 0x80) == 0) ||
669       (first_byte == 0xff && (second_byte & 0x80) != 0)) {
670     return 0;  // The value is minimal iff the first 9 bits are not all equal.
671   }
672   return 1;
673 }
674 
CBS_is_unsigned_asn1_integer(const CBS * cbs)675 int CBS_is_unsigned_asn1_integer(const CBS *cbs) {
676   int is_negative;
677   return CBS_is_valid_asn1_integer(cbs, &is_negative) && !is_negative;
678 }
679 
add_decimal(CBB * out,uint64_t v)680 static int add_decimal(CBB *out, uint64_t v) {
681   char buf[DECIMAL_SIZE(uint64_t) + 1];
682   snprintf(buf, sizeof(buf), "%" PRIu64, v);
683   return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf));
684 }
685 
CBS_is_valid_asn1_oid(const CBS * cbs)686 int CBS_is_valid_asn1_oid(const CBS *cbs) {
687   if (CBS_len(cbs) == 0) {
688     return 0;  // OID encodings cannot be empty.
689   }
690 
691   CBS copy = *cbs;
692   uint8_t v, prev = 0;
693   while (CBS_get_u8(&copy, &v)) {
694     // OID encodings are a sequence of minimally-encoded base-128 integers (see
695     // |parse_base128_integer|). If |prev|'s MSB was clear, it was the last byte
696     // of an integer (or |v| is the first byte). |v| is then the first byte of
697     // the next integer. If first byte of an integer is 0x80, it is not
698     // minimally-encoded.
699     if ((prev & 0x80) == 0 && v == 0x80) {
700       return 0;
701     }
702     prev = v;
703   }
704 
705   // The last byte should must end an integer encoding.
706   return (prev & 0x80) == 0;
707 }
708 
CBS_asn1_oid_to_text(const CBS * cbs)709 char *CBS_asn1_oid_to_text(const CBS *cbs) {
710   CBB cbb;
711   if (!CBB_init(&cbb, 32)) {
712     goto err;
713   }
714 
715   CBS copy = *cbs;
716   // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2.
717   uint64_t v;
718   if (!parse_base128_integer(&copy, &v)) {
719     goto err;
720   }
721 
722   if (v >= 80) {
723     if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
724         !add_decimal(&cbb, v - 80)) {
725       goto err;
726     }
727   } else if (!add_decimal(&cbb, v / 40) ||
728              !CBB_add_u8(&cbb, '.') ||
729              !add_decimal(&cbb, v % 40)) {
730     goto err;
731   }
732 
733   while (CBS_len(&copy) != 0) {
734     if (!parse_base128_integer(&copy, &v) ||
735         !CBB_add_u8(&cbb, '.') ||
736         !add_decimal(&cbb, v)) {
737       goto err;
738     }
739   }
740 
741   uint8_t *txt;
742   size_t txt_len;
743   if (!CBB_add_u8(&cbb, '\0') ||
744       !CBB_finish(&cbb, &txt, &txt_len)) {
745     goto err;
746   }
747 
748   return (char *)txt;
749 
750 err:
751   CBB_cleanup(&cbb);
752   return NULL;
753 }
754 
cbs_get_two_digits(CBS * cbs,int * out)755 static int cbs_get_two_digits(CBS *cbs, int *out) {
756   uint8_t first_digit, second_digit;
757   if (!CBS_get_u8(cbs, &first_digit)) {
758     return 0;
759   }
760   if (!OPENSSL_isdigit(first_digit)) {
761     return 0;
762   }
763   if (!CBS_get_u8(cbs, &second_digit)) {
764     return 0;
765   }
766   if (!OPENSSL_isdigit(second_digit)) {
767     return 0;
768   }
769   *out = (first_digit - '0') * 10 + (second_digit - '0');
770   return 1;
771 }
772 
is_valid_day(int year,int month,int day)773 static int is_valid_day(int year, int month, int day) {
774   if (day < 1) {
775     return 0;
776   }
777   switch (month) {
778     case 1:
779     case 3:
780     case 5:
781     case 7:
782     case 8:
783     case 10:
784     case 12:
785       return day <= 31;
786     case 4:
787     case 6:
788     case 9:
789     case 11:
790       return day <= 30;
791     case 2:
792       if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
793         return day <= 29;
794       } else {
795         return day <= 28;
796       }
797     default:
798       return 0;
799   }
800 }
801 
CBS_parse_rfc5280_time_internal(const CBS * cbs,int is_gentime,int allow_timezone_offset,struct tm * out_tm)802 static int CBS_parse_rfc5280_time_internal(const CBS *cbs, int is_gentime,
803                                            int allow_timezone_offset,
804                                            struct tm *out_tm) {
805   int year, month, day, hour, min, sec, tmp;
806   CBS copy = *cbs;
807   uint8_t tz;
808 
809   if (is_gentime) {
810     if (!cbs_get_two_digits(&copy, &tmp)) {
811       return 0;
812     }
813     year = tmp * 100;
814     if (!cbs_get_two_digits(&copy, &tmp)) {
815       return 0;
816     }
817       year += tmp;
818   } else {
819     year = 1900;
820     if (!cbs_get_two_digits(&copy, &tmp)) {
821       return 0;
822     }
823     year += tmp;
824     if (year < 1950) {
825       year += 100;
826     }
827     if (year >= 2050) {
828       return 0;  // A Generalized time must be used.
829     }
830   }
831   if (!cbs_get_two_digits(&copy, &month) || month < 1 ||
832       month > 12 ||  // Reject invalid months.
833       !cbs_get_two_digits(&copy, &day) ||
834       !is_valid_day(year, month, day) ||  // Reject invalid days.
835       !cbs_get_two_digits(&copy, &hour) ||
836       hour > 23 ||  // Reject invalid hours.
837       !cbs_get_two_digits(&copy, &min) ||
838       min > 59 ||  // Reject invalid minutes.
839       !cbs_get_two_digits(&copy, &sec) || sec > 59 || !CBS_get_u8(&copy, &tz)) {
840     return 0;
841   }
842 
843   int offset_sign = 0;
844   switch (tz) {
845     case 'Z':
846       break;  // We correctly have 'Z' on the end as per spec.
847     case '+':
848       offset_sign = 1;
849       break;  // Should not be allowed per RFC 5280.
850     case '-':
851       offset_sign = -1;
852       break;  // Should not be allowed per RFC 5280.
853     default:
854       return 0;  // Reject anything else after the time.
855   }
856 
857   // If allow_timezone_offset is non-zero, allow for a four digit timezone
858   // offset to be specified even though this is not allowed by RFC 5280. We are
859   // permissive of this for UTCTimes due to the unfortunate existence of
860   // artisinally rolled long lived certificates that were baked into places that
861   // are now difficult to change. These certificates were generated with the
862   // 'openssl' command that permissively allowed the creation of certificates
863   // with notBefore and notAfter times specified as strings for direct
864   // certificate inclusion on the command line. For context see cl/237068815.
865   //
866   // TODO(bbe): This has been expunged from public web-pki as the ecosystem has
867   // managed to encourage CA compliance with standards. We should find a way to
868   // get rid of this or make it off by default.
869   int offset_seconds = 0;
870   if (offset_sign != 0) {
871     if (!allow_timezone_offset) {
872       return 0;
873     }
874     int offset_hours, offset_minutes;
875     if (!cbs_get_two_digits(&copy, &offset_hours) ||
876         offset_hours > 23 ||  // Reject invalid hours.
877         !cbs_get_two_digits(&copy, &offset_minutes) ||
878         offset_minutes > 59) {  // Reject invalid minutes.
879       return 0;
880     }
881     offset_seconds = offset_sign * (offset_hours * 3600 + offset_minutes * 60);
882   }
883 
884   if (CBS_len(&copy) != 0) {
885     return 0;  // Reject invalid lengths.
886   }
887 
888   if (out_tm != NULL) {
889     // Fill in the tm fields corresponding to what we validated.
890     out_tm->tm_year = year - 1900;
891     out_tm->tm_mon = month - 1;
892     out_tm->tm_mday = day;
893     out_tm->tm_hour = hour;
894     out_tm->tm_min = min;
895     out_tm->tm_sec = sec;
896     if (offset_seconds && !OPENSSL_gmtime_adj(out_tm, 0, offset_seconds)) {
897       return 0;
898     }
899   }
900   return 1;
901 }
902 
CBS_parse_generalized_time(const CBS * cbs,struct tm * out_tm,int allow_timezone_offset)903 int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm,
904                                int allow_timezone_offset) {
905   return CBS_parse_rfc5280_time_internal(cbs, 1, allow_timezone_offset, out_tm);
906 }
907 
CBS_parse_utc_time(const CBS * cbs,struct tm * out_tm,int allow_timezone_offset)908 int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm,
909                        int allow_timezone_offset) {
910   return CBS_parse_rfc5280_time_internal(cbs, 0, allow_timezone_offset, out_tm);
911 }
912