// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/webcrypto/algorithms/ec.h"

#include <stddef.h>
#include <utility>

#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/asymmetric_key_util.h"
#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/platform/web_crypto_key_algorithm.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec.h"
#include "third_party/boringssl/src/include/openssl/ec_key.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"

namespace webcrypto {

namespace {

// Maps a blink::WebCryptoNamedCurve to the corresponding NID used by
// BoringSSL.
Status WebCryptoCurveToNid(blink::WebCryptoNamedCurve named_curve, int* nid) {
  switch (named_curve) {
    case blink::kWebCryptoNamedCurveP256:
      *nid = NID_X9_62_prime256v1;
      return Status::Success();
    case blink::kWebCryptoNamedCurveP384:
      *nid = NID_secp384r1;
      return Status::Success();
    case blink::kWebCryptoNamedCurveP521:
      *nid = NID_secp521r1;
      return Status::Success();
  }
  return Status::ErrorUnsupported();
}

// Maps a BoringSSL NID to the corresponding WebCrypto named curve.
Status NidToWebCryptoCurve(int nid, blink::WebCryptoNamedCurve* named_curve) {
  switch (nid) {
    case NID_X9_62_prime256v1:
      *named_curve = blink::kWebCryptoNamedCurveP256;
      return Status::Success();
    case NID_secp384r1:
      *named_curve = blink::kWebCryptoNamedCurveP384;
      return Status::Success();
    case NID_secp521r1:
      *named_curve = blink::kWebCryptoNamedCurveP521;
      return Status::Success();
  }
  return Status::ErrorImportedEcKeyIncorrectCurve();
}

struct JwkCrvMapping {
  const char* jwk_curve;
  blink::WebCryptoNamedCurve named_curve;
};

const JwkCrvMapping kJwkCrvMappings[] = {
    {"P-256", blink::kWebCryptoNamedCurveP256},
    {"P-384", blink::kWebCryptoNamedCurveP384},
    {"P-521", blink::kWebCryptoNamedCurveP521},
};

// Gets the "crv" parameter from a JWK and converts it to a WebCryptoNamedCurve.
Status ReadJwkCrv(const JwkReader& jwk,
                  blink::WebCryptoNamedCurve* named_curve) {
  std::string jwk_curve;
  Status status = jwk.GetString("crv", &jwk_curve);
  if (status.IsError())
    return status;

  for (size_t i = 0; i < base::size(kJwkCrvMappings); ++i) {
    if (kJwkCrvMappings[i].jwk_curve == jwk_curve) {
      *named_curve = kJwkCrvMappings[i].named_curve;
      return Status::Success();
    }
  }

  return Status::ErrorJwkIncorrectCrv();
}

// Converts a WebCryptoNamedCurve to an equivalent JWK "crv".
Status WebCryptoCurveToJwkCrv(blink::WebCryptoNamedCurve named_curve,
                              std::string* jwk_crv) {
  for (size_t i = 0; i < base::size(kJwkCrvMappings); ++i) {
    if (kJwkCrvMappings[i].named_curve == named_curve) {
      *jwk_crv = kJwkCrvMappings[i].jwk_curve;
      return Status::Success();
    }
  }
  return Status::ErrorUnexpected();
}

// Verifies that an EC key imported from PKCS8 or SPKI format is correct.
// This involves verifying the key validity, and the NID for the named curve.
// Also removes the EC_PKEY_NO_PUBKEY flag if present.
Status VerifyEcKeyAfterSpkiOrPkcs8Import(
    EVP_PKEY* pkey,
    blink::WebCryptoNamedCurve expected_named_curve) {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey);
  if (!ec)
    return Status::ErrorUnexpected();

  // When importing an ECPrivateKey, the public key is optional. If it was
  // omitted then the public key will be calculated by BoringSSL and added into
  // the EC_KEY. However an encoding flag is set such that when exporting to
  // PKCS8 format the public key is once again omitted. Remove this flag.
  unsigned int enc_flags = EC_KEY_get_enc_flags(ec);
  enc_flags &= ~EC_PKEY_NO_PUBKEY;
  EC_KEY_set_enc_flags(ec, enc_flags);

