// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/bytestring.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#include <algorithm>

#include <openssl/err.h>
#include <openssl/mem.h>

#include "../internal.h"
#include "../mem_internal.h"
#include "internal.h"


using namespace bssl;

void CBB_zero(CBB *cbb) { OPENSSL_memset(cbb, 0, sizeof(CBB)); }

static void cbb_init(CBB *cbb, uint8_t *buf, size_t cap, int can_resize) {
  cbb->is_child = 0;
  cbb->child = nullptr;
  cbb->u.base.buf = buf;
  cbb->u.base.len = 0;
  cbb->u.base.cap = cap;
  cbb->u.base.can_resize = can_resize;
  cbb->u.base.error = 0;
}

int CBB_init(CBB *cbb, size_t initial_capacity) {
  CBB_zero(cbb);

  uint8_t *buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(initial_capacity));
  if (initial_capacity > 0 && buf == nullptr) {
    return 0;
  }

  cbb_init(cbb, buf, initial_capacity, /*can_resize=*/1);
  return 1;
}

int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
  CBB_zero(cbb);
  cbb_init(cbb, buf, len, /*can_resize=*/0);
  return 1;
}

void CBB_cleanup(CBB *cbb) {
  // Child `CBB`s are non-owning. They are implicitly discarded and should not
  // be used with `CBB_cleanup` or `ScopedCBB`.
  assert(!cbb->is_child);
  if (cbb->is_child) {
    return;
  }

  if (cbb->u.base.can_resize) {
    OPENSSL_free(cbb->u.base.buf);
    cbb->u.base.buf = nullptr;
  }
}

static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
                              size_t len) {
  if (base == nullptr) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  size_t newlen = base->len + len;
  if (newlen < base->len) {
    // Overflow
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
    goto err;
  }

  if (newlen > base->cap) {
    if (!base->can_resize) {
      OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
      goto err;
    }

    size_t newcap = base->cap * 2;
    if (newcap < base->cap || newcap < newlen) {
      newcap = newlen;
    }
    uint8_t *newbuf =
        reinterpret_cast<uint8_t *>(OPENSSL_realloc(base->buf, newcap));
    if (newbuf == nullptr) {
      goto err;
    }

    base->buf = newbuf;
    base->cap = newcap;
  }

  if (out) {
    *out = base->buf + base->len;
  }

  return 1;

err:
  base->error = 1;
  return 0;
}

static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
                          size_t len) {
  if (!cbb_buffer_reserve(base, out, len)) {
    return 0;
  }
  // This will not overflow or `cbb_buffer_reserve` would have failed.
  base->len += len;
  return 1;
}

int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
  if (cbb->is_child) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (!CBB_flush(cbb)) {
    return 0;
  }

  if (cbb->u.base.can_resize && (out_data == nullptr || out_len == nullptr)) {
    // `out_data` and `out_len` can only be NULL if the CBB is fixed.
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (out_data != nullptr) {
    *out_data = cbb->u.base.buf;
  }
  if (out_len != nullptr) {
    *out_len = cbb->u.base.len;
  }
  cbb->u.base.buf = nullptr;
  CBB_cleanup(cbb);
  return 1;
}

static struct cbb_buffer_st *cbb_get_base(CBB *cbb) {
  if (cbb->is_child) {
    return cbb->u.child.base;
  }
  return &cbb->u.base;
}

static void cbb_on_error(CBB *cbb) {
  // Due to C's lack of destructors and `CBB`'s auto-flushing API, a failing
  // `CBB`-taking function may leave a dangling pointer to a child `CBB`. As a
  // result, the convention is callers may not write to `CBB`s that have failed.
  // But, as a safety measure, we lock the `CBB` into an error state. Once the
  // error bit is set, `cbb->child` will not be read.
  //
  // TODO(davidben): This still isn't quite ideal. A `CBB` function *outside*
  // this file may originate an error while the `CBB` points to a local child.
  // In that case we don't set the error bit and are reliant on the error
  // convention. Perhaps we allow `CBB_cleanup` on child `CBB`s and make every
  // child's `CBB_cleanup` set the error bit if unflushed. That will be
  // convenient for C++ callers, but very tedious for C callers. So C callers
  // perhaps should get a `CBB_on_error` function that can be, less tediously,
  // stuck in a `goto err` block.
  cbb_get_base(cbb)->error = 1;

  // Clearing the pointer is not strictly necessary, but GCC's dangling pointer
  // warning does not know `cbb->child` will not be read once `error` is set
  // above.
  cbb->child = nullptr;
}

