/* Written by Nils Larsch for the OpenSSL project. */
/* ====================================================================
 * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
 *
 * 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 above 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 acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED 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 OpenSSL PROJECT OR
 * ITS 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.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

#include <openssl/ec.h>

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

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

#include "internal.h"
#include "../bytestring/internal.h"


static const uint8_t kParametersTag =
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
static const uint8_t kPublicKeyTag =
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;

EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
  CBS ec_private_key, private_key;
  uint64_t version;
  if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1_uint64(&ec_private_key, &version) ||
      version != 1 ||
      !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    return NULL;
  }

  /* Parse the optional parameters field. */
  EC_GROUP *inner_group = NULL;
  EC_KEY *ret = NULL;
  if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) {
    /* Per SEC 1, as an alternative to omitting it, one is allowed to specify
     * this field and put in a NULL to mean inheriting this value. This was
     * omitted in a previous version of this logic without problems, so leave it
     * unimplemented. */
    CBS child;
    if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) {
      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
      goto err;
    }
    inner_group = EC_KEY_parse_parameters(&child);
    if (inner_group == NULL) {
      goto err;
    }
    if (group == NULL) {
      group = inner_group;
    } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) {
      /* If a group was supplied externally, it must match. */
      OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
      goto err;
    }
    if (CBS_len(&child) != 0) {
      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
      goto err;
    }
  }

  if (group == NULL) {
    OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
    goto err;
  }

  ret = EC_KEY_new();
  if (ret == NULL || !EC_KEY_set_group(ret, group)) {
    goto err;
  }

  /* Although RFC 5915 specifies the length of the key, OpenSSL historically
   * got this wrong, so accept any length. See upstream's
   * 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. */
  ret->priv_key =
      BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL);
  ret->pub_key = EC_POINT_new(group);
  if (ret->priv_key == NULL || ret->pub_key == NULL) {
    goto err;
  }

  if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(group)) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
    goto err;
  }

  if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) {
    CBS child, public_key;
    uint8_t padding;
    if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) ||
        !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
        /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
         * encoded as a BIT STRING with bits ordered as in the DER encoding. */
        !CBS_get_u8(&public_key, &padding) ||
        padding != 0 ||
        /* Explicitly check |public_key| is non-empty to save the conversion
         * form later. */
        CBS_len(&public_key) == 0 ||
        !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key),
                            CBS_len(&public_key), NULL) ||
        CBS_len(&child) != 0) {
      OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
      goto err;
    }

    /* Save the point conversion form.
     * TODO(davidben): Consider removing this. */
    ret->conv_form = (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01);
  } else {
    /* Compute the public key instead. */
    if (!EC_POINT_mul(group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
      goto err;
    }
    /* Remember the original private-key-only encoding.
     * TODO(davidben): Consider removing this. */
    ret->enc_flag |= EC_PKEY_NO_PUBKEY;
  }

  if (CBS_len(&ec_private_key) != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    goto err;
  }

  /* Ensure the resulting key is valid. */
  if (!EC_KEY_check_key(ret)) {
    goto err;
  }

  EC_GROUP_free(inner_group);
  return ret;

err:
  EC_KEY_free(ret);
  EC_GROUP_free(inner_group);
  return NULL;
}

int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
                               unsigned enc_flags) {
  if (key == NULL || key->group == NULL || key->priv_key == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  CBB ec_private_key, private_key;
  if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) ||
      !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) ||
      !BN_bn2cbb_padded(&private_key,
                        BN_num_bytes(EC_GROUP_get0_order(key->group)),
                        key->priv_key)) {
    OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
    return 0;
  }

  if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) {
    CBB child;
    if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) ||
        !EC_KEY_marshal_curve_name(&child, key->group) ||
        !CBB_flush(&ec_private_key)) {
      OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
      return 0;
    }
  }

  /* TODO(fork): replace this flexibility with sensible default? */
  if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
    CBB child, public_key;
    if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) ||
        !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
        /* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
         * encoded as a BIT STRING with bits ordered as in the DER encoding. */
        !CBB_add_u8(&public_key, 0 /* padding */) ||
        !EC_POINT_point2cbb(&public_key, key->group, key->pub_key,
                            key->conv_form, NULL) ||
        !CBB_flush(&ec_private_key)) {
      OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
      return 0;
    }
  }

  if (!CBB_flush(cbb)) {
    OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
    return 0;
  }

  return 1;
}

