// Copyright 2020 The Cobalt Authors. All Rights Reserved.
//
// 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
//
//     http://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 "cobalt/subtlecrypto/subtle_crypto.h"

#include <algorithm>
#include <set>
#include <string>

#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/subtlecrypto/crypto_impl.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings.h"

namespace cobalt {
namespace subtlecrypto {

namespace {

const ByteVector to_vector(const web::BufferSource &data) {
  const uint8_t *buff;
  int buf_len;
  web::GetBufferAndSize(data, &buff, &buf_len);
  return ByteVector(buff, buff + buf_len);
}

std::string algo_name(const Algorithm &algo) {
  return algo.has_name() ? algo.name() : "";
}

template <typename T, typename W>
std::string get_name(const W &algorithm) {
  if (algorithm.template IsType<T>()) {
    return algo_name(algorithm.template AsType<T>());
  }
  return std::is_same<T, Algorithm>::value ? ""
                                           : get_name<Algorithm>(algorithm);
}

template <typename T = Algorithm, typename W>
std::string get_name_or_string(const W &algorithm) {
  if (algorithm.template IsType<T>()) {
    return algo_name(algorithm.template AsType<T>());
  }
  return algorithm.template AsType<std::string>();
}

template <typename Promise>
Promise reject(Promise &&promise,
               const scoped_refptr<script::ScriptException> &result) {
  promise->Reject(result);
  return promise;
}

template <typename Promise>
Promise reject(Promise &&promise, web::DOMException::ExceptionCode error) {
  return reject(promise, new web::DOMException(error));
}

template <typename Promise>
Promise reject(Promise &&promise, const std::string &dom_error) {
  return reject(promise, new web::DOMException(dom_error, dom_error));
}

}  // namespace

using PromiseBool = SubtleCrypto::PromiseBool;
using PromiseArray = SubtleCrypto::PromiseArray;
using PromiseWrappable = SubtleCrypto::PromiseWrappable;

SubtleCrypto::SubtleCrypto(script::EnvironmentSettings *environment) {
  global_env_ =
      base::polymorphic_downcast<web::EnvironmentSettings *>(environment)
          ->context()
          ->global_environment();
  script_value_factory_ = global_env_->script_value_factory();
}

SubtleCrypto::~SubtleCrypto() {}

PromiseWrappable SubtleCrypto::CreateKeyPromise() {
  DCHECK(script_value_factory_);
  return script_value_factory_
      ->CreateInterfacePromise<scoped_refptr<CryptoKeyPtr>>();
}

web::BufferSource SubtleCrypto::CreateBufferSource(const ByteVector &input) {
  DCHECK(global_env_);
  auto arrayBuffer =
      script::ArrayBuffer::New(global_env_, input.data(), input.size());
  return web::BufferSource(arrayBuffer);
}

PromiseArray SubtleCrypto::Decrypt(EncryptionAlgorithm algorithm,
                                   const CryptoKeyPtr &key,
                                   const web::BufferSource &data) {
  // 1. Let algorithm and key be the algorithm and key parameters passed to the
  // decrypt method, respectively.
  // 2. Let data be the result of getting a copy of the bytes held by the data
  // parameter passed to the decrypt method.
  // 3. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "decrypt".
  std::string normalizedAlgorithm = get_name<AesCtrParams>(algorithm);
  // 5. Let promise be a new Promise.
  auto promise = CreatePromise();
  // 4. If an error occurred, return a Promise rejected with
  // normalizedAlgorithm.
  if (normalizedAlgorithm != key->get_algorithm()) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  // 9. If the [[usages]] internal slot of key does not contain an entry that is
  // "decrypt", then throw an InvalidAccessError.
  if (!key->usage(KeyUsage::kKeyUsageDecrypt)) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  if (key->get_key().size() == 0) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  if (normalizedAlgorithm == "AES-CTR") {
    auto ctr_params = algorithm.AsType<AesCtrParams>();
    if (!(ctr_params.has_length() && ctr_params.has_counter())) {
      return reject(promise, web::DOMException::kValidationErr);
    }
    auto iv = to_vector(ctr_params.counter());
    auto counter_len = ctr_params.length();
    // 25.7.1 If the counter member of normalizedAlgorithm does not have length
    // 16 bytes, then throw an OperationError.
    // 25.7.2 If the length member of normalizedAlgorithm is zero or is greater
    // than 128, then throw an OperationError.
    if (counter_len < 1 || counter_len > 128 || iv.size() != 16) {
      return reject(promise, "OperationError");
    }
    // 10. Let plaintext be the result of performing the decrypt operation
    // specified by normalizedAlgorithm using key and algorithm and with
    // data as ciphertext.
    auto out = CalculateAES_CTR(to_vector(data), key->get_key(), iv);
    if (out.empty()) {
      reject(promise, "Internal error");
    }
    // 11. Resolve promise with plaintext.
    promise->Resolve(CreateBufferSource(out));
  } else {
    // 7. If the following steps or referenced procedures say to throw an error,
    // reject promise with the returned error and then terminate the algorithm.
    return reject(promise, web::DOMException::kNotSupportedErr);
  }
  // 6. Return promise and asynchronously perform the remaining steps.
  return promise;
}

// TODO: Consider sharing the implementation with Decrypt, as the flow is
// very similar for symmetric algos.
PromiseArray SubtleCrypto::Encrypt(EncryptionAlgorithm algorithm,
                                   const CryptoKeyPtr &key,
                                   const web::BufferSource &data) {
  // 1. Let algorithm and key be the algorithm and key parameters passed to the
  // encrypt method, respectively.
  // 2. Let data be the result of getting a copy of the bytes held by the data
  // parameter passed to the encrypt method.
  // 3. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "encrypt".
  std::string normalizedAlgorithm = get_name<AesCtrParams>(algorithm);
  // 5. Let promise be a new Promise.
  auto promise = CreatePromise();
  // 4. If an error occurred, return a Promise rejected with
  // normalizedAlgorithm.
  if (normalizedAlgorithm != key->get_algorithm()) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  // 9. If the [[usages]] internal slot of key does not contain an entry that is
  // "encrypt", then throw an InvalidAccessError.
  if (!key->usage(KeyUsage::kKeyUsageEncrypt)) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  if (key->get_key().size() == 0) {
    return reject(promise, web::DOMException::kInvalidAccessErr);
  }
  if (normalizedAlgorithm == "AES-CTR") {
    auto ctr_params = algorithm.AsType<AesCtrParams>();
    if (!(ctr_params.has_length() && ctr_params.has_counter())) {
      return reject(promise, web::DOMException::kValidationErr);
    }
    auto iv = to_vector(ctr_params.counter());
    auto counter_len = ctr_params.length();
    // 25.7.1 If the counter member of normalizedAlgorithm does not have length
    // 16 bytes, then throw an OperationError.
    // 25.7.2 If the length member of normalizedAlgorithm is zero or is greater
    // than 128, then throw an OperationError.
    if (counter_len < 1 || counter_len > 128 || iv.size() != 16) {
      return reject(promise, "OperationError");
    }
    // 10. Let ciphertext be the result of performing the encrypt operation
    // specified by normalizedAlgorithm using algorithm and key and with data
    // as plaintext.
    auto out = CalculateAES_CTR(to_vector(data), key->get_key(), iv);
    if (out.empty()) {
      reject(promise, "Internal error");
    }
    // 11. Resolve promise with ciphertext.
    promise->Resolve(CreateBufferSource(out));
  } else {
    // 7. If the following steps or referenced procedures say to throw an error,
    // reject promise with the returned error and then terminate the algorithm.
    return reject(promise, web::DOMException::kNotSupportedErr);
  }
  // 6. Return promise and asynchronously perform the remaining steps.
  return promise;
}

PromiseArray SubtleCrypto::Sign(AlgorithmIdentifier algorithm,
                                const CryptoKeyPtr &key,
                                const web::BufferSource &data) {
  // 1. Let algorithm and key be the algorithm and key parameters passed to the
  // sign method, respectively.
  // 2. Let data be the result of getting a copy of the bytes held by the data
  // parameter passed to the sign method.
  // 3. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "sign".
  std::string normalizedAlgorithm = get_name_or_string(algorithm);
  // 5. Let promise be a new Promise.
  auto promise = CreatePromise();
  if (normalizedAlgorithm == "HMAC") {
    auto hash = Hash::CreateByName(key->get_hash());
    // 9. If the [[usages]] internal slot of key does not contain an entry that
    // is "sign", then throw an InvalidAccessError.
    if (!key->usage(KeyUsage::kKeyUsageSign) || !hash) {
      return reject(promise, web::DOMException::kInvalidAccessErr);
    }
    // 10. Let result be the result of performing the sign operation specified
    // by normalizedAlgorithm using key and algorithm and with data as message.
    auto out = hash->CalculateHMAC(to_vector(data), key->get_key());
    // 11. Resolve promise with result.
    promise->Resolve(CreateBufferSource(out));
  } else {
    // 7. If the following steps or referenced procedures say to throw an error,
    // reject promise with the returned error and then terminate the algorithm.
    return reject(promise, web::DOMException::kNotSupportedErr);
  }
  // 6. Return promise and asynchronously perform the remaining steps.
  return promise;
}

PromiseBool SubtleCrypto::Verify(AlgorithmIdentifier algorithm,
                                 const CryptoKeyPtr &key,
                                 const web::BufferSource &signature,
                                 const web::BufferSource &data) {
  // 1. Let algorithm and key be the algorithm and key parameters passed to the
  // verify method, respectively.
  // 2. Let signature be the result of getting a copy of the bytes held by the
  // signature parameter passed to the verify method.
  // 3. Let data be the result of getting a copy of the bytes held by the data
  // parameter passed to the verify method.
  // 4. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "verify".
  std::string normalizedAlgorithm = get_name_or_string(algorithm);
  // 6. Let promise be a new Promise.
  auto promise = CreatePromise<PromiseBool, bool>();
  if (normalizedAlgorithm == "HMAC") {
    auto hash = Hash::CreateByName(key->get_hash());
    // 10. If the [[usages]] internal slot of key does not contain an entry that
    // is "verify", then throw an InvalidAccessError.
    if (!key->usage(KeyUsage::kKeyUsageVerify) || !hash) {
      return reject(promise, web::DOMException::kInvalidAccessErr);
    }
    // 11. Let result be the result of performing the verify operation
    // specified by normalizedAlgorithm using key, algorithm and signature
    // and with data as message.
    auto out = hash->CalculateHMAC(to_vector(data), key->get_key());
    bool signature_matches = to_vector(signature) == out;
    // 12. Resolve promise with result.
    promise->Resolve(signature_matches);
  } else {
    // 8. If the following steps or referenced procedures say to throw an error,
    // reject promise with the returned error and then terminate the algorithm.
    return reject(promise, web::DOMException::kNotSupportedErr);
  }
  // 7. Return promise and asynchronously perform the remaining steps.
  return promise;
}

PromiseArray SubtleCrypto::Digest(AlgorithmIdentifier algorithm,
                                  const web::BufferSource &data) {
  // 1. Let algorithm be the algorithm parameter passed to the digest method.
  // 2. Let data be the result of getting a copy of the bytes held by the data
  // parameter passed to the digest method.
  // 3. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "digest".
  auto normalizedAlgorithm = get_name_or_string(algorithm);
  // 5. Let promise be a new Promise.
  auto promise = CreatePromise();
  auto hash = Hash::CreateByName(normalizedAlgorithm);
  if (!hash) {
    // 4. If an error occurred, return a Promise rejected with
    // normalizedAlgorithm.
    return reject(promise, web::DOMException::kNotSupportedErr);
  }
  // 8. Let result be the result of performing the digest operation specified by
  // normalizedAlgorithm using algorithm, with data as message.
  hash->Update(to_vector(data));
  auto out = hash->Finish();
  // 9. Resolve promise with result.
  promise->Resolve(CreateBufferSource(out));
  // 6. Return promise and asynchronously perform the remaining steps.
  return promise;
}

PromiseArray SubtleCrypto::GenerateKey(AlgorithmIdentifier algorithm,
                                       bool extractable,
                                       const KeyUsages &keyUsages) {
  NOTIMPLEMENTED();
  return reject(CreatePromise(), web::DOMException::kNotSupportedErr);
}

PromiseArray SubtleCrypto::DeriveKey(AlgorithmIdentifier algorithm,
                                     const CryptoKeyPtr &key,
                                     AlgorithmIdentifier derivedKeyType,
                                     bool extractable,
                                     const KeyUsages &keyUsages) {
  NOTIMPLEMENTED();
  return reject(CreatePromise(), web::DOMException::kNotSupportedErr);
}

PromiseArray SubtleCrypto::DeriveBits(AlgorithmIdentifier algorithm,
                                      const CryptoKeyPtr &key,
                                      const uint32_t length) {
  NOTIMPLEMENTED();
  return reject(CreatePromise(), web::DOMException::kNotSupportedErr);
}

PromiseWrappable SubtleCrypto::ImportKey(
    KeyFormat format, const web::BufferSource &keyData,
    script::UnionType2<ImportKeyAlgorithmParams, std::string> algorithm,
    bool extractable, const KeyUsages &keyUsages) {
  // 1. Let format, algorithm, extractable and usages, be the format, algorithm,
  // extractable and keyUsages parameters passed to the importKey method,
  // respectively.
  // 2. Let keyData be the result of getting a copy of the bytes held by the
  // keyData parameter passed to the importKey method.
  // 3. Let normalizedAlgorithm be the result of normalizing an algorithm, with
  // alg set to algorithm and op set to "importKey".
  std::string normalizedAlgorithm =
      get_name_or_string<ImportKeyAlgorithmParams>(algorithm);
  // 5. Let promise be a new Promise.
  auto promise = CreateKeyPromise();

  if (format != kKeyFormatRaw) {
    NOTIMPLEMENTED();
    return reject(promise,
                  new web::DOMException(web::DOMException::kNotSupportedErr));
  }

  if (!(normalizedAlgorithm == "AES-CTR" || normalizedAlgorithm == "HMAC")) {
    return reject(promise,
                  new web::DOMException(web::DOMException::kNotSupportedErr));
  }

  // 8. Let result be the CryptoKey object that results from performing the
  // import key operation specified by normalizedAlgorithm using keyData,
  // algorithm, format, extractable and usages.
  scoped_refptr<CryptoKey> cryptoKey = new CryptoKey(normalizedAlgorithm);

  // 11. Set the [[usages]] internal slot of result to the normalized value of
  // usages.
  if (!cryptoKey->set_usages(keyUsages)) {
    return reject(promise, new web::DOMException("Invalid key", "not allowed"));
  }
  // 25.7.1 Let data be the octet string contained in keyData.
  cryptoKey->set_key(to_vector(keyData));
  if (algorithm.IsType<ImportKeyAlgorithmParams>()) {
    ImportKeyAlgorithmParams algo_params =
        algorithm.AsType<ImportKeyAlgorithmParams>();
    // 29.6.2 Set hash to equal the hash member of normalizedAlgorithm.
    if (algo_params.has_hash()) {
      cryptoKey->set_hash(algo_params.hash());
    }
  }
  // 12. Resolve promise with result.
  promise->Resolve(cryptoKey);
  // 6. Return promise and asynchronously perform the remaining steps.
  return promise;
}

PromiseArray SubtleCrypto::ExportKey(KeyFormat format,
                                     const CryptoKeyPtr &key) {
  NOTIMPLEMENTED();
  return reject(CreatePromise(), web::DOMException::kNotSupportedErr);
}

PromiseArray SubtleCrypto::WrapKey(KeyFormat format, const CryptoKeyPtr &key,
                                   const CryptoKeyPtr &wrappingKey,
                                   AlgorithmIdentifier algorithm) {
  NOTIMPLEMENTED();
  return reject(CreatePromise(), web::DOMException::kNotSupportedErr);
}

PromiseWrappable SubtleCrypto::UnwrapKey(
    KeyFormat format, const web::BufferSource &wrappedKey,
    const CryptoKeyPtr &unwrappingKey, AlgorithmIdentifier unwrapAlgorithm,
    AlgorithmIdentifier unwrappedKeyAlgorithm, bool extractacble,
    const KeyUsages &keyUsages) {
  NOTIMPLEMENTED();
  return reject(CreateKeyPromise(), web::DOMException::kNotSupportedErr);
}

}  // namespace subtlecrypto
}  // namespace cobalt