  if (!EC_KEY_check_key(ec))
    return Status::ErrorEcKeyInvalid();

  // Make sure the curve matches the expected curve name.
  int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
  blink::WebCryptoNamedCurve named_curve = blink::kWebCryptoNamedCurveP256;
  Status status = NidToWebCryptoCurve(curve_nid, &named_curve);
  if (status.IsError())
    return status;

  if (named_curve != expected_named_curve)
    return Status::ErrorImportedEcKeyIncorrectCurve();

  return Status::Success();
}

// Creates an EC_KEY for the given WebCryptoNamedCurve.
Status CreateEC_KEY(blink::WebCryptoNamedCurve named_curve,
                    bssl::UniquePtr<EC_KEY>* ec) {
  int curve_nid = 0;
  Status status = WebCryptoCurveToNid(named_curve, &curve_nid);
  if (status.IsError())
    return status;

  ec->reset(EC_KEY_new_by_curve_name(curve_nid));
  if (!ec->get())
    return Status::OperationError();

  return Status::Success();
}

// Writes an unsigned BIGNUM into |jwk|, zero-padding it to a length of
// |padded_length|.
Status WritePaddedBIGNUM(const std::string& member_name,
                         const BIGNUM* value,
                         size_t padded_length,
                         JwkWriter* jwk) {
  std::vector<uint8_t> padded_bytes(padded_length);
  if (!BN_bn2bin_padded(padded_bytes.data(), padded_bytes.size(), value))
    return Status::OperationError();
  jwk->SetBytes(member_name, CryptoData(padded_bytes));
  return Status::Success();
}

// Reads a fixed length BIGNUM from a JWK.
Status ReadPaddedBIGNUM(const JwkReader& jwk,
                        const std::string& member_name,
                        size_t expected_length,
                        bssl::UniquePtr<BIGNUM>* out) {
  std::string bytes;
  Status status = jwk.GetBytes(member_name, &bytes);
  if (status.IsError())
    return status;

  if (bytes.size() != expected_length) {
    return Status::JwkOctetStringWrongLength(member_name, expected_length,
                                             bytes.size());
  }

  out->reset(CreateBIGNUM(bytes));
  return Status::Success();
}

int GetGroupDegreeInBytes(EC_KEY* ec) {
  const EC_GROUP* group = EC_KEY_get0_group(ec);
  return NumBitsToBytes(EC_GROUP_get_degree(group));
}

// Extracts the public key as affine coordinates (x,y).
Status GetPublicKey(EC_KEY* ec,
                    bssl::UniquePtr<BIGNUM>* x,
                    bssl::UniquePtr<BIGNUM>* y) {
  const EC_GROUP* group = EC_KEY_get0_group(ec);
  const EC_POINT* point = EC_KEY_get0_public_key(ec);

  x->reset(BN_new());
  y->reset(BN_new());

  if (!EC_POINT_get_affine_coordinates_GFp(group, point, x->get(), y->get(),
                                           nullptr)) {
    return Status::OperationError();
  }

  return Status::Success();
}

// Synthesizes an import algorithm given a key algorithm, so that
// deserialization can re-use the ImportKey*() methods.
blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
    const blink::WebCryptoKeyAlgorithm& algorithm) {
  return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
      algorithm.Id(), new blink::WebCryptoEcKeyImportParams(
                          algorithm.EcParams()->NamedCurve()));
}

}  // namespace

