/* 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(ASN1_INTEGER *a, long 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(ASN1_ENUMERATED *a, long 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;
}

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);
}