// CBB_flush recurses and then writes out any pending length prefix. The
// current length of the underlying base is taken to be the length of the
// length-prefixed data.
int CBB_flush(CBB *cbb) {
  // If `base` has hit an error, the buffer is in an undefined state, so
  // fail all following calls. In particular, `cbb->child` may point to invalid
  // memory.
  struct cbb_buffer_st *base = cbb_get_base(cbb);
  if (base == nullptr || base->error) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (cbb->child == nullptr) {
    // Nothing to flush.
    return 1;
  }

  assert(cbb->child->is_child);
  struct cbb_child_st *child = &cbb->child->u.child;
  assert(child->base == base);
  size_t child_start = child->offset + child->pending_len_len;

  size_t len;
  if (!CBB_flush(cbb->child)) {
    goto err;
  }
  if (child_start < child->offset || base->len < child_start) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  len = base->len - child_start;

  if (child->pending_is_asn1) {
    // For ASN.1 we assume that we'll only need a single byte for the length.
    // If that turned out to be incorrect, we have to move the contents along
    // in order to make space.
    uint8_t len_len;
    uint8_t initial_length_byte;

    assert(child->pending_len_len == 1);

    if (len > 0xfffffffe) {
      OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
      // Too large.
      goto err;
    } else if (len > 0xffffff) {
      len_len = 5;
      initial_length_byte = 0x80 | 4;
    } else if (len > 0xffff) {
      len_len = 4;
      initial_length_byte = 0x80 | 3;
    } else if (len > 0xff) {
      len_len = 3;
      initial_length_byte = 0x80 | 2;
    } else if (len > 0x7f) {
      len_len = 2;
      initial_length_byte = 0x80 | 1;
    } else {
      len_len = 1;
      initial_length_byte = (uint8_t)len;
      len = 0;
    }

    if (len_len != 1) {
      // We need to move the contents along in order to make space.
      size_t extra_bytes = len_len - 1;
      if (!cbb_buffer_add(base, nullptr, extra_bytes)) {
        goto err;
      }
      OPENSSL_memmove(base->buf + child_start + extra_bytes,
                      base->buf + child_start, len);
    }
    base->buf[child->offset++] = initial_length_byte;
    child->pending_len_len = len_len - 1;
  }

  for (size_t i = child->pending_len_len - 1; i < child->pending_len_len; i--) {
    base->buf[child->offset + i] = (uint8_t)len;
    len >>= 8;
  }
  if (len != 0) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
    goto err;
  }

  child->base = nullptr;
  cbb->child = nullptr;

  return 1;

err:
  cbb_on_error(cbb);
  return 0;
}

uint8_t *CBB_data(const CBB *cbb) {
  assert(cbb->child == nullptr);
  if (cbb->is_child) {
    return cbb->u.child.base->buf + cbb->u.child.offset +
           cbb->u.child.pending_len_len;
  }
  return cbb->u.base.buf;
}

size_t CBB_len(const CBB *cbb) {
  assert(cbb->child == nullptr);
  if (cbb->is_child) {
    assert(cbb->u.child.offset + cbb->u.child.pending_len_len <=
           cbb->u.child.base->len);
    return cbb->u.child.base->len - cbb->u.child.offset -
           cbb->u.child.pending_len_len;
  }
  return cbb->u.base.len;
}

static int cbb_add_child(CBB *cbb, CBB *out_child, uint8_t len_len,
                         int is_asn1) {
  assert(cbb->child == nullptr);
  assert(!is_asn1 || len_len == 1);
  struct cbb_buffer_st *base = cbb_get_base(cbb);
  size_t offset = base->len;

  // Reserve space for the length prefix.
  uint8_t *prefix_bytes;
  if (!cbb_buffer_add(base, &prefix_bytes, len_len)) {
    return 0;
  }
  OPENSSL_memset(prefix_bytes, 0, len_len);

  CBB_zero(out_child);
  out_child->is_child = 1;
  out_child->u.child.base = base;
  out_child->u.child.offset = offset;
  out_child->u.child.pending_len_len = len_len;
  out_child->u.child.pending_is_asn1 = is_asn1;
  cbb->child = out_child;
  return 1;
}