Status EcAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                                bool extractable,
                                blink::WebCryptoKeyUsageMask combined_usages,
                                GenerateKeyResult* result) const {
  blink::WebCryptoKeyUsageMask public_usages = 0;
  blink::WebCryptoKeyUsageMask private_usages = 0;

  Status status = GetUsagesForGenerateAsymmetricKey(
      combined_usages, all_public_key_usages_, all_private_key_usages_,
      &public_usages, &private_usages);
  if (status.IsError())
    return status;

  const blink::WebCryptoEcKeyGenParams* params = algorithm.EcKeyGenParams();

  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  // Generate an EC key pair.
  bssl::UniquePtr<EC_KEY> ec_private_key;
  status = CreateEC_KEY(params->NamedCurve(), &ec_private_key);
  if (status.IsError())
    return status;

  if (!EC_KEY_generate_key(ec_private_key.get()))
    return Status::OperationError();

  // Construct an EVP_PKEY for the private key.
  bssl::UniquePtr<EVP_PKEY> private_pkey(EVP_PKEY_new());
  if (!private_pkey ||
      !EVP_PKEY_set1_EC_KEY(private_pkey.get(), ec_private_key.get())) {
    return Status::OperationError();
  }

  // Construct an EVP_PKEY for just the public key.
  bssl::UniquePtr<EC_KEY> ec_public_key;
  bssl::UniquePtr<EVP_PKEY> public_pkey(EVP_PKEY_new());
  status = CreateEC_KEY(params->NamedCurve(), &ec_public_key);
  if (status.IsError())
    return status;
  if (!EC_KEY_set_public_key(ec_public_key.get(),
                             EC_KEY_get0_public_key(ec_private_key.get()))) {
    return Status::OperationError();
  }
  if (!public_pkey ||
      !EVP_PKEY_set1_EC_KEY(public_pkey.get(), ec_public_key.get())) {
    return Status::OperationError();
  }

  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;

  blink::WebCryptoKeyAlgorithm key_algorithm =
      blink::WebCryptoKeyAlgorithm::CreateEc(algorithm.Id(),
                                             params->NamedCurve());

  // Note that extractable is unconditionally set to true. This is because per
  // the WebCrypto spec generated public keys are always extractable.
  status = CreateWebCryptoPublicKey(std::move(public_pkey), key_algorithm, true,
                                    public_usages, &public_key);
  if (status.IsError())
    return status;

  status = CreateWebCryptoPrivateKey(std::move(private_pkey), key_algorithm,
                                     extractable, private_usages, &private_key);
  if (status.IsError())
    return status;

  result->AssignKeyPair(public_key, private_key);
  return Status::Success();
}

Status EcAlgorithm::ImportKey(blink::WebCryptoKeyFormat format,
                              const CryptoData& key_data,
                              const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
                              blink::WebCryptoKeyUsageMask usages,
                              blink::WebCryptoKey* key) const {
  switch (format) {
    case blink::kWebCryptoKeyFormatRaw:
      return ImportKeyRaw(key_data, algorithm, extractable, usages, key);
    case blink::kWebCryptoKeyFormatPkcs8:
      return ImportKeyPkcs8(key_data, algorithm, extractable, usages, key);
    case blink::kWebCryptoKeyFormatSpki:
      return ImportKeySpki(key_data, algorithm, extractable, usages, key);
    case blink::kWebCryptoKeyFormatJwk:
      return ImportKeyJwk(key_data, algorithm, extractable, usages, key);
    default:
      return Status::ErrorUnsupportedImportKeyFormat();
  }
}

Status EcAlgorithm::ExportKey(blink::WebCryptoKeyFormat format,
                              const blink::WebCryptoKey& key,
                              std::vector<uint8_t>* buffer) const {
  switch (format) {
    case blink::kWebCryptoKeyFormatRaw:
      return ExportKeyRaw(key, buffer);
    case blink::kWebCryptoKeyFormatPkcs8:
      return ExportKeyPkcs8(key, buffer);
    case blink::kWebCryptoKeyFormatSpki:
      return ExportKeySpki(key, buffer);
    case blink::kWebCryptoKeyFormatJwk:
      return ExportKeyJwk(key, buffer);
    default:
      return Status::ErrorUnsupportedExportKeyFormat();
  }
}

