/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/asn1.h>

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

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

#include "../internal.h"


ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) {
  return ASN1_STRING_dup(x);
}

int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) {
  // Compare signs.
  int neg = x->type & V_ASN1_NEG;
  if (neg != (y->type & V_ASN1_NEG)) {
    return neg ? -1 : 1;
  }

  int ret = ASN1_STRING_cmp(x, y);
  if (neg) {
    // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from
    // returning |INT_MIN|.
    if (ret < 0) {
      return 1;
    } else if (ret > 0) {
      return -1;
    } else {
      return 0;
    }
  }

  return ret;
}

// negate_twos_complement negates |len| bytes from |buf| in-place, interpreted
// as a signed, big-endian two's complement value.
static void negate_twos_complement(uint8_t *buf, size_t len) {
  uint8_t borrow = 0;
  for (size_t i = len - 1; i < len; i--) {
    uint8_t t = buf[i];
    buf[i] = 0u - borrow - t;
    borrow |= t != 0;
  }
}

static int is_all_zeros(const uint8_t *in, size_t len) {
  for (size_t i = 0; i < len; i++) {
    if (in[i] != 0) {
      return 0;
    }
  }
  return 1;
}

int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) {
  if (in == NULL) {
    return 0;
  }

  // |ASN1_INTEGER|s should be represented minimally, but it is possible to
  // construct invalid ones. Skip leading zeros so this does not produce an
  // invalid encoding or break invariants.
  int start = 0;
  while (start < in->length && in->data[start] == 0) {
    start++;
  }

  int is_negative = (in->type & V_ASN1_NEG) != 0;
  int pad;
  if (start >= in->length) {
    // Zero is represented as a single byte.
    is_negative = 0;
    pad = 1;
  } else if (is_negative) {
    // 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff
    // through 0x00...01 and need an extra byte to be negative.
    // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff
    // through 0x80...00 and can be negated as-is.
    pad = in->data[start] > 0x80 ||
          (in->data[start] == 0x80 &&
           !is_all_zeros(in->data + start + 1, in->length - start - 1));
  } else {
    // If the high bit is set, the signed representation needs an extra
    // byte to be positive.
    pad = (in->data[start] & 0x80) != 0;
  }

  if (in->length - start > INT_MAX - pad) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
    return 0;
  }
  int len = pad + in->length - start;
  assert(len > 0);
  if (outp == NULL) {
    return len;
  }

  if (pad) {
    (*outp)[0] = 0;
  }
  OPENSSL_memcpy(*outp + pad, in->data + start, in->length - start);
  if (is_negative) {
    negate_twos_complement(*outp, len);
    assert((*outp)[0] >= 0x80);
  } else {
    assert((*outp)[0] < 0x80);
  }
  *outp += len;
  return len;
}

ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp,
                               long len) {
  // This function can handle lengths up to INT_MAX - 1, but the rest of the
  // legacy ASN.1 code mixes integer types, so avoid exposing it to
  // ASN1_INTEGERS with larger lengths.
  if (len < 0 || len > INT_MAX / 2) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
    return NULL;
  }

  CBS cbs;
  CBS_init(&cbs, *inp, (size_t)len);
  int is_negative;
  if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
    return NULL;
  }

  ASN1_INTEGER *ret = NULL;
  if (out == NULL || *out == NULL) {
    ret = ASN1_INTEGER_new();
    if (ret == NULL) {
      return NULL;
    }
  } else {
    ret = *out;
  }

  // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First,
  // determine the size needed for a minimal result.
  if (is_negative) {
    // 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff
    // through 0x000100...001 and need one leading zero removed. 0x8000...00
    // through 0xff00...00 have a two's complement of 0x8000...00 through
    // 0x0100...00 and will be minimally-encoded as-is.
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff &&
        !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) {
      CBS_skip(&cbs, 1);
    }
  } else {
    // Remove the leading zero byte, if any.
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) {
      CBS_skip(&cbs, 1);
    }
  }

  if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) {
    goto err;
  }

  if (is_negative) {
    ret->type = V_ASN1_NEG_INTEGER;
    negate_twos_complement(ret->data, ret->length);
  } else {
    ret->type = V_ASN1_INTEGER;
  }

  // The value should be minimally-encoded.
  assert(ret->length == 0 || ret->data[0] != 0);
  // Zero is not negative.
  assert(!is_negative || ret->length > 0);

  *inp += len;
  if (out != NULL) {
    *out = ret;
  }
  return ret;

