//
// Copyright 2020 gRPC authors.
//
// 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 <memory>

#include <gtest/gtest.h>

#include <grpc/grpc.h>
#include <grpc/grpc_crl_provider.h>
#include <grpc/grpc_security.h>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/security/tls_credentials_options.h>
#include <grpcpp/security/tls_crl_provider.h>

#include "test/core/util/test_config.h"
#include "test/cpp/util/tls_test_utils.h"

#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
#define CRL_DIR_PATH "test/core/tsi/test_creds/crl_data/crls"

namespace {

constexpr const char* kRootCertName = "root_cert_name";
constexpr const char* kRootCertContents = "root_cert_contents";
constexpr const char* kIdentityCertName = "identity_cert_name";
constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
constexpr const char* kIdentityCertContents = "identity_cert_contents";

using ::grpc::experimental::CreateStaticCrlProvider;
using ::grpc::experimental::ExternalCertificateVerifier;
using ::grpc::experimental::FileWatcherCertificateProvider;
using ::grpc::experimental::NoOpCertificateVerifier;
using ::grpc::experimental::StaticDataCertificateProvider;
using ::grpc::experimental::TlsServerCredentials;
using ::grpc::experimental::TlsServerCredentialsOptions;

}  // namespace

namespace grpc {
namespace testing {
namespace {

TEST(
    CredentialsTest,
    TlsServerCredentialsWithStaticDataCertificateProviderLoadingRootAndIdentity) {
  experimental::IdentityKeyCertPair key_cert_pair;
  key_cert_pair.private_key = kIdentityCertPrivateKey;
  key_cert_pair.certificate_chain = kIdentityCertContents;
  std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
  identity_key_cert_pairs.emplace_back(key_cert_pair);
  auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
      kRootCertContents, identity_key_cert_pairs);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_root_certs();
  options.set_root_cert_name(kRootCertName);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

// ServerCredentials should always have identity credential presented.
// Otherwise gRPC stack will fail.
TEST(CredentialsTest,
     TlsServerCredentialsWithStaticDataCertificateProviderLoadingIdentityOnly) {
  experimental::IdentityKeyCertPair key_cert_pair;
  key_cert_pair.private_key = kIdentityCertPrivateKey;
  key_cert_pair.certificate_chain = kIdentityCertContents;
  std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs;
  // Adding two key_cert_pair(s) should still work.
  identity_key_cert_pairs.emplace_back(key_cert_pair);
  identity_key_cert_pairs.emplace_back(key_cert_pair);
  auto certificate_provider =
      std::make_shared<StaticDataCertificateProvider>(identity_key_cert_pairs);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

TEST(
    CredentialsTest,
    TlsServerCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) {
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_root_certs();
  options.set_root_cert_name(kRootCertName);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithCrlChecking) {
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_root_certs();
  options.set_root_cert_name(kRootCertName);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  options.set_crl_directory(CRL_DIR_PATH);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

// ServerCredentials should always have identity credential presented.
// Otherwise gRPC stack will fail.
TEST(
    CredentialsTest,
    TlsServerCredentialsWithFileWatcherCertificateProviderLoadingIdentityOnly) {
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithSyncExternalVerifier) {
  auto verifier =
      ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_root_certs();
  options.set_root_cert_name(kRootCertName);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  options.set_certificate_verifier(verifier);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithAsyncExternalVerifier) {
  auto verifier =
      ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true);
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.watch_root_certs();
  options.set_root_cert_name(kRootCertName);
  options.watch_identity_key_cert_pairs();
  options.set_identity_cert_name(kIdentityCertName);
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
  options.set_certificate_verifier(verifier);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(server_credentials.get() != nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithCrlProvider) {
  auto provider = experimental::CreateStaticCrlProvider({});
  ASSERT_TRUE(provider.ok());
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.set_crl_provider(*provider);
  auto channel_credentials = grpc::experimental::TlsServerCredentials(options);
  GPR_ASSERT(channel_credentials.get() != nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithCrlProviderAndDirectory) {
  auto provider = experimental::CreateStaticCrlProvider({});
  ASSERT_TRUE(provider.ok());
  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
  options.set_crl_directory(CRL_DIR_PATH);
  options.set_crl_provider(*provider);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  //   TODO(gtcooke94) - behavior might change to make this return nullptr in
  //   the future
  GPR_ASSERT(server_credentials != nullptr);
}

TEST(CredentialsTest, TlsCredentialsOptionsDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options(provider);
  (void)options;
}

TEST(CredentialsTest, MultipleOptionsOneCertificateProviderDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options_1(provider);
  (void)options_1;
  TlsServerCredentialsOptions options_2(provider);
  (void)options_2;
}

TEST(CredentialsTest, MultipleOptionsOneCertificateVerifierDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  auto verifier = std::make_shared<NoOpCertificateVerifier>();
  TlsServerCredentialsOptions options_1(provider);
  options_1.set_certificate_verifier(verifier);
  TlsServerCredentialsOptions options_2(provider);
  options_2.set_certificate_verifier(verifier);
}

TEST(CredentialsTest, MultipleOptionsOneCrlProviderDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  auto crl_provider = CreateStaticCrlProvider(/*crls=*/{});
  EXPECT_TRUE(crl_provider.ok());
  TlsServerCredentialsOptions options_1(provider);
  options_1.set_crl_provider(*crl_provider);
  TlsServerCredentialsOptions options_2(provider);
  options_2.set_crl_provider(*crl_provider);
}

TEST(CredentialsTest, TlsServerCredentialsDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options(provider);
  auto server_creds = TlsServerCredentials(options);
  EXPECT_NE(server_creds, nullptr);
}

TEST(CredentialsTest, MultipleServerCredentialsOneOptionsDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options(provider);
  auto server_creds_1 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_1, nullptr);
  auto server_creds_2 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_2, nullptr);
}

TEST(CredentialsTest,
     MultipleServerCredentialsOneCertificateVerifierDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options(provider);
  auto verifier = std::make_shared<NoOpCertificateVerifier>();
  options.set_certificate_verifier(verifier);
  auto server_creds_1 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_1, nullptr);
  auto server_creds_2 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_2, nullptr);
}

TEST(CredentialsTest, MultipleServerCredentialsOneCrlProviderDoesNotLeak) {
  auto provider = std::make_shared<StaticDataCertificateProvider>("root-pem");
  TlsServerCredentialsOptions options(provider);
  auto crl_provider = CreateStaticCrlProvider(/*crls=*/{});
  EXPECT_TRUE(crl_provider.ok());
  options.set_crl_provider(*crl_provider);
  auto server_creds_1 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_1, nullptr);
  auto server_creds_2 = TlsServerCredentials(options);
  EXPECT_NE(server_creds_2, nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithGoodMinMaxTlsVersions) {
  grpc::experimental::TlsServerCredentialsOptions options(
      /*certificate_provider=*/nullptr);
  options.set_min_tls_version(grpc_tls_version::TLS1_2);
  options.set_max_tls_version(grpc_tls_version::TLS1_3);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  EXPECT_NE(server_credentials, nullptr);
}

TEST(CredentialsTest, TlsServerCredentialsWithBadMinMaxTlsVersions) {
  grpc::experimental::TlsServerCredentialsOptions options(
      /*certificate_provider=*/nullptr);
  options.set_min_tls_version(grpc_tls_version::TLS1_3);
  options.set_max_tls_version(grpc_tls_version::TLS1_2);
  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
  EXPECT_EQ(server_credentials, nullptr);
}

}  // namespace
}  // namespace testing
}  // namespace grpc

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  grpc::testing::TestEnvironment env(&argc, argv);
  int ret = RUN_ALL_TESTS();
  return ret;
}