Status EcAlgorithm::ImportKeyRaw(const CryptoData& key_data,
                                 const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
                                 blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoKey* key) const {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  Status status = CheckKeyCreationUsages(all_public_key_usages_, usages);
  if (status.IsError())
    return status;

  const blink::WebCryptoEcKeyImportParams* params =
      algorithm.EcKeyImportParams();

  // Create an EC_KEY.
  bssl::UniquePtr<EC_KEY> ec;
  status = CreateEC_KEY(params->NamedCurve(), &ec);
  if (status.IsError())
    return status;

  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(EC_KEY_get0_group(ec.get())));
  if (!point.get())
    return Status::OperationError();

  // Convert the "raw" input from X9.62 format to an EC_POINT.
  if (!EC_POINT_oct2point(EC_KEY_get0_group(ec.get()), point.get(),
                          key_data.bytes(), key_data.byte_length(), nullptr)) {
    return Status::DataError();
  }

  // Copy the point (public key) into the EC_KEY.
  if (!EC_KEY_set_public_key(ec.get(), point.get()))
    return Status::OperationError();

  // Verify the key.
  if (!EC_KEY_check_key(ec.get()))
    return Status::ErrorEcKeyInvalid();

  // Wrap the EC_KEY into an EVP_PKEY.
  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get()))
    return Status::OperationError();

  blink::WebCryptoKeyAlgorithm key_algorithm =
      blink::WebCryptoKeyAlgorithm::CreateEc(algorithm.Id(),
                                             params->NamedCurve());

  // Wrap the EVP_PKEY into a WebCryptoKey
  return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable,
                                  usages, key);
}

Status EcAlgorithm::ImportKeyPkcs8(const CryptoData& key_data,
                                   const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
                                   blink::WebCryptoKeyUsageMask usages,
                                   blink::WebCryptoKey* key) const {
  Status status = CheckKeyCreationUsages(all_private_key_usages_, usages);
  if (status.IsError())
    return status;

  bssl::UniquePtr<EVP_PKEY> private_key;
  status = ImportUnverifiedPkeyFromPkcs8(key_data, EVP_PKEY_EC, &private_key);
  if (status.IsError())
    return status;

  const blink::WebCryptoEcKeyImportParams* params =
      algorithm.EcKeyImportParams();

  status = VerifyEcKeyAfterSpkiOrPkcs8Import(private_key.get(),
                                             params->NamedCurve());
  if (status.IsError())
    return status;

  return CreateWebCryptoPrivateKey(std::move(private_key),
                                   blink::WebCryptoKeyAlgorithm::CreateEc(
                                       algorithm.Id(), params->NamedCurve()),
                                   extractable, usages, key);
}

Status EcAlgorithm::ImportKeySpki(const CryptoData& key_data,
                                  const blink::WebCryptoAlgorithm& algorithm,
                                  bool extractable,
                                  blink::WebCryptoKeyUsageMask usages,
                                  blink::WebCryptoKey* key) const {
  Status status = CheckKeyCreationUsages(all_public_key_usages_, usages);
  if (status.IsError())
    return status;

  bssl::UniquePtr<EVP_PKEY> public_key;
  status = ImportUnverifiedPkeyFromSpki(key_data, EVP_PKEY_EC, &public_key);
  if (status.IsError())
    return status;

  const blink::WebCryptoEcKeyImportParams* params =
      algorithm.EcKeyImportParams();

  status =
      VerifyEcKeyAfterSpkiOrPkcs8Import(public_key.get(), params->NamedCurve());
  if (status.IsError())
    return status;

  return CreateWebCryptoPublicKey(std::move(public_key),
                                  blink::WebCryptoKeyAlgorithm::CreateEc(
                                      algorithm.Id(), params->NamedCurve()),
                                  extractable, usages, key);
}