err:
  if (ret != NULL && (out == NULL || *out != ret)) {
    ASN1_INTEGER_free(ret);
  }
  return NULL;
}

int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) {
  if (v >= 0) {
    return ASN1_INTEGER_set_uint64(a, (uint64_t)v);
  }

  if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) {
    return 0;
  }

  a->type = V_ASN1_NEG_INTEGER;
  return 1;
}

int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) {
  if (v >= 0) {
    return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v);
  }

  if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) {
    return 0;
  }

  a->type = V_ASN1_NEG_ENUMERATED;
  return 1;
}

int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) {
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
  return ASN1_INTEGER_set_int64(a, v);
}

int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) {
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
  return ASN1_ENUMERATED_set_int64(a, v);
}

static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) {
  uint8_t buf[sizeof(uint64_t)];
  CRYPTO_store_u64_be(buf, v);
  size_t leading_zeros;
  for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) {
    if (buf[leading_zeros] != 0) {
      break;
    }
  }

  if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) {
    return 0;
  }
  out->type = type;
  return 1;
}

int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) {
  return asn1_string_set_uint64(out, v, V_ASN1_INTEGER);
}

int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) {
  return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED);
}

static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a,
                                      int type) {
  if ((a->type & ~V_ASN1_NEG) != type) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
    return 0;
  }
  uint8_t buf[sizeof(uint64_t)] = {0};
  if (a->length > (int)sizeof(buf)) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
    return 0;
  }
  OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length);
  *out = CRYPTO_load_u64_be(buf);
  return 1;
}

static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a,
                                  int type) {
  if (!asn1_string_get_abs_uint64(out, a, type)) {
    return 0;
  }
  if (a->type & V_ASN1_NEG) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
    return 0;
  }
  return 1;
}

int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) {
  return asn1_string_get_uint64(out, a, V_ASN1_INTEGER);
}

int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) {
  return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED);
}

static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) {
  uint64_t v;
  if (!asn1_string_get_abs_uint64(&v, a, type)) {
    return 0;
  }
  int64_t i64;
  int fits_in_i64;
  // Check |v != 0| to handle manually-constructed negative zeros.
  if ((a->type & V_ASN1_NEG) && v != 0) {
    i64 = (int64_t)(0u - v);
    fits_in_i64 = i64 < 0;
  } else {
    i64 = (int64_t)v;
    fits_in_i64 = i64 >= 0;
  }
  if (!fits_in_i64) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
    return 0;
  }
  *out = i64;
  return 1;
}

int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) {
  return asn1_string_get_int64(out, a, V_ASN1_INTEGER);
}

int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) {
  return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED);
}

static long asn1_string_get_long(const ASN1_STRING *a, int type) {
  if (a == NULL) {
    return 0;
  }

  int64_t v;
  if (!asn1_string_get_int64(&v, a, type) ||  //
      v < LONG_MIN || v > LONG_MAX) {
    // This function's return value does not distinguish overflow from -1.
    ERR_clear_error();
    return -1;
  }

  return (long)v;
}

long ASN1_INTEGER_get(const ASN1_INTEGER *a) {
  return asn1_string_get_long(a, V_ASN1_INTEGER);
}

long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) {
  return asn1_string_get_long(a, V_ASN1_ENUMERATED);
}

static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
                                      int type) {
  ASN1_INTEGER *ret;
  if (ai == NULL) {
    ret = ASN1_STRING_type_new(type);
  } else {
    ret = ai;
  }
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
    goto err;
  }

  if (BN_is_negative(bn) && !BN_is_zero(bn)) {
    ret->type = type | V_ASN1_NEG;
  } else {
    ret->type = type;
  }

  int len = BN_num_bytes(bn);
  if (!ASN1_STRING_set(ret, NULL, len) ||
      !BN_bn2bin_padded(ret->data, len, bn)) {
    goto err;
  }
  return ret;

err:
  if (ret != ai) {
    ASN1_STRING_free(ret);
  }
  return NULL;
}

ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) {
  return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
}

ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) {
  return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
}

static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) {
  if ((ai->type & ~V_ASN1_NEG) != type) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
    return NULL;
  }

  BIGNUM *ret;
  if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
  } else if (ai->type & V_ASN1_NEG) {
    BN_set_negative(ret, 1);
  }
  return ret;
}

BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) {
  return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
}

BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) {
  return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
}
