/* Copyright 2014 The BoringSSL Authors
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/mem.h>

#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <string.h>

#include "../asn1/internal.h"
#include "../internal.h"
#include "internal.h"


static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
  if (cbs->len < n) {
    return 0;
  }

  *p = cbs->data;
  cbs->data += n;
  cbs->len -= n;
  return 1;
}

int CBS_skip(CBS *cbs, size_t len) {
  const uint8_t *dummy;
  return cbs_get(cbs, &dummy, len);
}

int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
  OPENSSL_free(*out_ptr);
  *out_ptr = NULL;
  *out_len = 0;

  if (cbs->len == 0) {
    return 1;
  }
  *out_ptr = reinterpret_cast<uint8_t *>(OPENSSL_memdup(cbs->data, cbs->len));
  if (*out_ptr == NULL) {
    return 0;
  }
  *out_len = cbs->len;
  return 1;
}

int CBS_strdup(const CBS *cbs, char **out_ptr) {
  if (*out_ptr != NULL) {
    OPENSSL_free(*out_ptr);
  }
  *out_ptr = OPENSSL_strndup((const char *)cbs->data, cbs->len);
  return (*out_ptr != NULL);
}

int CBS_contains_zero_byte(const CBS *cbs) {
  return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
}

int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
  if (len != cbs->len) {
    return 0;
  }
  return CRYPTO_memcmp(cbs->data, data, len) == 0;
}

static int cbs_get_u(CBS *cbs, uint64_t *out, size_t len) {
  uint64_t result = 0;
  const uint8_t *data;

  if (!cbs_get(cbs, &data, len)) {
    return 0;
  }
  for (size_t i = 0; i < len; i++) {
    result <<= 8;
    result |= data[i];
  }
  *out = result;
  return 1;
}

int CBS_get_u8(CBS *cbs, uint8_t *out) {
  const uint8_t *v;
  if (!cbs_get(cbs, &v, 1)) {
    return 0;
  }
  *out = *v;
  return 1;
}

int CBS_get_u16(CBS *cbs, uint16_t *out) {
  uint64_t v;
  if (!cbs_get_u(cbs, &v, 2)) {
    return 0;
  }
  *out = v;
  return 1;
}

int CBS_get_u16le(CBS *cbs, uint16_t *out) {
  if (!CBS_get_u16(cbs, out)) {
    return 0;
  }
  *out = CRYPTO_bswap2(*out);
  return 1;
}

int CBS_get_u24(CBS *cbs, uint32_t *out) {
  uint64_t v;
  if (!cbs_get_u(cbs, &v, 3)) {
    return 0;
  }
  *out = (uint32_t)v;
  return 1;
}

int CBS_get_u32(CBS *cbs, uint32_t *out) {
  uint64_t v;
  if (!cbs_get_u(cbs, &v, 4)) {
    return 0;
  }
  *out = (uint32_t)v;
  return 1;
}

int CBS_get_u32le(CBS *cbs, uint32_t *out) {
  if (!CBS_get_u32(cbs, out)) {
    return 0;
  }
  *out = CRYPTO_bswap4(*out);
  return 1;
}

int CBS_get_u64(CBS *cbs, uint64_t *out) { return cbs_get_u(cbs, out, 8); }

int CBS_get_u64le(CBS *cbs, uint64_t *out) {
  if (!cbs_get_u(cbs, out, 8)) {
    return 0;
  }
  *out = CRYPTO_bswap8(*out);
  return 1;
}

int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
  if (cbs->len == 0) {
    return 0;
  }
  *out = cbs->data[cbs->len - 1];
  cbs->len--;
  return 1;
}

int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
  const uint8_t *v;
  if (!cbs_get(cbs, &v, len)) {
    return 0;
  }
  CBS_init(out, v, len);
  return 1;
}

int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
  const uint8_t *v;
  if (!cbs_get(cbs, &v, len)) {
    return 0;
  }
  OPENSSL_memcpy(out, v, len);
  return 1;
}

static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
  uint64_t len;
  if (!cbs_get_u(cbs, &len, len_len)) {
    return 0;
  }
  // If |len_len| <= 3 then we know that |len| will fit into a |size_t|, even on
  // 32-bit systems.
  assert(len_len <= 3);
  return CBS_get_bytes(cbs, out, len);
}

int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
  return cbs_get_length_prefixed(cbs, out, 1);
}

int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
  return cbs_get_length_prefixed(cbs, out, 2);
}

int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
  return cbs_get_length_prefixed(cbs, out, 3);
}

int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) {
  const uint8_t *split = reinterpret_cast<const uint8_t *>(
      OPENSSL_memchr(CBS_data(cbs), c, CBS_len(cbs)));
  if (split == NULL) {
    return 0;
  }
  return CBS_get_bytes(cbs, out, split - CBS_data(cbs));
}

int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) {
  uint64_t v = 0;
  int seen_digit = 0;
  while (CBS_len(cbs) != 0) {
    uint8_t c = CBS_data(cbs)[0];
    if (!OPENSSL_isdigit(c)) {
      break;
    }
    CBS_skip(cbs, 1);
    if (/* Forbid stray leading zeros */
        (v == 0 && seen_digit) ||
        // Check for overflow.
        v > UINT64_MAX / 10 ||  //
        v * 10 > UINT64_MAX - (c - '0')) {
      return 0;
    }
    v = v * 10 + (c - '0');
    seen_digit = 1;
  }

  *out = v;
  return seen_digit;
}

// parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets
// |*out| to the result. This is the encoding used in DER for both high tag
// number form and OID components.
static int parse_base128_integer(CBS *cbs, uint64_t *out) {
  uint64_t v = 0;
  uint8_t b;
  do {
    if (!CBS_get_u8(cbs, &b)) {
      return 0;
    }
    if ((v >> (64 - 7)) != 0) {
      // The value is too large.
      return 0;
    }
    if (v == 0 && b == 0x80) {
      // The value must be minimally encoded.
      return 0;
    }
    v = (v << 7) | (b & 0x7f);

    // Values end at an octet with the high bit cleared.
  } while (b & 0x80);

  *out = v;
  return 1;
}

static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) {
  uint8_t tag_byte;
  if (!CBS_get_u8(cbs, &tag_byte)) {
    return 0;
  }

  // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
  // number no greater than 30.
  //
  // If the number portion is 31 (0x1f, the largest value that fits in the
  // allotted bits), then the tag is more than one byte long and the
  // continuation bytes contain the tag number.
  CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
  CBS_ASN1_TAG tag_number = tag_byte & 0x1f;
  if (tag_number == 0x1f) {
    uint64_t v;
    if (!parse_base128_integer(cbs, &v) ||
        // Check the tag number is within our supported bounds.
        v > CBS_ASN1_TAG_NUMBER_MASK ||
        // Small tag numbers should have used low tag number form, even in BER.
        v < 0x1f) {
      return 0;
    }
    tag_number = (CBS_ASN1_TAG)v;
  }

  tag |= tag_number;

  // Tag [UNIVERSAL 0] is reserved for use by the encoding. Reject it here to
  // avoid some ambiguity around ANY values and BER indefinite-length EOCs. See
  // https://crbug.com/boringssl/455.
  if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) {
    return 0;
  }

  *out = tag;
  return 1;
}