// The format for JWK EC keys is given by:
// https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-36#section-6.2
Status EcAlgorithm::ImportKeyJwk(const CryptoData& key_data,
                                 const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
                                 blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoKey* key) const {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  const blink::WebCryptoEcKeyImportParams* params =
      algorithm.EcKeyImportParams();

  // When importing EC keys from JWK there may be up to *three* separate curve
  // names:
  //
  //   (1) The one given to WebCrypto's importKey (params->namedCurve()).
  //   (2) JWK's "crv" member
  //   (3) A curve implied by JWK's "alg" member.
  //
  // (In the case of ECDSA, the "alg" member implicitly names a curve and hash)

  JwkReader jwk;
  Status status = jwk.Init(key_data, extractable, usages, "EC",
                           GetJwkAlgorithm(params->NamedCurve()));
  if (status.IsError())
    return status;

  // Verify that "crv" matches expected curve.
  blink::WebCryptoNamedCurve jwk_crv = blink::kWebCryptoNamedCurveP256;
  status = ReadJwkCrv(jwk, &jwk_crv);
  if (status.IsError())
    return status;
  if (jwk_crv != params->NamedCurve())
    return Status::ErrorJwkIncorrectCrv();

  // Only private keys have a "d" parameter. The key may still be invalid, but
  // tentatively decide if it is a public or private key.
  bool is_private_key = jwk.HasMember("d");

  // Now that the key type is known, verify the usages.
  if (is_private_key) {
    status = CheckKeyCreationUsages(all_private_key_usages_, usages);
  } else {
    status = CheckKeyCreationUsages(all_public_key_usages_, usages);
  }

  if (status.IsError())
    return status;

  // Create an EC_KEY.
  bssl::UniquePtr<EC_KEY> ec;
  status = CreateEC_KEY(params->NamedCurve(), &ec);
  if (status.IsError())
    return status;

  // JWK requires the length of x, y, d to match the group degree.
  int degree_bytes = GetGroupDegreeInBytes(ec.get());

  // Read the public key's uncompressed affine coordinates.
  bssl::UniquePtr<BIGNUM> x;
  status = ReadPaddedBIGNUM(jwk, "x", degree_bytes, &x);
  if (status.IsError())
    return status;

  bssl::UniquePtr<BIGNUM> y;
  status = ReadPaddedBIGNUM(jwk, "y", degree_bytes, &y);
  if (status.IsError())
    return status;

  // TODO(eroman): Distinguish more accurately between a DataError and
  // OperationError. In general if this fails it was due to the key being an
  // invalid EC key.
  if (!EC_KEY_set_public_key_affine_coordinates(ec.get(), x.get(), y.get()))
    return Status::DataError();

  // Extract the "d" parameters.
  if (is_private_key) {
    bssl::UniquePtr<BIGNUM> d;
    status = ReadPaddedBIGNUM(jwk, "d", degree_bytes, &d);
    if (status.IsError())
      return status;

    if (!EC_KEY_set_private_key(ec.get(), d.get()))
      return Status::OperationError();
  }

  // Verify the key.
  if (!EC_KEY_check_key(ec.get()))
    return Status::ErrorEcKeyInvalid();

  // Wrap the EC_KEY into an EVP_PKEY.
  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get()))
    return Status::OperationError();

  blink::WebCryptoKeyAlgorithm key_algorithm =
      blink::WebCryptoKeyAlgorithm::CreateEc(algorithm.Id(),
                                             params->NamedCurve());

  // Wrap the EVP_PKEY into a WebCryptoKey
  if (is_private_key) {
    return CreateWebCryptoPrivateKey(std::move(pkey), key_algorithm,
                                     extractable, usages, key);
  }
  return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable,
                                  usages, key);
}

Status EcAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
                                 std::vector<uint8_t>* buffer) const {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  if (key.GetType() != blink::kWebCryptoKeyTypePublic)
    return Status::ErrorUnexpectedKeyType();

  EVP_PKEY* pkey = GetEVP_PKEY(key);

  EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey);
  if (!ec)
    return Status::ErrorUnexpected();

  // Serialize the public key as an uncompressed point in X9.62 form.
  uint8_t* raw;
  size_t raw_len;
  bssl::ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 0) ||
      !EC_POINT_point2cbb(cbb.get(), EC_KEY_get0_group(ec),
                          EC_KEY_get0_public_key(ec),
                          POINT_CONVERSION_UNCOMPRESSED, nullptr) ||
      !CBB_finish(cbb.get(), &raw, &raw_len)) {
    return Status::OperationError();
  }
  buffer->assign(raw, raw + raw_len);
  OPENSSL_free(raw);

  return Status::Success();
}

