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

#include "components/webcrypto/fuzzer_support.h"

#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/no_destructor.h"
#include "base/task/single_thread_task_executor.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/status.h"
#include "mojo/core/embedder/embedder.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/web/blink.h"

namespace webcrypto {

namespace {

// This mock is used to initialize blink.
class InitOnce : public blink::Platform {
 public:
  InitOnce() {
    base::CommandLine::Init(0, nullptr);
    mojo::core::Init();
    blink::Platform::CreateMainThreadAndInitialize(this);
  }
  ~InitOnce() override = default;

 private:
  base::SingleThreadTaskExecutor main_thread_task_executor_;
};

void EnsureInitialized() {
  static base::NoDestructor<InitOnce> init_once;
}

blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
    blink::WebCryptoAlgorithmId id,
    blink::WebCryptoAlgorithmId hash_id) {
  DCHECK(blink::WebCryptoAlgorithm::IsHash(hash_id));
  return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
      id,
      new blink::WebCryptoRsaHashedImportParams(
          blink::WebCryptoAlgorithm::AdoptParamsAndCreate(hash_id, nullptr)));
}

blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
    blink::WebCryptoAlgorithmId id,
    blink::WebCryptoNamedCurve named_curve) {
  return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
      id, new blink::WebCryptoEcKeyImportParams(named_curve));
}

}  // namespace

blink::WebCryptoKeyUsageMask GetCompatibleKeyUsages(
    blink::WebCryptoKeyFormat format) {
  // SPKI format implies import of a public key, whereas PKCS8 implies import
  // of a private key. Pick usages that are compatible with a signature
  // algorithm.
  return format == blink::kWebCryptoKeyFormatSpki
             ? blink::kWebCryptoKeyUsageVerify
             : blink::kWebCryptoKeyUsageSign;
}

void ImportEcKeyFromDerFuzzData(const uint8_t* data,
                                size_t size,
                                blink::WebCryptoKeyFormat format) {
  DCHECK(format == blink::kWebCryptoKeyFormatSpki ||
         format == blink::kWebCryptoKeyFormatPkcs8);
  EnsureInitialized();

  // There are 3 possible EC named curves. Fix this parameter. It shouldn't
  // matter based on the current implementation for PKCS8 or SPKI. But it
  // will have an impact when parsing JWK format.
  blink::WebCryptoNamedCurve curve = blink::kWebCryptoNamedCurveP384;

  // Always use ECDSA as the algorithm. Shouldn't make much difference for
  // non-JWK formats.
  blink::WebCryptoAlgorithmId algorithm_id = blink::kWebCryptoAlgorithmIdEcdsa;

  // Use key usages that are compatible with the chosen algorithm and key type.
  blink::WebCryptoKeyUsageMask usages = GetCompatibleKeyUsages(format);

  blink::WebCryptoKey key;
  webcrypto::Status status = webcrypto::ImportKey(
      format, UNSAFE_TODO(base::span(data, size)),
      CreateEcImportAlgorithm(algorithm_id, curve), true, usages, &key);

  // These errors imply a bad setup of parameters, and means ImportKey() may not
  // be testing the actual parsing.
  DCHECK_NE(status.error_details(),
            Status::ErrorUnsupportedImportKeyFormat().error_details());
  DCHECK_NE(status.error_details(),
            Status::ErrorCreateKeyBadUsages().error_details());
}

void ImportEcKeyFromRawFuzzData(const uint8_t* data, size_t size) {
  EnsureInitialized();

  // There are 3 possible EC named curves. Consume the first byte to decide on
  // the curve.
  uint8_t curve_index = 0;
  if (size > 0) {
    curve_index = data[0];
    UNSAFE_TODO(data++);
    size--;
  }

  blink::WebCryptoNamedCurve curve;

  switch (curve_index % 3) {
    case 0:
      curve = blink::kWebCryptoNamedCurveP256;
      break;
    case 1:
      curve = blink::kWebCryptoNamedCurveP384;
      break;
    default:
      curve = blink::kWebCryptoNamedCurveP521;
      break;
  }

  // Always use ECDSA as the algorithm. Shouldn't make an difference for import.
  blink::WebCryptoAlgorithmId algorithm_id = blink::kWebCryptoAlgorithmIdEcdsa;

  // Use key usages that are compatible with the chosen algorithm and key type.
  blink::WebCryptoKeyUsageMask usages = blink::kWebCryptoKeyUsageVerify;

  blink::WebCryptoKey key;
  webcrypto::Status status = webcrypto::ImportKey(
      blink::kWebCryptoKeyFormatRaw, UNSAFE_TODO(base::span(data, size)),
      CreateEcImportAlgorithm(algorithm_id, curve), true, usages, &key);

  // These errors imply a bad setup of parameters, and means ImportKey() may not
  // be testing the actual parsing.
  DCHECK_NE(status.error_details(),
            Status::ErrorUnsupportedImportKeyFormat().error_details());
  DCHECK_NE(status.error_details(),
            Status::ErrorCreateKeyBadUsages().error_details());
}

void ImportRsaKeyFromDerFuzzData(const uint8_t* data,
                                 size_t size,
                                 blink::WebCryptoKeyFormat format) {
  DCHECK(format == blink::kWebCryptoKeyFormatSpki ||
         format == blink::kWebCryptoKeyFormatPkcs8);
  EnsureInitialized();

  // There are several possible hash functions. Fix this parameter. It shouldn't
  // matter based on the current implementation for PKCS8 or SPKI. But it
  // will have an impact when parsing JWK format.
  blink::WebCryptoAlgorithmId hash_id = blink::kWebCryptoAlgorithmIdSha256;

  // Always use RSA-SSA PKCS#1 as the algorithm. Shouldn't make much difference
  // for non-JWK formats.
  blink::WebCryptoAlgorithmId algorithm_id =
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5;

  // Use key usages that are compatible with the chosen algorithm and key type.
  blink::WebCryptoKeyUsageMask usages = GetCompatibleKeyUsages(format);

  blink::WebCryptoKey key;
  webcrypto::Status status = webcrypto::ImportKey(
      format, UNSAFE_TODO(base::span(data, size)),
      CreateRsaHashedImportAlgorithm(algorithm_id, hash_id), true, usages,
      &key);

  // These errors imply a bad setup of parameters, and means ImportKey() may not
  // be testing the actual parsing.
  DCHECK_NE(status.error_details(),
            Status::ErrorUnsupportedImportKeyFormat().error_details());
  DCHECK_NE(status.error_details(),
            Status::ErrorCreateKeyBadUsages().error_details());
}

}  // namespace webcrypto
