• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if !defined(__STDC_FORMAT_MACROS)
16 #define __STDC_FORMAT_MACROS
17 #endif
18 
19 #include <openssl/buf.h>
20 #include <openssl/mem.h>
21 #include <openssl/bytestring.h>
22 
23 #include <assert.h>
24 #include <inttypes.h>
25 #include <string.h>
26 
27 #include "internal.h"
28 #include "../internal.h"
29 
30 
CBS_init(CBS * cbs,const uint8_t * data,size_t len)31 void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
32   cbs->data = data;
33   cbs->len = len;
34 }
35 
cbs_get(CBS * cbs,const uint8_t ** p,size_t n)36 static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
37   if (cbs->len < n) {
38     return 0;
39   }
40 
41   *p = cbs->data;
42   cbs->data += n;
43   cbs->len -= n;
44   return 1;
45 }
46 
CBS_skip(CBS * cbs,size_t len)47 int CBS_skip(CBS *cbs, size_t len) {
48   const uint8_t *dummy;
49   return cbs_get(cbs, &dummy, len);
50 }
51 
CBS_data(const CBS * cbs)52 const uint8_t *CBS_data(const CBS *cbs) {
53   return cbs->data;
54 }
55 
CBS_len(const CBS * cbs)56 size_t CBS_len(const CBS *cbs) {
57   return cbs->len;
58 }
59 
CBS_stow(const CBS * cbs,uint8_t ** out_ptr,size_t * out_len)60 int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
61   OPENSSL_free(*out_ptr);
62   *out_ptr = NULL;
63   *out_len = 0;
64 
65   if (cbs->len == 0) {
66     return 1;
67   }
68   *out_ptr = BUF_memdup(cbs->data, cbs->len);
69   if (*out_ptr == NULL) {
70     return 0;
71   }
72   *out_len = cbs->len;
73   return 1;
74 }
75 
CBS_strdup(const CBS * cbs,char ** out_ptr)76 int CBS_strdup(const CBS *cbs, char **out_ptr) {
77   if (*out_ptr != NULL) {
78     OPENSSL_free(*out_ptr);
79   }
80   *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
81   return (*out_ptr != NULL);
82 }
83 
CBS_contains_zero_byte(const CBS * cbs)84 int CBS_contains_zero_byte(const CBS *cbs) {
85   return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
86 }
87 
CBS_mem_equal(const CBS * cbs,const uint8_t * data,size_t len)88 int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
89   if (len != cbs->len) {
90     return 0;
91   }
92   return CRYPTO_memcmp(cbs->data, data, len) == 0;
93 }
94 
cbs_get_u(CBS * cbs,uint32_t * out,size_t len)95 static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
96   uint32_t result = 0;
97   const uint8_t *data;
98 
99   if (!cbs_get(cbs, &data, len)) {
100     return 0;
101   }
102   for (size_t i = 0; i < len; i++) {
103     result <<= 8;
104     result |= data[i];
105   }
106   *out = result;
107   return 1;
108 }
109 
CBS_get_u8(CBS * cbs,uint8_t * out)110 int CBS_get_u8(CBS *cbs, uint8_t *out) {
111   const uint8_t *v;
112   if (!cbs_get(cbs, &v, 1)) {
113     return 0;
114   }
115   *out = *v;
116   return 1;
117 }
118 
CBS_get_u16(CBS * cbs,uint16_t * out)119 int CBS_get_u16(CBS *cbs, uint16_t *out) {
120   uint32_t v;
121   if (!cbs_get_u(cbs, &v, 2)) {
122     return 0;
123   }
124   *out = v;
125   return 1;
126 }
127 
CBS_get_u24(CBS * cbs,uint32_t * out)128 int CBS_get_u24(CBS *cbs, uint32_t *out) {
129   return cbs_get_u(cbs, out, 3);
130 }
131 
CBS_get_u32(CBS * cbs,uint32_t * out)132 int CBS_get_u32(CBS *cbs, uint32_t *out) {
133   return cbs_get_u(cbs, out, 4);
134 }
135 
CBS_get_last_u8(CBS * cbs,uint8_t * out)136 int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
137   if (cbs->len == 0) {
138     return 0;
139   }
140   *out = cbs->data[cbs->len - 1];
141   cbs->len--;
142   return 1;
143 }
144 
CBS_get_bytes(CBS * cbs,CBS * out,size_t len)145 int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
146   const uint8_t *v;
147   if (!cbs_get(cbs, &v, len)) {
148     return 0;
149   }
150   CBS_init(out, v, len);
151   return 1;
152 }
153 
CBS_copy_bytes(CBS * cbs,uint8_t * out,size_t len)154 int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
155   const uint8_t *v;
156   if (!cbs_get(cbs, &v, len)) {
157     return 0;
158   }
159   OPENSSL_memcpy(out, v, len);
160   return 1;
161 }
162 
cbs_get_length_prefixed(CBS * cbs,CBS * out,size_t len_len)163 static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
164   uint32_t len;
165   if (!cbs_get_u(cbs, &len, len_len)) {
166     return 0;
167   }
168   return CBS_get_bytes(cbs, out, len);
169 }
170 
CBS_get_u8_length_prefixed(CBS * cbs,CBS * out)171 int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
172   return cbs_get_length_prefixed(cbs, out, 1);
173 }
174 
CBS_get_u16_length_prefixed(CBS * cbs,CBS * out)175 int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
176   return cbs_get_length_prefixed(cbs, out, 2);
177 }
178 
CBS_get_u24_length_prefixed(CBS * cbs,CBS * out)179 int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
180   return cbs_get_length_prefixed(cbs, out, 3);
181 }
182 
183 // parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets
184 // |*out| to the result. This is the encoding used in DER for both high tag
185 // number form and OID components.
parse_base128_integer(CBS * cbs,uint64_t * out)186 static int parse_base128_integer(CBS *cbs, uint64_t *out) {
187   uint64_t v = 0;
188   uint8_t b;
189   do {
190     if (!CBS_get_u8(cbs, &b)) {
191       return 0;
192     }
193     if ((v >> (64 - 7)) != 0) {
194       // The value is too large.
195       return 0;
196     }
197     if (v == 0 && b == 0x80) {
198       // The value must be minimally encoded.
199       return 0;
200     }
201     v = (v << 7) | (b & 0x7f);
202 
203     // Values end at an octet with the high bit cleared.
204   } while (b & 0x80);
205 
206   *out = v;
207   return 1;
208 }
209 
parse_asn1_tag(CBS * cbs,unsigned * out)210 static int parse_asn1_tag(CBS *cbs, unsigned *out) {
211   uint8_t tag_byte;
212   if (!CBS_get_u8(cbs, &tag_byte)) {
213     return 0;
214   }
215 
216   // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
217   // number no greater than 30.
218   //
219   // If the number portion is 31 (0x1f, the largest value that fits in the
220   // allotted bits), then the tag is more than one byte long and the
221   // continuation bytes contain the tag number. This parser only supports tag
222   // numbers less than 31 (and thus single-byte tags).
223   unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
224   unsigned tag_number = tag_byte & 0x1f;
225   if (tag_number == 0x1f) {
226     uint64_t v;
227     if (!parse_base128_integer(cbs, &v) ||
228         // Check the tag number is within our supported bounds.
229         v > CBS_ASN1_TAG_NUMBER_MASK ||
230         // Small tag numbers should have used low tag number form.
231         v < 0x1f) {
232       return 0;
233     }
234     tag_number = (unsigned)v;
235   }
236 
237   tag |= tag_number;
238 
239   *out = tag;
240   return 1;
241 }
242 
cbs_get_any_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len,int ber_ok)243 static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
244                                     size_t *out_header_len, int ber_ok) {
245   CBS header = *cbs;
246   CBS throwaway;
247 
248   if (out == NULL) {
249     out = &throwaway;
250   }
251 
252   unsigned tag;
253   if (!parse_asn1_tag(&header, &tag)) {
254     return 0;
255   }
256   if (out_tag != NULL) {
257     *out_tag = tag;
258   }
259 
260   uint8_t length_byte;
261   if (!CBS_get_u8(&header, &length_byte)) {
262     return 0;
263   }
264 
265   size_t header_len = CBS_len(cbs) - CBS_len(&header);
266 
267   size_t len;
268   // The format for the length encoding is specified in ITU-T X.690 section
269   // 8.1.3.
270   if ((length_byte & 0x80) == 0) {
271     // Short form length.
272     len = ((size_t) length_byte) + header_len;
273     if (out_header_len != NULL) {
274       *out_header_len = header_len;
275     }
276   } else {
277     // The high bit indicate that this is the long form, while the next 7 bits
278     // encode the number of subsequent octets used to encode the length (ITU-T
279     // X.690 clause 8.1.3.5.b).
280     const size_t num_bytes = length_byte & 0x7f;
281     uint32_t len32;
282 
283     if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
284       // indefinite length
285       if (out_header_len != NULL) {
286         *out_header_len = header_len;
287       }
288       return CBS_get_bytes(cbs, out, header_len);
289     }
290 
291     // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
292     // used as the first byte of the length. If this parser encounters that
293     // value, num_bytes will be parsed as 127, which will fail the check below.
294     if (num_bytes == 0 || num_bytes > 4) {
295       return 0;
296     }
297     if (!cbs_get_u(&header, &len32, num_bytes)) {
298       return 0;
299     }
300     // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
301     // with the minimum number of octets.
302     if (len32 < 128) {
303       // Length should have used short-form encoding.
304       return 0;
305     }
306     if ((len32 >> ((num_bytes-1)*8)) == 0) {
307       // Length should have been at least one byte shorter.
308       return 0;
309     }
310     len = len32;
311     if (len + header_len + num_bytes < len) {
312       // Overflow.
313       return 0;
314     }
315     len += header_len + num_bytes;
316     if (out_header_len != NULL) {
317       *out_header_len = header_len + num_bytes;
318     }
319   }
320 
321   return CBS_get_bytes(cbs, out, len);
322 }
323 
CBS_get_any_asn1(CBS * cbs,CBS * out,unsigned * out_tag)324 int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
325   size_t header_len;
326   if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
327     return 0;
328   }
329 
330   if (!CBS_skip(out, header_len)) {
331     assert(0);
332     return 0;
333   }
334 
335   return 1;
336 }
337 
CBS_get_any_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len)338 int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
339                                     size_t *out_header_len) {
340   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
341                                   0 /* DER only */);
342 }
343 
CBS_get_any_ber_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len)344 int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
345                                  size_t *out_header_len) {
346   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
347                                   1 /* BER allowed */);
348 }
349 
cbs_get_asn1(CBS * cbs,CBS * out,unsigned tag_value,int skip_header)350 static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
351                         int skip_header) {
352   size_t header_len;
353   unsigned tag;
354   CBS throwaway;
355 
356   if (out == NULL) {
357     out = &throwaway;
358   }
359 
360   if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
361       tag != tag_value) {
362     return 0;
363   }
364 
365   if (skip_header && !CBS_skip(out, header_len)) {
366     assert(0);
367     return 0;
368   }
369 
370   return 1;
371 }
372 
CBS_get_asn1(CBS * cbs,CBS * out,unsigned tag_value)373 int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
374   return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
375 }
376 
CBS_get_asn1_element(CBS * cbs,CBS * out,unsigned tag_value)377 int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
378   return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
379 }
380 
CBS_peek_asn1_tag(const CBS * cbs,unsigned tag_value)381 int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
382   if (CBS_len(cbs) < 1) {
383     return 0;
384   }
385 
386   CBS copy = *cbs;
387   unsigned actual_tag;
388   return parse_asn1_tag(&copy, &actual_tag) && tag_value == actual_tag;
389 }
390 
CBS_get_asn1_uint64(CBS * cbs,uint64_t * out)391 int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
392   CBS bytes;
393   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
394     return 0;
395   }
396 
397   *out = 0;
398   const uint8_t *data = CBS_data(&bytes);
399   size_t len = CBS_len(&bytes);
400 
401   if (len == 0) {
402     // An INTEGER is encoded with at least one octet.
403     return 0;
404   }
405 
406   if ((data[0] & 0x80) != 0) {
407     // Negative number.
408     return 0;
409   }
410 
411   if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) {
412     // Extra leading zeros.
413     return 0;
414   }
415 
416   for (size_t i = 0; i < len; i++) {
417     if ((*out >> 56) != 0) {
418       // Too large to represent as a uint64_t.
419       return 0;
420     }
421     *out <<= 8;
422     *out |= data[i];
423   }
424 
425   return 1;
426 }
427 
CBS_get_asn1_bool(CBS * cbs,int * out)428 int CBS_get_asn1_bool(CBS *cbs, int *out) {
429   CBS bytes;
430   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) ||
431       CBS_len(&bytes) != 1) {
432     return 0;
433   }
434 
435   const uint8_t value = *CBS_data(&bytes);
436   if (value != 0 && value != 0xff) {
437     return 0;
438   }
439 
440   *out = !!value;
441   return 1;
442 }
443 
CBS_get_optional_asn1(CBS * cbs,CBS * out,int * out_present,unsigned tag)444 int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
445   int present = 0;
446 
447   if (CBS_peek_asn1_tag(cbs, tag)) {
448     if (!CBS_get_asn1(cbs, out, tag)) {
449       return 0;
450     }
451     present = 1;
452   }
453 
454   if (out_present != NULL) {
455     *out_present = present;
456   }
457 
458   return 1;
459 }
460 
CBS_get_optional_asn1_octet_string(CBS * cbs,CBS * out,int * out_present,unsigned tag)461 int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
462                                        unsigned tag) {
463   CBS child;
464   int present;
465   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
466     return 0;
467   }
468   if (present) {
469     if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
470         CBS_len(&child) != 0) {
471       return 0;
472     }
473   } else {
474     CBS_init(out, NULL, 0);
475   }
476   if (out_present) {
477     *out_present = present;
478   }
479   return 1;
480 }
481 
CBS_get_optional_asn1_uint64(CBS * cbs,uint64_t * out,unsigned tag,uint64_t default_value)482 int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
483                                  uint64_t default_value) {
484   CBS child;
485   int present;
486   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
487     return 0;
488   }
489   if (present) {
490     if (!CBS_get_asn1_uint64(&child, out) ||
491         CBS_len(&child) != 0) {
492       return 0;
493     }
494   } else {
495     *out = default_value;
496   }
497   return 1;
498 }
499 
CBS_get_optional_asn1_bool(CBS * cbs,int * out,unsigned tag,int default_value)500 int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
501                                int default_value) {
502   CBS child, child2;
503   int present;
504   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
505     return 0;
506   }
507   if (present) {
508     uint8_t boolean;
509 
510     if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
511         CBS_len(&child2) != 1 ||
512         CBS_len(&child) != 0) {
513       return 0;
514     }
515 
516     boolean = CBS_data(&child2)[0];
517     if (boolean == 0) {
518       *out = 0;
519     } else if (boolean == 0xff) {
520       *out = 1;
521     } else {
522       return 0;
523     }
524   } else {
525     *out = default_value;
526   }
527   return 1;
528 }
529 
CBS_is_valid_asn1_bitstring(const CBS * cbs)530 int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
531   CBS in = *cbs;
532   uint8_t num_unused_bits;
533   if (!CBS_get_u8(&in, &num_unused_bits) ||
534       num_unused_bits > 7) {
535     return 0;
536   }
537 
538   if (num_unused_bits == 0) {
539     return 1;
540   }
541 
542   // All num_unused_bits bits must exist and be zeros.
543   uint8_t last;
544   if (!CBS_get_last_u8(&in, &last) ||
545       (last & ((1 << num_unused_bits) - 1)) != 0) {
546     return 0;
547   }
548 
549   return 1;
550 }
551 
CBS_asn1_bitstring_has_bit(const CBS * cbs,unsigned bit)552 int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
553   if (!CBS_is_valid_asn1_bitstring(cbs)) {
554     return 0;
555   }
556 
557   const unsigned byte_num = (bit >> 3) + 1;
558   const unsigned bit_num = 7 - (bit & 7);
559 
560   // Unused bits are zero, and this function does not distinguish between
561   // missing and unset bits. Thus it is sufficient to do a byte-level length
562   // check.
563   return byte_num < CBS_len(cbs) &&
564          (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
565 }
566 
add_decimal(CBB * out,uint64_t v)567 static int add_decimal(CBB *out, uint64_t v) {
568   char buf[DECIMAL_SIZE(uint64_t) + 1];
569   BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v);
570   return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf));
571 }
572 
CBS_asn1_oid_to_text(const CBS * cbs)573 char *CBS_asn1_oid_to_text(const CBS *cbs) {
574   CBB cbb;
575   if (!CBB_init(&cbb, 32)) {
576     goto err;
577   }
578 
579   CBS copy = *cbs;
580   // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2.
581   uint64_t v;
582   if (!parse_base128_integer(&copy, &v)) {
583     goto err;
584   }
585 
586   if (v >= 80) {
587     if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
588         !add_decimal(&cbb, v - 80)) {
589       goto err;
590     }
591   } else if (!add_decimal(&cbb, v / 40) ||
592              !CBB_add_u8(&cbb, '.') ||
593              !add_decimal(&cbb, v % 40)) {
594     goto err;
595   }
596 
597   while (CBS_len(&copy) != 0) {
598     if (!parse_base128_integer(&copy, &v) ||
599         !CBB_add_u8(&cbb, '.') ||
600         !add_decimal(&cbb, v)) {
601       goto err;
602     }
603   }
604 
605   uint8_t *txt;
606   size_t txt_len;
607   if (!CBB_add_u8(&cbb, '\0') ||
608       !CBB_finish(&cbb, &txt, &txt_len)) {
609     goto err;
610   }
611 
612   return (char *)txt;
613 
614 err:
615   CBB_cleanup(&cbb);
616   return NULL;
617 }
618