// Copyright 2016 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 "net/ssl/ssl_private_key_test_util.h"

#include <vector>

#include "base/bind.h"
#include "base/containers/span.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "crypto/openssl_util.h"
#include "net/base/net_errors.h"
#include "net/ssl/ssl_private_key.h"
#include "net/test/gtest_util.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/digest.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/rsa.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"

using net::test::IsOk;

namespace net {

namespace {

bool VerifyWithOpenSSL(uint16_t algorithm,
                       base::span<const uint8_t> input,
                       EVP_PKEY* key,
                       base::span<const uint8_t> signature) {
  bssl::ScopedEVP_MD_CTX ctx;
  EVP_PKEY_CTX* pctx;
  if (!EVP_DigestVerifyInit(ctx.get(), &pctx,
                            SSL_get_signature_algorithm_digest(algorithm),
                            nullptr, key)) {
    return false;
  }
  if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* hash length */)) {
      return false;
    }
  }
  return EVP_DigestVerify(ctx.get(), signature.data(), signature.size(),
                          input.data(), input.size());
}

void OnSignComplete(base::RunLoop* loop,
                    Error* out_error,
                    std::vector<uint8_t>* out_signature,
                    Error error,
                    const std::vector<uint8_t>& signature) {
  *out_error = error;
  *out_signature = signature;
  loop->Quit();
}

Error DoKeySigningWithWrapper(SSLPrivateKey* key,
                              uint16_t algorithm,
                              base::span<const uint8_t> input,
                              std::vector<uint8_t>* result) {
  Error error;
  base::RunLoop loop;
  key->Sign(algorithm, input,
            base::BindOnce(OnSignComplete, base::Unretained(&loop),
                           base::Unretained(&error), base::Unretained(result)));
  loop.Run();
  return error;
}

}  // namespace

void TestSSLPrivateKeyMatches(SSLPrivateKey* key, const std::string& pkcs8) {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  // Create the equivalent OpenSSL key.
  CBS cbs;
  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(pkcs8.data()), pkcs8.size());
  bssl::UniquePtr<EVP_PKEY> openssl_key(EVP_parse_private_key(&cbs));
  ASSERT_TRUE(openssl_key);
  EXPECT_EQ(0u, CBS_len(&cbs));

  // Test all supported algorithms.
  std::vector<uint16_t> preferences = key->GetAlgorithmPreferences();

  // To support TLS 1.1 and earlier, RSA keys must implicitly support MD5-SHA1,
  // despite not being advertised.
  preferences.push_back(SSL_SIGN_RSA_PKCS1_MD5_SHA1);

  for (uint16_t algorithm : preferences) {
    SCOPED_TRACE(
        SSL_get_signature_algorithm_name(algorithm, 0 /* exclude curve */));
    // BoringSSL will skip signatures algorithms that don't match the key type.
    if (EVP_PKEY_id(openssl_key.get()) !=
        SSL_get_signature_algorithm_key_type(algorithm)) {
      continue;
    }
    // If the RSA key is too small for the hash, skip the algorithm. BoringSSL
    // will filter this algorithm out and decline using it. In particular,
    // 1024-bit RSA keys cannot sign RSA-PSS with SHA-512 and test keys are
    // often 1024 bits.
    if (SSL_is_signature_algorithm_rsa_pss(algorithm) &&
        static_cast<size_t>(EVP_PKEY_size(openssl_key.get())) <
            2 * EVP_MD_size(SSL_get_signature_algorithm_digest(algorithm)) +
                2) {
      continue;
    }

    // Test the key generates valid signatures.
    std::vector<uint8_t> input(100, 'a');
    std::vector<uint8_t> signature;
#ifdef STARBOARD
    base::span<const uint8_t> input_span(input.data(), input.size());
    base::span<const uint8_t> signature_span(signature.data(),
                                             signature.size());
    Error error =
        DoKeySigningWithWrapper(key, algorithm, input_span, &signature);
    EXPECT_THAT(error, IsOk());
    EXPECT_TRUE(VerifyWithOpenSSL(algorithm, input_span, openssl_key.get(),
                                  signature_span));
#else
    Error error = DoKeySigningWithWrapper(key, algorithm, input, &signature);
    EXPECT_THAT(error, IsOk());
    EXPECT_TRUE(
        VerifyWithOpenSSL(algorithm, input, openssl_key.get(), signature));
#endif
  }
}

}  // namespace net