static int 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) {
  CBS header = *cbs;
  CBS throwaway;

  if (out == NULL) {
    out = &throwaway;
  }
  if (ber_ok) {
    *out_ber_found = 0;
    *out_indefinite = 0;
  } else {
    assert(out_ber_found == NULL);
    assert(out_indefinite == NULL);
  }

  CBS_ASN1_TAG tag;
  if (!parse_asn1_tag(&header, &tag)) {
    return 0;
  }
  if (out_tag != NULL) {
    *out_tag = tag;
  }

  uint8_t length_byte;
  if (!CBS_get_u8(&header, &length_byte)) {
    return 0;
  }

  size_t header_len = CBS_len(cbs) - CBS_len(&header);

  size_t len;
  // The format for the length encoding is specified in ITU-T X.690 section
  // 8.1.3.
  if ((length_byte & 0x80) == 0) {
    // Short form length.
    len = ((size_t)length_byte) + header_len;
    if (out_header_len != NULL) {
      *out_header_len = header_len;
    }
  } else {
    // The high bit indicate that this is the long form, while the next 7 bits
    // encode the number of subsequent octets used to encode the length (ITU-T
    // X.690 clause 8.1.3.5.b).
    const size_t num_bytes = length_byte & 0x7f;
    uint64_t len64;

    if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
      // indefinite length
      if (out_header_len != NULL) {
        *out_header_len = header_len;
      }
      *out_ber_found = 1;
      *out_indefinite = 1;
      return CBS_get_bytes(cbs, out, header_len);
    }

    // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
    // used as the first byte of the length. If this parser encounters that
    // value, num_bytes will be parsed as 127, which will fail this check.
    if (num_bytes == 0 || num_bytes > 4) {
      return 0;
    }
    if (!cbs_get_u(&header, &len64, num_bytes)) {
      return 0;
    }
    // ITU-T X.690 section 10.1 (DER length forms) requires encoding the
    // length with the minimum number of octets. BER could, technically, have
    // 125 superfluous zero bytes. We do not attempt to handle that and still
    // require that the length fit in a |uint32_t| for BER.
    if (len64 < 128) {
      // Length should have used short-form encoding.
      if (ber_ok) {
        *out_ber_found = 1;
      } else {
        return 0;
      }
    }
    if ((len64 >> ((num_bytes - 1) * 8)) == 0) {
      // Length should have been at least one byte shorter.
      if (ber_ok) {
        *out_ber_found = 1;
      } else {
        return 0;
      }
    }
    len = len64;
    if (len + header_len + num_bytes < len) {
      // Overflow.
      return 0;
    }
    len += header_len + num_bytes;
    if (out_header_len != NULL) {
      *out_header_len = header_len + num_bytes;
    }
  }

  return CBS_get_bytes(cbs, out, len);
}

int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) {
  size_t header_len;
  if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
    return 0;
  }

  if (!CBS_skip(out, header_len)) {
    assert(0);
    return 0;
  }

  return 1;
}

int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag,
                             size_t *out_header_len) {
  return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL,
                                  /*ber_ok=*/0);
}

int 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) {
  int ber_found_temp;
  return cbs_get_any_asn1_element(
      cbs, out, out_tag, out_header_len,
      out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite,
      /*ber_ok=*/1);
}

static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value,
                        int skip_header) {
  size_t header_len;
  CBS_ASN1_TAG tag;
  CBS throwaway;

  if (out == NULL) {
    out = &throwaway;
  }

  if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
      tag != tag_value) {
    return 0;
  }

  if (skip_header && !CBS_skip(out, header_len)) {
    assert(0);
    return 0;
  }

  return 1;
}

int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
  return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
}

int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) {
  return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
}

int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) {
  CBS copy = *cbs;
  CBS_ASN1_TAG actual_tag;
  return parse_asn1_tag(&copy, &actual_tag) && tag_value == actual_tag;
}

int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
  CBS bytes;
  if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) ||
      !CBS_is_unsigned_asn1_integer(&bytes)) {
    return 0;
  }

  *out = 0;
  const uint8_t *data = CBS_data(&bytes);
  size_t len = CBS_len(&bytes);
  for (size_t i = 0; i < len; i++) {
    if ((*out >> 56) != 0) {
      // Too large to represent as a uint64_t.
      return 0;
    }
    *out <<= 8;
    *out |= data[i];
  }

  return 1;
}