static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
                                   uint8_t len_len) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  return cbb_add_child(cbb, out_contents, len_len, /*is_asn1=*/0);
}

int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) {
  return cbb_add_length_prefixed(cbb, out_contents, 1);
}

int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) {
  return cbb_add_length_prefixed(cbb, out_contents, 2);
}

int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
  return cbb_add_length_prefixed(cbb, out_contents, 3);
}

// add_base128_integer encodes `v` as a big-endian base-128 integer where the
// high bit of each byte indicates where there is more data. This is the
// encoding used in DER for both high tag number form and OID components.
static int add_base128_integer(CBB *cbb, uint64_t v) {
  unsigned len_len = 0;
  uint64_t copy = v;
  while (copy > 0) {
    len_len++;
    copy >>= 7;
  }
  if (len_len == 0) {
    len_len = 1;  // Zero is encoded with one byte.
  }
  for (unsigned i = len_len - 1; i < len_len; i--) {
    uint8_t byte = (v >> (7 * i)) & 0x7f;
    if (i != 0) {
      // The high bit denotes whether there is more data.
      byte |= 0x80;
    }
    if (!CBB_add_u8(cbb, byte)) {
      return 0;
    }
  }
  return 1;
}

int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  // Split the tag into leading bits and tag number.
  uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0;
  CBS_ASN1_TAG tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK;
  if (tag_number >= 0x1f) {
    // Set all the bits in the tag number to signal high tag number form.
    if (!CBB_add_u8(cbb, tag_bits | 0x1f) ||
        !add_base128_integer(cbb, tag_number)) {
      return 0;
    }
  } else if (!CBB_add_u8(cbb, tag_bits | tag_number)) {
    return 0;
  }

  // Reserve one byte of length prefix. `CBB_flush` will finish it later.
  return cbb_add_child(cbb, out_contents, /*len_len=*/1, /*is_asn1=*/1);
}

int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
  uint8_t *out;
  if (!CBB_add_space(cbb, &out, len)) {
    return 0;
  }
  OPENSSL_memcpy(out, data, len);
  return 1;
}

int CBB_add_zeros(CBB *cbb, size_t len) {
  uint8_t *out;
  if (!CBB_add_space(cbb, &out, len)) {
    return 0;
  }
  OPENSSL_memset(out, 0, len);
  return 1;
}

int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
  if (!CBB_flush(cbb) || !cbb_buffer_add(cbb_get_base(cbb), out_data, len)) {
    return 0;
  }
  return 1;
}

int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) {
  if (!CBB_flush(cbb) ||
      !cbb_buffer_reserve(cbb_get_base(cbb), out_data, len)) {
    return 0;
  }
  return 1;
}

int CBB_did_write(CBB *cbb, size_t len) {
  struct cbb_buffer_st *base = cbb_get_base(cbb);
  size_t newlen = base->len + len;
  if (cbb->child != nullptr || newlen < base->len || newlen > base->cap) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }
  base->len = newlen;
  return 1;
}

static int cbb_add_u(CBB *cbb, uint64_t v, size_t len_len) {
  uint8_t *buf;
  if (!CBB_add_space(cbb, &buf, len_len)) {
    return 0;
  }

  for (size_t i = len_len - 1; i < len_len; i--) {
    buf[i] = v;
    v >>= 8;
  }

  // `v` must fit in `len_len` bytes.
  if (v != 0) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
    cbb_on_error(cbb);
    return 0;
  }

  return 1;
}

int CBB_add_u8(CBB *cbb, uint8_t value) { return cbb_add_u(cbb, value, 1); }

int CBB_add_u16(CBB *cbb, uint16_t value) { return cbb_add_u(cbb, value, 2); }

int CBB_add_u16le(CBB *cbb, uint16_t value) {
  return CBB_add_u16(cbb, CRYPTO_bswap2(value));
}

int CBB_add_u24(CBB *cbb, uint32_t value) { return cbb_add_u(cbb, value, 3); }