Status EcAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
                                   std::vector<uint8_t>* buffer) const {
  if (key.GetType() != blink::kWebCryptoKeyTypePrivate)
    return Status::ErrorUnexpectedKeyType();
  // This relies on the fact that PKCS8 formatted data was already
  // associated with the key during its creation (used by
  // structured clone).
  *buffer = GetSerializedKeyData(key);
  return Status::Success();
}

Status EcAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key,
                                  std::vector<uint8_t>* buffer) const {
  if (key.GetType() != blink::kWebCryptoKeyTypePublic)
    return Status::ErrorUnexpectedKeyType();
  // This relies on the fact that SPKI formatted data was already
  // associated with the key during its creation (used by
  // structured clone).
  *buffer = GetSerializedKeyData(key);
  return Status::Success();
}

// The format for JWK EC keys is given by:
// https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-36#section-6.2
Status EcAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
                                 std::vector<uint8_t>* buffer) const {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  EVP_PKEY* pkey = GetEVP_PKEY(key);

  EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey);
  if (!ec)
    return Status::ErrorUnexpected();

  // No "alg" is set for EC keys.
  JwkWriter jwk(std::string(), key.Extractable(), key.Usages(), "EC");

  // Set the crv
  std::string crv;
  Status status =
      WebCryptoCurveToJwkCrv(key.Algorithm().EcParams()->NamedCurve(), &crv);
  if (status.IsError())
    return status;

  int degree_bytes = GetGroupDegreeInBytes(ec);

  jwk.SetString("crv", crv);

  bssl::UniquePtr<BIGNUM> x;
  bssl::UniquePtr<BIGNUM> y;
  status = GetPublicKey(ec, &x, &y);
  if (status.IsError())
    return status;

  status = WritePaddedBIGNUM("x", x.get(), degree_bytes, &jwk);
  if (status.IsError())
    return status;

  status = WritePaddedBIGNUM("y", y.get(), degree_bytes, &jwk);
  if (status.IsError())
    return status;

  if (key.GetType() == blink::kWebCryptoKeyTypePrivate) {
    const BIGNUM* d = EC_KEY_get0_private_key(ec);
    status = WritePaddedBIGNUM("d", d, degree_bytes, &jwk);
    if (status.IsError())
      return status;
  }

  jwk.ToJson(buffer);
  return Status::Success();
}

// TODO(eroman): Defer import to the crypto thread. http://crbug.com/430763
Status EcAlgorithm::DeserializeKeyForClone(
    const blink::WebCryptoKeyAlgorithm& algorithm,
    blink::WebCryptoKeyType type,
    bool extractable,
    blink::WebCryptoKeyUsageMask usages,
    const CryptoData& key_data,
    blink::WebCryptoKey* key) const {
  if (algorithm.ParamsType() != blink::kWebCryptoKeyAlgorithmParamsTypeEc)
    return Status::ErrorUnexpected();

  blink::WebCryptoAlgorithm import_algorithm =
      SynthesizeImportAlgorithmForClone(algorithm);

  Status status;

  // The serialized data will be either SPKI or PKCS8 formatted.
  switch (type) {
    case blink::kWebCryptoKeyTypePublic:
      status =
          ImportKeySpki(key_data, import_algorithm, extractable, usages, key);
      break;
    case blink::kWebCryptoKeyTypePrivate:
      status =
          ImportKeyPkcs8(key_data, import_algorithm, extractable, usages, key);
      break;
    default:
      return Status::ErrorUnexpected();
  }

  if (!status.IsSuccess())
    return status;

  // There is some duplicated information in the serialized format used by
  // structured clone (since the KeyAlgorithm is serialized separately from the
  // key data). Use this extra information to further validate what was
  // deserialized from the key data.

  if (algorithm.Id() != key->Algorithm().Id())
    return Status::ErrorUnexpected();

  if (type != key->GetType())
    return Status::ErrorUnexpected();

  if (algorithm.EcParams()->NamedCurve() !=
      key->Algorithm().EcParams()->NamedCurve()) {
    return Status::ErrorUnexpected();
  }

  return Status::Success();
}

}  // namespace webcrypto