int CBS_get_asn1_int64(CBS *cbs, int64_t *out) {
  int is_negative;
  CBS bytes;
  if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) ||
      !CBS_is_valid_asn1_integer(&bytes, &is_negative)) {
    return 0;
  }
  const uint8_t *data = CBS_data(&bytes);
  const size_t len = CBS_len(&bytes);
  if (len > sizeof(int64_t)) {
    return 0;
  }
  uint8_t sign_extend[sizeof(int64_t)];
  OPENSSL_memset(sign_extend, is_negative ? 0xff : 0, sizeof(sign_extend));
  OPENSSL_memcpy(sign_extend + sizeof(int64_t) - len, data, len);
  *out = CRYPTO_load_u64_be(sign_extend);
  return 1;
}

int CBS_get_asn1_bool(CBS *cbs, int *out) {
  CBS bytes;
  if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || CBS_len(&bytes) != 1) {
    return 0;
  }

  const uint8_t value = *CBS_data(&bytes);
  if (value != 0 && value != 0xff) {
    return 0;
  }

  *out = !!value;
  return 1;
}

int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
                          CBS_ASN1_TAG tag) {
  int present = 0;

  if (CBS_peek_asn1_tag(cbs, tag)) {
    if (!CBS_get_asn1(cbs, out, tag)) {
      return 0;
    }
    present = 1;
  }

  if (out_present != NULL) {
    *out_present = present;
  }

  return 1;
}

int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
                                       CBS_ASN1_TAG tag) {
  CBS child;
  int present;
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    return 0;
  }
  if (present) {
    assert(out);
    if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
        CBS_len(&child) != 0) {
      return 0;
    }
  } else {
    CBS_init(out, NULL, 0);
  }
  if (out_present) {
    *out_present = present;
  }
  return 1;
}

int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag,
                                 uint64_t default_value) {
  CBS child;
  int present;
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    return 0;
  }
  if (present) {
    if (!CBS_get_asn1_uint64(&child, out) || CBS_len(&child) != 0) {
      return 0;
    }
  } else {
    *out = default_value;
  }
  return 1;
}

int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag,
                               int default_value) {
  CBS child, child2;
  int present;
  if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
    return 0;
  }
  if (present) {
    uint8_t boolean;

    if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
        CBS_len(&child2) != 1 || CBS_len(&child) != 0) {
      return 0;
    }

    boolean = CBS_data(&child2)[0];
    if (boolean == 0) {
      *out = 0;
    } else if (boolean == 0xff) {
      *out = 1;
    } else {
      return 0;
    }
  } else {
    *out = default_value;
  }
  return 1;
}

int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
  CBS in = *cbs;
  uint8_t num_unused_bits;
  if (!CBS_get_u8(&in, &num_unused_bits) || num_unused_bits > 7) {
    return 0;
  }

  if (num_unused_bits == 0) {
    return 1;
  }

  // All num_unused_bits bits must exist and be zeros.
  uint8_t last;
  if (!CBS_get_last_u8(&in, &last) ||
      (last & ((1 << num_unused_bits) - 1)) != 0) {
    return 0;
  }

  return 1;
}

int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
  if (!CBS_is_valid_asn1_bitstring(cbs)) {
    return 0;
  }

  const unsigned byte_num = (bit >> 3) + 1;
  const unsigned bit_num = 7 - (bit & 7);

  // Unused bits are zero, and this function does not distinguish between
  // missing and unset bits. Thus it is sufficient to do a byte-level length
  // check.
  return byte_num < CBS_len(cbs) &&
         (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
}