/* is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and
 * zero otherwise. */
static int is_unsigned_integer(const CBS *cbs) {
  if (CBS_len(cbs) == 0) {
    return 0;
  }
  uint8_t byte = CBS_data(cbs)[0];
  if ((byte & 0x80) ||
      (byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) {
    /* Negative or not minimally-encoded. */
    return 0;
  }
  return 1;
}

/* kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. */
static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01};

static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
                                      CBS *out_b, CBS *out_base_x,
                                      CBS *out_base_y, CBS *out_order) {
  /* See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an
   * ECParameters while RFC 5480 calls it a SpecifiedECDomain. */
  CBS params, field_id, field_type, curve, base;
  uint64_t version;
  if (!CBS_get_asn1(in, &params, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1_uint64(&params, &version) ||
      version != 1 ||
      !CBS_get_asn1(&params, &field_id, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
      CBS_len(&field_type) != sizeof(kPrimeField) ||
      memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 ||
      !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) ||
      !is_unsigned_integer(out_prime) ||
      CBS_len(&field_id) != 0 ||
      !CBS_get_asn1(&params, &curve, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) ||
      !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) ||
      /* |curve| has an optional BIT STRING seed which we ignore. */
      !CBS_get_asn1(&params, &base, CBS_ASN1_OCTETSTRING) ||
      !CBS_get_asn1(&params, out_order, CBS_ASN1_INTEGER) ||
      !is_unsigned_integer(out_order)) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    return 0;
  }

  /* |params| has an optional cofactor which we ignore. With the optional seed
   * in |curve|, a group already has arbitrarily many encodings. Parse enough to
   * uniquely determine the curve. */

  /* Require that the base point use uncompressed form. */
  uint8_t form;
  if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
    return 0;
  }

  if (CBS_len(&base) % 2 != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    return 0;
  }
  size_t field_len = CBS_len(&base) / 2;
  CBS_init(out_base_x, CBS_data(&base), field_len);
  CBS_init(out_base_y, CBS_data(&base) + field_len, field_len);

  return 1;
}

/* integers_equal returns one if |a| and |b| are equal, up to leading zeros, and
 * zero otherwise. */
static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) {
  /* Remove leading zeros from |a| and |b|. */
  CBS a_copy = *a;
  while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) {
    CBS_skip(&a_copy, 1);
  }
  while (b_len > 0 && b[0] == 0) {
    b++;
    b_len--;
  }
  return CBS_mem_equal(&a_copy, b, b_len);
}

EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) {
  CBS named_curve;
  if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    return NULL;
  }

  /* Look for a matching curve. */
  unsigned i;
  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
    if (CBS_len(&named_curve) == curve->oid_len &&
        memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == 0) {
      return EC_GROUP_new_by_curve_name(curve->nid);
    }
  }

  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
  return NULL;
}

int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) {
  int nid = EC_GROUP_get_curve_name(group);
  if (nid == NID_undef) {
    OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
    return 0;
  }

  unsigned i;
  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
    if (curve->nid == nid) {
      CBB child;
      return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) &&
             CBB_add_bytes(&child, curve->oid, curve->oid_len) &&
             CBB_flush(cbb);
    }
  }

  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
  return 0;
}

EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) {
  if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) {
    return EC_KEY_parse_curve_name(cbs);
  }

  /* OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions
   * of named curves.
   *
   * TODO(davidben): Remove support for this. */
  CBS prime, a, b, base_x, base_y, order;
  if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y,
                                  &order)) {
    return NULL;
  }

  /* Look for a matching prime curve. */
  unsigned i;
  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    const struct built_in_curve *curve = &OPENSSL_built_in_curves[i];
    const unsigned param_len = curve->data->param_len;
    /* |curve->data->data| is ordered p, a, b, x, y, order, each component
     * zero-padded up to the field length. Although SEC 1 states that the
     * Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes
     * |a| and |b|, so this comparison must allow omitting leading zeros. (This
     * is relevant for P-521 whose |b| has a leading 0.) */
    if (integers_equal(&prime, curve->data->data, param_len) &&
        integers_equal(&a, curve->data->data + param_len, param_len) &&
        integers_equal(&b, curve->data->data + param_len * 2, param_len) &&
        integers_equal(&base_x, curve->data->data + param_len * 3, param_len) &&
        integers_equal(&base_y, curve->data->data + param_len * 4, param_len) &&
        integers_equal(&order, curve->data->data + param_len * 5, param_len)) {
      return EC_GROUP_new_by_curve_name(curve->nid);
    }
  }

  OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
  return NULL;
}

EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) {
  /* This function treats its |out| parameter differently from other |d2i|
   * functions. If supplied, take the group from |*out|. */
  const EC_GROUP *group = NULL;
  if (out != NULL && *out != NULL) {
    group = EC_KEY_get0_group(*out);
  }

  if (len < 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
    return NULL;
  }
  CBS cbs;
  CBS_init(&cbs, *inp, (size_t)len);
  EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group);
  if (ret == NULL) {
    return NULL;
  }
  if (out != NULL) {
    EC_KEY_free(*out);
    *out = ret;
  }
  *inp = CBS_data(&cbs);
  return ret;
}

int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
  CBB cbb;
  if (!CBB_init(&cbb, 0) ||
      !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) {
    CBB_cleanup(&cbb);
    return -1;
  }
  return CBB_finish_i2d(&cbb, outp);
}

EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) {
  if (len < 0) {
    return NULL;
  }

  CBS cbs;
  CBS_init(&cbs, *inp, (size_t)len);
  EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
  if (group == NULL) {
    return NULL;
  }

  EC_KEY *ret = EC_KEY_new();
  if (ret == NULL || !EC_KEY_set_group(ret, group)) {
    EC_GROUP_free(group);
    EC_KEY_free(ret);
    return NULL;
  }
  EC_GROUP_free(group);

  if (out_key != NULL) {
    EC_KEY_free(*out_key);
    *out_key = ret;
  }
  *inp = CBS_data(&cbs);
  return ret;
}

int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
  if (key == NULL || key->group == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return -1;
  }

  CBB cbb;
  if (!CBB_init(&cbb, 0) ||
      !EC_KEY_marshal_curve_name(&cbb, key->group)) {
    CBB_cleanup(&cbb);
    return -1;
  }
  return CBB_finish_i2d(&cbb, outp);
}

EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
  EC_KEY *ret = NULL;

  if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return NULL;
  }
  ret = *keyp;
  if (ret->pub_key == NULL &&
      (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    return NULL;
  }
  /* save the point conversion form */
  ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
  *inp += len;
  return ret;
}

int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
  size_t buf_len = 0;
  int new_buffer = 0;

  if (key == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
                               0, NULL);

  if (outp == NULL || buf_len == 0) {
    /* out == NULL => just return the length of the octet string */
    return buf_len;
  }

  if (*outp == NULL) {
    *outp = OPENSSL_malloc(buf_len);
    if (*outp == NULL) {
      OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
      return 0;
    }
    new_buffer = 1;
  }
  if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
                          buf_len, NULL)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    if (new_buffer) {
      OPENSSL_free(*outp);
      *outp = NULL;
    }
    return 0;
  }

  if (!new_buffer) {
    *outp += buf_len;
  }
  return buf_len;
}
