Home | History | Annotate | Download | only in bytestring
      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/buf.h>
     16 #include <openssl/mem.h>
     17 #include <openssl/bytestring.h>
     18 
     19 #include <assert.h>
     20 #include <string.h>
     21 
     22 #include "internal.h"
     23 #include "../internal.h"
     24 
     25 
     26 void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
     27   cbs->data = data;
     28   cbs->len = len;
     29 }
     30 
     31 static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
     32   if (cbs->len < n) {
     33     return 0;
     34   }
     35 
     36   *p = cbs->data;
     37   cbs->data += n;
     38   cbs->len -= n;
     39   return 1;
     40 }
     41 
     42 int CBS_skip(CBS *cbs, size_t len) {
     43   const uint8_t *dummy;
     44   return cbs_get(cbs, &dummy, len);
     45 }
     46 
     47 const uint8_t *CBS_data(const CBS *cbs) {
     48   return cbs->data;
     49 }
     50 
     51 size_t CBS_len(const CBS *cbs) {
     52   return cbs->len;
     53 }
     54 
     55 int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
     56   OPENSSL_free(*out_ptr);
     57   *out_ptr = NULL;
     58   *out_len = 0;
     59 
     60   if (cbs->len == 0) {
     61     return 1;
     62   }
     63   *out_ptr = BUF_memdup(cbs->data, cbs->len);
     64   if (*out_ptr == NULL) {
     65     return 0;
     66   }
     67   *out_len = cbs->len;
     68   return 1;
     69 }
     70 
     71 int CBS_strdup(const CBS *cbs, char **out_ptr) {
     72   if (*out_ptr != NULL) {
     73     OPENSSL_free(*out_ptr);
     74   }
     75   *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
     76   return (*out_ptr != NULL);
     77 }
     78 
     79 int CBS_contains_zero_byte(const CBS *cbs) {
     80   return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
     81 }
     82 
     83 int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
     84   if (len != cbs->len) {
     85     return 0;
     86   }
     87   return CRYPTO_memcmp(cbs->data, data, len) == 0;
     88 }
     89 
     90 static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
     91   uint32_t result = 0;
     92   const uint8_t *data;
     93 
     94   if (!cbs_get(cbs, &data, len)) {
     95     return 0;
     96   }
     97   for (size_t i = 0; i < len; i++) {
     98     result <<= 8;
     99     result |= data[i];
    100   }
    101   *out = result;
    102   return 1;
    103 }
    104 
    105 int CBS_get_u8(CBS *cbs, uint8_t *out) {
    106   const uint8_t *v;
    107   if (!cbs_get(cbs, &v, 1)) {
    108     return 0;
    109   }
    110   *out = *v;
    111   return 1;
    112 }
    113 
    114 int CBS_get_u16(CBS *cbs, uint16_t *out) {
    115   uint32_t v;
    116   if (!cbs_get_u(cbs, &v, 2)) {
    117     return 0;
    118   }
    119   *out = v;
    120   return 1;
    121 }
    122 
    123 int CBS_get_u24(CBS *cbs, uint32_t *out) {
    124   return cbs_get_u(cbs, out, 3);
    125 }
    126 
    127 int CBS_get_u32(CBS *cbs, uint32_t *out) {
    128   return cbs_get_u(cbs, out, 4);
    129 }
    130 
    131 int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
    132   if (cbs->len == 0) {
    133     return 0;
    134   }
    135   *out = cbs->data[cbs->len - 1];
    136   cbs->len--;
    137   return 1;
    138 }
    139 
    140 int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
    141   const uint8_t *v;
    142   if (!cbs_get(cbs, &v, len)) {
    143     return 0;
    144   }
    145   CBS_init(out, v, len);
    146   return 1;
    147 }
    148 
    149 int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
    150   const uint8_t *v;
    151   if (!cbs_get(cbs, &v, len)) {
    152     return 0;
    153   }
    154   OPENSSL_memcpy(out, v, len);
    155   return 1;
    156 }
    157 
    158 static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
    159   uint32_t len;
    160   if (!cbs_get_u(cbs, &len, len_len)) {
    161     return 0;
    162   }
    163   return CBS_get_bytes(cbs, out, len);
    164 }
    165 
    166 int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
    167   return cbs_get_length_prefixed(cbs, out, 1);
    168 }
    169 
    170 int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
    171   return cbs_get_length_prefixed(cbs, out, 2);
    172 }
    173 
    174 int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
    175   return cbs_get_length_prefixed(cbs, out, 3);
    176 }
    177 
    178 static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
    179                                     size_t *out_header_len, int ber_ok) {
    180   uint8_t tag, length_byte;
    181   CBS header = *cbs;
    182   CBS throwaway;
    183 
    184   if (out == NULL) {
    185     out = &throwaway;
    186   }
    187 
    188   if (!CBS_get_u8(&header, &tag) ||
    189       !CBS_get_u8(&header, &length_byte)) {
    190     return 0;
    191   }
    192 
    193   /* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
    194    * number no greater than 30.
    195    *
    196    * If the number portion is 31 (0x1f, the largest value that fits in the
    197    * allotted bits), then the tag is more than one byte long and the
    198    * continuation bytes contain the tag number. This parser only supports tag
    199    * numbers less than 31 (and thus single-byte tags). */
    200   if ((tag & 0x1f) == 0x1f) {
    201     return 0;
    202   }
    203 
    204   if (out_tag != NULL) {
    205     *out_tag = tag;
    206   }
    207 
    208   size_t len;
    209   /* The format for the length encoding is specified in ITU-T X.690 section
    210    * 8.1.3. */
    211   if ((length_byte & 0x80) == 0) {
    212     /* Short form length. */
    213     len = ((size_t) length_byte) + 2;
    214     if (out_header_len != NULL) {
    215       *out_header_len = 2;
    216     }
    217   } else {
    218     /* The high bit indicate that this is the long form, while the next 7 bits
    219      * encode the number of subsequent octets used to encode the length (ITU-T
    220      * X.690 clause 8.1.3.5.b). */
    221     const size_t num_bytes = length_byte & 0x7f;
    222     uint32_t len32;
    223 
    224     if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
    225       /* indefinite length */
    226       if (out_header_len != NULL) {
    227         *out_header_len = 2;
    228       }
    229       return CBS_get_bytes(cbs, out, 2);
    230     }
    231 
    232     /* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
    233      * used as the first byte of the length. If this parser encounters that
    234      * value, num_bytes will be parsed as 127, which will fail the check below.
    235      */
    236     if (num_bytes == 0 || num_bytes > 4) {
    237       return 0;
    238     }
    239     if (!cbs_get_u(&header, &len32, num_bytes)) {
    240       return 0;
    241     }
    242     /* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
    243      * with the minimum number of octets. */
    244     if (len32 < 128) {
    245       /* Length should have used short-form encoding. */
    246       return 0;
    247     }
    248     if ((len32 >> ((num_bytes-1)*8)) == 0) {
    249       /* Length should have been at least one byte shorter. */
    250       return 0;
    251     }
    252     len = len32;
    253     if (len + 2 + num_bytes < len) {
    254       /* Overflow. */
    255       return 0;
    256     }
    257     len += 2 + num_bytes;
    258     if (out_header_len != NULL) {
    259       *out_header_len = 2 + num_bytes;
    260     }
    261   }
    262 
    263   return CBS_get_bytes(cbs, out, len);
    264 }
    265 
    266 int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
    267   size_t header_len;
    268   if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
    269     return 0;
    270   }
    271 
    272   if (!CBS_skip(out, header_len)) {
    273     assert(0);
    274     return 0;
    275   }
    276 
    277   return 1;
    278 }
    279 
    280 int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
    281                                     size_t *out_header_len) {
    282   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
    283                                   0 /* DER only */);
    284 }
    285 
    286 int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
    287                                  size_t *out_header_len) {
    288   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
    289                                   1 /* BER allowed */);
    290 }
    291 
    292 static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
    293                         int skip_header) {
    294   size_t header_len;
    295   unsigned tag;
    296   CBS throwaway;
    297 
    298   if (out == NULL) {
    299     out = &throwaway;
    300   }
    301 
    302   if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
    303       tag != tag_value) {
    304     return 0;
    305   }
    306 
    307   if (skip_header && !CBS_skip(out, header_len)) {
    308     assert(0);
    309     return 0;
    310   }
    311 
    312   return 1;
    313 }
    314 
    315 int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
    316   return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
    317 }
    318 
    319 int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
    320   return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
    321 }
    322 
    323 int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
    324   if (CBS_len(cbs) < 1) {
    325     return 0;
    326   }
    327   return CBS_data(cbs)[0] == tag_value;
    328 }
    329 
    330 int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
    331   CBS bytes;
    332   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
    333     return 0;
    334   }
    335 
    336   *out = 0;
    337   const uint8_t *data = CBS_data(&bytes);
    338   size_t len = CBS_len(&bytes);
    339 
    340   if (len == 0) {
    341     /* An INTEGER is encoded with at least one octet. */
    342     return 0;
    343   }
    344 
    345   if ((data[0] & 0x80) != 0) {
    346     /* Negative number. */
    347     return 0;
    348   }
    349 
    350   if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) {
    351     /* Extra leading zeros. */
    352     return 0;
    353   }
    354 
    355   for (size_t i = 0; i < len; i++) {
    356     if ((*out >> 56) != 0) {
    357       /* Too large to represent as a uint64_t. */
    358       return 0;
    359     }
    360     *out <<= 8;
    361     *out |= data[i];
    362   }
    363 
    364   return 1;
    365 }
    366 
    367 int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
    368   int present = 0;
    369 
    370   if (CBS_peek_asn1_tag(cbs, tag)) {
    371     if (!CBS_get_asn1(cbs, out, tag)) {
    372       return 0;
    373     }
    374     present = 1;
    375   }
    376 
    377   if (out_present != NULL) {
    378     *out_present = present;
    379   }
    380 
    381   return 1;
    382 }
    383 
    384 int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
    385                                        unsigned tag) {
    386   CBS child;
    387   int present;
    388   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    389     return 0;
    390   }
    391   if (present) {
    392     if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
    393         CBS_len(&child) != 0) {
    394       return 0;
    395     }
    396   } else {
    397     CBS_init(out, NULL, 0);
    398   }
    399   if (out_present) {
    400     *out_present = present;
    401   }
    402   return 1;
    403 }
    404 
    405 int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
    406                                  uint64_t default_value) {
    407   CBS child;
    408   int present;
    409   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    410     return 0;
    411   }
    412   if (present) {
    413     if (!CBS_get_asn1_uint64(&child, out) ||
    414         CBS_len(&child) != 0) {
    415       return 0;
    416     }
    417   } else {
    418     *out = default_value;
    419   }
    420   return 1;
    421 }
    422 
    423 int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
    424                                int default_value) {
    425   CBS child, child2;
    426   int present;
    427   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    428     return 0;
    429   }
    430   if (present) {
    431     uint8_t boolean;
    432 
    433     if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
    434         CBS_len(&child2) != 1 ||
    435         CBS_len(&child) != 0) {
    436       return 0;
    437     }
    438 
    439     boolean = CBS_data(&child2)[0];
    440     if (boolean == 0) {
    441       *out = 0;
    442     } else if (boolean == 0xff) {
    443       *out = 1;
    444     } else {
    445       return 0;
    446     }
    447   } else {
    448     *out = default_value;
    449   }
    450   return 1;
    451 }
    452 
    453 int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
    454   CBS in = *cbs;
    455   uint8_t num_unused_bits;
    456   if (!CBS_get_u8(&in, &num_unused_bits) ||
    457       num_unused_bits > 7) {
    458     return 0;
    459   }
    460 
    461   if (num_unused_bits == 0) {
    462     return 1;
    463   }
    464 
    465   /* All num_unused_bits bits must exist and be zeros. */
    466   uint8_t last;
    467   if (!CBS_get_last_u8(&in, &last) ||
    468       (last & ((1 << num_unused_bits) - 1)) != 0) {
    469     return 0;
    470   }
    471 
    472   return 1;
    473 }
    474 
    475 int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
    476   if (!CBS_is_valid_asn1_bitstring(cbs)) {
    477     return 0;
    478   }
    479 
    480   const unsigned byte_num = (bit >> 3) + 1;
    481   const unsigned bit_num = 7 - (bit & 7);
    482 
    483   /* Unused bits are zero, and this function does not distinguish between
    484    * missing and unset bits. Thus it is sufficient to do a byte-level length
    485    * check. */
    486   return byte_num < CBS_len(cbs) &&
    487          (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
    488 }
    489