int CBS_is_valid_asn1_integer(const CBS *cbs, int *out_is_negative) {
  CBS copy = *cbs;
  uint8_t first_byte, second_byte;
  if (!CBS_get_u8(&copy, &first_byte)) {
    return 0;  // INTEGERs may not be empty.
  }
  if (out_is_negative != NULL) {
    *out_is_negative = (first_byte & 0x80) != 0;
  }
  if (!CBS_get_u8(&copy, &second_byte)) {
    return 1;  // One byte INTEGERs are always minimal.
  }
  if ((first_byte == 0x00 && (second_byte & 0x80) == 0) ||
      (first_byte == 0xff && (second_byte & 0x80) != 0)) {
    return 0;  // The value is minimal iff the first 9 bits are not all equal.
  }
  return 1;
}

int CBS_is_unsigned_asn1_integer(const CBS *cbs) {
  int is_negative;
  return CBS_is_valid_asn1_integer(cbs, &is_negative) && !is_negative;
}

static int add_decimal(CBB *out, uint64_t v) {
  char buf[DECIMAL_SIZE(uint64_t) + 1];
  snprintf(buf, sizeof(buf), "%" PRIu64, v);
  return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf));
}

int CBS_is_valid_asn1_oid(const CBS *cbs) {
  if (CBS_len(cbs) == 0) {
    return 0;  // OID encodings cannot be empty.
  }

  CBS copy = *cbs;
  uint8_t v, prev = 0;
  while (CBS_get_u8(&copy, &v)) {
    // OID encodings are a sequence of minimally-encoded base-128 integers (see
    // |parse_base128_integer|). If |prev|'s MSB was clear, it was the last byte
    // of an integer (or |v| is the first byte). |v| is then the first byte of
    // the next integer. If first byte of an integer is 0x80, it is not
    // minimally-encoded.
    if ((prev & 0x80) == 0 && v == 0x80) {
      return 0;
    }
    prev = v;
  }

  // The last byte should must end an integer encoding.
  return (prev & 0x80) == 0;
}

char *CBS_asn1_oid_to_text(const CBS *cbs) {
  CBS copy = *cbs;
  CBB cbb;
  if (!CBB_init(&cbb, 32)) {
    goto err;
  }

  // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2.
  uint64_t v;
  if (!parse_base128_integer(&copy, &v)) {
    goto err;
  }

  if (v >= 80) {
    if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
        !add_decimal(&cbb, v - 80)) {
      goto err;
    }
  } else if (!add_decimal(&cbb, v / 40) || !CBB_add_u8(&cbb, '.') ||
             !add_decimal(&cbb, v % 40)) {
    goto err;
  }

  while (CBS_len(&copy) != 0) {
    if (!parse_base128_integer(&copy, &v) || !CBB_add_u8(&cbb, '.') ||
        !add_decimal(&cbb, v)) {
      goto err;
    }
  }

  uint8_t *txt;
  size_t txt_len;
  if (!CBB_add_u8(&cbb, '\0') || !CBB_finish(&cbb, &txt, &txt_len)) {
    goto err;
  }

  return (char *)txt;

err:
  CBB_cleanup(&cbb);
  return NULL;
}

static int cbs_get_two_digits(CBS *cbs, int *out) {
  uint8_t first_digit, second_digit;
  if (!CBS_get_u8(cbs, &first_digit)) {
    return 0;
  }
  if (!OPENSSL_isdigit(first_digit)) {
    return 0;
  }
  if (!CBS_get_u8(cbs, &second_digit)) {
    return 0;
  }
  if (!OPENSSL_isdigit(second_digit)) {
    return 0;
  }
  *out = (first_digit - '0') * 10 + (second_digit - '0');
  return 1;
}

static int is_valid_day(int year, int month, int day) {
  if (day < 1) {
    return 0;
  }
  switch (month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
      return day <= 31;
    case 4:
    case 6:
    case 9:
    case 11:
      return day <= 30;
    case 2:
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
        return day <= 29;
      } else {
        return day <= 28;
      }
    default:
      return 0;
  }
}