int CBB_add_u32(CBB *cbb, uint32_t value) { return cbb_add_u(cbb, value, 4); }

int CBB_add_u32le(CBB *cbb, uint32_t value) {
  return CBB_add_u32(cbb, CRYPTO_bswap4(value));
}

int CBB_add_u48(CBB *cbb, uint64_t value) { return cbb_add_u(cbb, value, 6); }

int CBB_add_u64(CBB *cbb, uint64_t value) { return cbb_add_u(cbb, value, 8); }

int CBB_add_u64le(CBB *cbb, uint64_t value) {
  return CBB_add_u64(cbb, CRYPTO_bswap8(value));
}

void CBB_discard(CBB *cbb, size_t len) {
  BSSL_CHECK(cbb->child == nullptr);
  BSSL_CHECK(len <= CBB_len(cbb));
  struct cbb_buffer_st *base = cbb_get_base(cbb);
  base->len -= len;
}

void CBB_discard_child(CBB *cbb) {
  if (cbb->child == nullptr) {
    return;
  }

  struct cbb_buffer_st *base = cbb_get_base(cbb);
  assert(cbb->child->is_child);
  base->len = cbb->child->u.child.offset;

  cbb->child->u.child.base = nullptr;
  cbb->child = nullptr;
}

int CBB_add_asn1_element(CBB *cbb, CBS_ASN1_TAG tag, const uint8_t *data,
                         size_t data_len) {
  CBB child;
  if (!CBB_add_asn1(cbb, &child, tag) ||
      !CBB_add_bytes(&child, data, data_len) ||  //
      !CBB_flush(cbb)) {
    cbb_on_error(cbb);
    return 0;
  }

  return 1;
}

int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
  return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER);
}

int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, CBS_ASN1_TAG tag) {
  CBB child;
  int started = 0;
  if (!CBB_add_asn1(cbb, &child, tag)) {
    goto err;
  }

  for (size_t i = 0; i < 8; i++) {
    uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
    if (!started) {
      if (byte == 0) {
        // Don't encode leading zeros.
        continue;
      }
      // If the high bit is set, add a padding byte to make it
      // unsigned.
      if ((byte & 0x80) && !CBB_add_u8(&child, 0)) {
        goto err;
      }
      started = 1;
    }
    if (!CBB_add_u8(&child, byte)) {
      goto err;
    }
  }

  // 0 is encoded as a single 0, not the empty string.
  if (!started && !CBB_add_u8(&child, 0)) {
    goto err;
  }

  return CBB_flush(cbb);

err:
  cbb_on_error(cbb);
  return 0;
}

int CBB_add_asn1_int64(CBB *cbb, int64_t value) {
  return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER);
}

int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, CBS_ASN1_TAG tag) {
  if (value >= 0) {
    return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag);
  }

  uint8_t bytes[sizeof(int64_t)];
  memcpy(bytes, &value, sizeof(value));
  int start = 7;
  // Skip leading sign-extension bytes unless they are necessary.
  while (start > 0 && (bytes[start] == 0xff && (bytes[start - 1] & 0x80))) {
    start--;
  }

  CBB child;
  if (!CBB_add_asn1(cbb, &child, tag)) {
    goto err;
  }
  for (int i = start; i >= 0; i--) {
    if (!CBB_add_u8(&child, bytes[i])) {
      goto err;
    }
  }
  return CBB_flush(cbb);

err:
  cbb_on_error(cbb);
  return 0;
}

int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) {
  return CBB_add_asn1_element(cbb, CBS_ASN1_OCTETSTRING, data, data_len);
}

int CBB_add_asn1_bool(CBB *cbb, int value) {
  CBB child;
  if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) ||
      !CBB_add_u8(&child, value != 0 ? 0xff : 0) || !CBB_flush(cbb)) {
    cbb_on_error(cbb);
    return 0;
  }

  return 1;
}

// parse_dotted_decimal parses one decimal component from `cbs`, where `cbs` is
// an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the
// component and the dot, so `cbs` may be passed into the function again for the
// next value.
static int parse_dotted_decimal(CBS *cbs, uint64_t *out) {
  if (!CBS_get_u64_decimal(cbs, out)) {
    return 0;
  }

  // The integer must have either ended at the end of the string, or a
  // non-terminal dot, which should be consumed. If the string ends with a dot,
  // this is not a valid OID string.
  uint8_t dot;
  return !CBS_get_u8(cbs, &dot) || (dot == '.' && CBS_len(cbs) > 0);
}