static int CBS_parse_rfc5280_time_internal(const CBS *cbs, int is_gentime,
                                           int allow_timezone_offset,
                                           struct tm *out_tm) {
  int year, month, day, hour, min, sec, tmp;
  CBS copy = *cbs;
  uint8_t tz;

  if (is_gentime) {
    if (!cbs_get_two_digits(&copy, &tmp)) {
      return 0;
    }
    year = tmp * 100;
    if (!cbs_get_two_digits(&copy, &tmp)) {
      return 0;
    }
    year += tmp;
  } else {
    year = 1900;
    if (!cbs_get_two_digits(&copy, &tmp)) {
      return 0;
    }
    year += tmp;
    if (year < 1950) {
      year += 100;
    }
    if (year >= 2050) {
      return 0;  // A Generalized time must be used.
    }
  }
  if (!cbs_get_two_digits(&copy, &month) || month < 1 ||
      month > 12 ||  // Reject invalid months.
      !cbs_get_two_digits(&copy, &day) ||
      !is_valid_day(year, month, day) ||  // Reject invalid days.
      !cbs_get_two_digits(&copy, &hour) ||
      hour > 23 ||  // Reject invalid hours.
      !cbs_get_two_digits(&copy, &min) ||
      min > 59 ||  // Reject invalid minutes.
      !cbs_get_two_digits(&copy, &sec) || sec > 59 || !CBS_get_u8(&copy, &tz)) {
    return 0;
  }

  int offset_sign = 0;
  switch (tz) {
    case 'Z':
      break;  // We correctly have 'Z' on the end as per spec.
    case '+':
      offset_sign = 1;
      break;  // Should not be allowed per RFC 5280.
    case '-':
      offset_sign = -1;
      break;  // Should not be allowed per RFC 5280.
    default:
      return 0;  // Reject anything else after the time.
  }

  // If allow_timezone_offset is non-zero, allow for a four digit timezone
  // offset to be specified even though this is not allowed by RFC 5280. We are
  // permissive of this for UTCTimes due to the unfortunate existence of
  // artisinally rolled long lived certificates that were baked into places that
  // are now difficult to change. These certificates were generated with the
  // 'openssl' command that permissively allowed the creation of certificates
  // with notBefore and notAfter times specified as strings for direct
  // certificate inclusion on the command line. For context see cl/237068815.
  //
  // TODO(bbe): This has been expunged from public web-pki as the ecosystem has
  // managed to encourage CA compliance with standards. We should find a way to
  // get rid of this or make it off by default.
  int offset_seconds = 0;
  if (offset_sign != 0) {
    if (!allow_timezone_offset) {
      return 0;
    }
    int offset_hours, offset_minutes;
    if (!cbs_get_two_digits(&copy, &offset_hours) ||
        offset_hours > 23 ||  // Reject invalid hours.
        !cbs_get_two_digits(&copy, &offset_minutes) ||
        offset_minutes > 59) {  // Reject invalid minutes.
      return 0;
    }
    offset_seconds = offset_sign * (offset_hours * 3600 + offset_minutes * 60);
  }

  if (CBS_len(&copy) != 0) {
    return 0;  // Reject invalid lengths.
  }

  if (out_tm != NULL) {
    // Fill in the tm fields corresponding to what we validated.
    out_tm->tm_year = year - 1900;
    out_tm->tm_mon = month - 1;
    out_tm->tm_mday = day;
    out_tm->tm_hour = hour;
    out_tm->tm_min = min;
    out_tm->tm_sec = sec;
    if (offset_seconds && !OPENSSL_gmtime_adj(out_tm, 0, offset_seconds)) {
      return 0;
    }
  }
  return 1;
}

int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm,
                               int allow_timezone_offset) {
  return CBS_parse_rfc5280_time_internal(cbs, 1, allow_timezone_offset, out_tm);
}

int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm,
                       int allow_timezone_offset) {
  return CBS_parse_rfc5280_time_internal(cbs, 0, allow_timezone_offset, out_tm);
}