int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  CBS cbs;
  CBS_init(&cbs, (const uint8_t *)text, len);

  // OIDs must have at least two components.
  uint64_t a, b;
  if (!parse_dotted_decimal(&cbs, &a) || !parse_dotted_decimal(&cbs, &b)) {
    return 0;
  }

  // The first component is encoded as 40 * `a` + `b`. This assumes that `a` is
  // 0, 1, or 2 and that, when it is 0 or 1, `b` is at most 39.
  if (a > 2 || (a < 2 && b > 39) || b > UINT64_MAX - 80 ||
      !add_base128_integer(cbb, 40u * a + b)) {
    return 0;
  }

  // The remaining components are encoded unmodified.
  while (CBS_len(&cbs) > 0) {
    if (!parse_dotted_decimal(&cbs, &a) || !add_base128_integer(cbb, a)) {
      return 0;
    }
  }

  return 1;
}

int CBB_add_asn1_relative_oid_from_text(CBB *cbb, const char *text,
                                        size_t len) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  // Relative OIDs must have at least one component.
  if (!len) {
    return 0;
  }

  CBS cbs;
  CBS_init(&cbs, reinterpret_cast<const uint8_t *>(text), len);

  while (CBS_len(&cbs) > 0) {
    uint64_t a;
    if (!parse_dotted_decimal(&cbs, &a) || !add_base128_integer(cbb, a)) {
      return 0;
    }
  }

  return 1;
}

int CBB_add_asn1_oid_component(CBB *cbb, uint64_t value) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  return add_base128_integer(cbb, value);
}

int CBB_flush_asn1_set_of(CBB *cbb) {
  if (!CBB_flush(cbb)) {
    return 0;
  }

  size_t num_children = 0;
  CBS cbs(CBBAsSpan(cbb));
  while (CBS_len(&cbs) != 0) {
    if (!CBS_get_any_asn1_element(&cbs, nullptr, nullptr, nullptr)) {
      OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
      return 0;
    }
    num_children++;
  }

  if (num_children < 2) {
    return 1;  // Nothing to do. This is the common case for X.509.
  }

  // Parse out the children and sort. We alias them into a copy of so they
  // remain valid as we rewrite `cbb`.
  Array<uint8_t> copy;
  Array<CBS> children;
  if (!copy.CopyFrom(CBBAsSpan(cbb)) ||  //
      !children.Init(num_children)) {
    return 0;
  }
  cbs = CBS(copy);
  for (size_t i = 0; i < num_children; i++) {
    if (!CBS_get_any_asn1_element(&cbs, &children[i], nullptr, nullptr)) {
      OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
      return 0;
    }
  }
  std::sort(children.begin(), children.end(), [](CBS a, CBS b) -> bool {
    // See X.690, section 11.6 for the ordering. They are sorted in ascending
    // order by their DER encoding. First compare the common prefix.
    size_t a_len = CBS_len(&a), b_len = CBS_len(&b);
    int cmp =
        OPENSSL_memcmp(CBS_data(&a), CBS_data(&b), std::min(a_len, b_len));
    if (cmp != 0) {
      return cmp < 0;
    }
    // If one is a prefix of the other, the shorter one sorts first. (They're
    // actually always equal length. DER encodings are prefix-free.)
    return a_len < b_len;
  });

  // Write the contents back in the new order.
  uint8_t *out = const_cast<uint8_t *>(CBB_data(cbb));
  size_t offset = 0;
  for (size_t i = 0; i < num_children; i++) {
    OPENSSL_memcpy(out + offset, CBS_data(&children[i]), CBS_len(&children[i]));
    offset += CBS_len(&children[i]);
  }
  assert(offset == copy.size());
  return 1;
}

bool bssl::CBBFinishArray(CBB *cbb, Array<uint8_t> *out) {
  uint8_t *ptr;
  size_t len;
  if (!CBB_finish(cbb, &ptr, &len)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }
  out->Reset(ptr, len);
  return true;
}
