// Copyright 2017 The Chromium OS 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 <string>
#include <tuple>
#include <vector>

#include <base/bind.h>
#include <chaps/attributes.h>
#include <chaps/chaps_proxy_mock.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

#include "cryptohome/cert_provision.h"
#include "cryptohome/cert_provision_cryptohome.h"
#include "cryptohome/cert_provision_keystore.h"
#include "cryptohome/cert_provision_pca.h"
#include "cryptohome/cert_provision_util.h"

#include "cryptohome/mock_cert_provision_cryptohome.h"
#include "cryptohome/mock_cert_provision_keystore.h"
#include "cryptohome/mock_cert_provision_pca.h"

#include "cert_provision.pb.h"  // NOLINT(build/include)

using ::brillo::SecureBlob;
using ::google::protobuf::MessageLite;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;

namespace {

// Some arbitrary certificate label used for testing.
const char kCertLabel[] = "test";
const char kWrongLabel[] = "some wrong label";

const char kBegCertificate[] = "-----BEGIN CERTIFICATE-----";
const char kEndCertificate[] = "-----END CERTIFICATE-----";

// Format for storing captured progress by the callback.
struct Progress {
  cert_provision::Status status;
  int progress;
  std::string message;
};

// Matchers for the captured progress vector.
MATCHER_P(ResultsIn, status, "") {
  return arg.back().status == status && arg.back().progress == 100;
}
MATCHER_P(ResultsNotIn, status, "") {
  return arg.back().status != status && arg.back().progress == 100;
}

}  // namespace

namespace cert_provision {

// Test class for testing top-level functions.
class CertProvisionTest : public testing::Test {
 public:
  CertProvisionTest() {
    CryptohomeProxy::subst_obj = &c_proxy_;
    PCAProxy::subst_obj = &pca_proxy_;
    KeyStore::subst_obj = &key_store_;
  }
  ~CertProvisionTest() {
    CryptohomeProxy::subst_obj = nullptr;
    PCAProxy::subst_obj = nullptr;
    KeyStore::subst_obj = nullptr;
    if (rsa_) {
      RSA_free(rsa_);
    }
  }

  void SetUp() {
    ON_CALL(c_proxy_, Init())
        .WillByDefault(Return(OpResult()));
    ON_CALL(c_proxy_, CheckIfPrepared(_))
        .WillByDefault(Invoke([this](bool* prepared) {
          *prepared = prepared_;
          return OpResult();
        }));
    ON_CALL(c_proxy_, CheckIfEnrolled(_))
        .WillByDefault(Invoke([this](bool* enrolled) {
          *enrolled = enrolled_;
          return OpResult();
        }));
    ON_CALL(c_proxy_, CreateEnrollRequest(_, _))
        .WillByDefault(Return(OpResult()));
    ON_CALL(c_proxy_, ProcessEnrollResponse(_, _))
        .WillByDefault(Return(OpResult()));
    ON_CALL(c_proxy_, CreateCertRequest(_, _, _))
        .WillByDefault(Return(OpResult()));
    ON_CALL(c_proxy_, ProcessCertResponse(_, _, _))
        .WillByDefault(Return(OpResult()));
    ON_CALL(c_proxy_, GetPublicKey(_, _))
        .WillByDefault(
            Invoke([this](const std::string& /* label */, SecureBlob* key) {
              *key = GetTestPublicKey();
              return OpResult();
            }));
    ON_CALL(c_proxy_, Register(_))
        .WillByDefault(Return(OpResult()));

    ON_CALL(pca_proxy_, MakeRequest(_, _, _))
        .WillByDefault(Return(OpResult()));

    ON_CALL(key_store_, Init())
        .WillByDefault(Return(OpResult()));
    ON_CALL(key_store_, Sign(_, _, _, _, _))
        .WillByDefault(Return(OpResult()));
    ON_CALL(key_store_, ReadProvisionStatus(_, _))
        .WillByDefault(Invoke([this](const std::string& /* label */,
                                     MessageLite* proto) {
          proto->ParseFromString(provision_status_.SerializeAsString());
          return OpResult();
        }));
    ON_CALL(key_store_, WriteProvisionStatus(_, _))
        .WillByDefault(Invoke([this](const std::string& /* label */,
                                     const MessageLite& proto) {
          provision_status_.ParseFromString(proto.SerializeAsString());
          return OpResult();
        }));
    ON_CALL(key_store_, DeleteKeys(_, _))
        .WillByDefault(Return(OpResult()));
  }

  OpResult TestError(Status status) {
    return {status, "Test error"};
  }

  // Resets the captured progress and returns the progress callback to
  // be passed to ProvisionCertificate() for capturing new progress.
  ProgressCallback GetProgressCallback() {
    progress_.clear();
    return base::Bind(&CertProvisionTest::CaptureProgress,
                      base::Unretained(this));
  }

  // Successfully provisions and checks results/
  void Provision() {
    EXPECT_EQ(Status::Success,
              ProvisionCertificate(PCAType::kDefaultPCA,
                                   std::string(),
                                   kCertLabel,
                                   CertificateProfile::CAST_CERTIFICATE,
                                   GetProgressCallback()));
    ExpectProvisioned(true);
    EXPECT_EQ(GetTestKeyID(), provision_status_.key_id());
  }

  // Verifies that a cert is provisioned/not provisioned.
  // Does so by checking the stored ProvisionStatus and the result of
  // GetCertificate().
  void ExpectProvisioned(bool provisioned) {
    EXPECT_EQ(provisioned, provision_status_.provisioned());
    std::string certificate;
    EXPECT_EQ(provisioned ? Status::Success : Status::NotProvisioned,
              GetCertificate(kCertLabel, true, &certificate));
  }

 protected:
  // Returns the current test RSA key. Generates a new random one, if empty.
  RSA* rsa() {
    if (!rsa_) {
      rsa_ = RSA_generate_key(2048, 65537, nullptr, nullptr);
      CHECK(rsa_);
    }
    return rsa_;
  }
  // Resets the current test RSA key. Next time it is requested through
  // GetTestPublicKey(), a new random key will be returned.
  void ResetObtainedTestKey() {
    if (rsa_) {
      RSA_free(rsa_);
      rsa_ = nullptr;
    }
  }
  // Returns the current test public key in X.509 format.
  SecureBlob GetTestPublicKey() {
    unsigned char* buffer = nullptr;
    int length = i2d_RSA_PUBKEY(rsa(), &buffer);
    if (length <= 0)
      return SecureBlob();
    SecureBlob tmp(buffer, buffer + length);
    OPENSSL_free(buffer);
    return tmp;
  }
  // Calculates the id for the current test public key.
  std::string GetTestKeyID() {
    return GetKeyID(GetTestPublicKey());
  }

  // Captures progress reported through callback.
  std::vector<Progress> progress_;

  // IsPreparedForEnrollment and IsEnrolled status.
  bool prepared_ = true;
  bool enrolled_ = false;

  // Emulated storage for ProvisionStatus in keystore.
  ProvisionStatus provision_status_;

  NiceMock<MockCryptohomeProxy> c_proxy_;
  NiceMock<MockPCAProxy> pca_proxy_;
  NiceMock<MockKeyStore> key_store_;

 private:
  void CaptureProgress(Status status,
                       int progress,
                       const std::string& message) {
    progress_.push_back({status, progress, message});
  }

  RSA* rsa_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(CertProvisionTest);
};

// Checks that provisioning succeeds after sending EnrollRequest if not
// enrolled yet. Checks that the reported progress is not decreasing and
// ends with 100%, and success is reported to the callback on all steps.
TEST_F(CertProvisionTest, ProvisionCertificateSuccessEnroll) {
  ExpectProvisioned(false);
  prepared_ = true;
  enrolled_ = false;
  EXPECT_CALL(c_proxy_, CreateEnrollRequest(_, _));
  EXPECT_CALL(c_proxy_, ProcessEnrollResponse(_, _));
  EXPECT_CALL(pca_proxy_, MakeRequest(_, _, _)).Times(2);
  EXPECT_EQ(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  int last_progress = 0;
  for (auto p : progress_) {
    EXPECT_EQ(Status::Success, p.status);
    EXPECT_LE(last_progress, p.progress);
    last_progress = p.progress;
  }
  EXPECT_EQ(100, last_progress);
  ExpectProvisioned(true);
}

// Checks that provisioning succeeds w/o sending EnrollRequest if already
// enrolled. Checks that the reported progress is not decreasing and
// ends with 100%, and success is reported to the callback on all steps.
TEST_F(CertProvisionTest, ProvisionCertificateSuccessAlreadyEnrolled) {
  ExpectProvisioned(false);
  prepared_ = true;
  enrolled_ = true;
  EXPECT_CALL(c_proxy_, CreateEnrollRequest(_, _)).Times(0);
  EXPECT_CALL(c_proxy_, ProcessEnrollResponse(_, _)).Times(0);
  EXPECT_CALL(pca_proxy_, MakeRequest(_, _, _)).Times(1);
  EXPECT_EQ(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  int last_progress = 0;
  for (auto p : progress_) {
    EXPECT_EQ(Status::Success, p.status);
    EXPECT_LE(last_progress, p.progress);
    last_progress = p.progress;
  }
  EXPECT_EQ(100, last_progress);
  ExpectProvisioned(true);
}

// Checks that if enrollment is not prepared, provisioning fails.
TEST_F(CertProvisionTest, ProvisionCertificateNotPrepared) {
  ExpectProvisioned(false);
  prepared_ = false;
  EXPECT_EQ(Status::NotPrepared,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::NotPrepared));
  ExpectProvisioned(false);
}

// Checks that a failure in EnrollRequest is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureEnroll) {
  ExpectProvisioned(false);
  enrolled_ = false;
  EXPECT_CALL(c_proxy_, ProcessEnrollResponse(_, _))
      .WillOnce(Return(TestError(Status::CryptohomeError)));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  EXPECT_EQ("Test error", progress_.back().message);
  ExpectProvisioned(false);
}

// Checks that a failure in CertRequest is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureCert) {
  ExpectProvisioned(false);
  EXPECT_CALL(c_proxy_, ProcessCertResponse(kCertLabel, _, _))
      .WillOnce(Return(TestError(Status::CryptohomeError)));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  EXPECT_EQ("Test error", progress_.back().message);
  ExpectProvisioned(false);
}

// Checks that a failure to access PCA is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailurePCA) {
  ExpectProvisioned(false);
  EXPECT_CALL(pca_proxy_, MakeRequest(_, _, _))
      .WillOnce(Return(TestError(Status::ServerError)));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  EXPECT_EQ("Test error", progress_.back().message);
  ExpectProvisioned(false);
}

// Checks that a failure when registering the keys is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureRegister) {
  ExpectProvisioned(false);
  EXPECT_CALL(c_proxy_, Register(kCertLabel))
      .WillOnce(Return(TestError(Status::CryptohomeError)));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  EXPECT_EQ("Test error", progress_.back().message);
  ExpectProvisioned(false);
}

// Checks that a failure when accessing the keystore is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureKeyStore) {
  ExpectProvisioned(false);
  EXPECT_CALL(key_store_, Init())
      .WillOnce(Return(TestError(Status::KeyStoreError)))
      .WillRepeatedly(Return(OpResult()));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  EXPECT_EQ("Test error", progress_.back().message);
  ExpectProvisioned(false);
}

// Checks that re-provisioning the certificate deletes the old keys and
// replaces the cert with the new one.
TEST_F(CertProvisionTest, ReProvisionCertificateSuccess) {
  Provision();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  EXPECT_CALL(key_store_, DeleteKeys(old_key_id, kCertLabel));
  Provision();
  EXPECT_NE(old_key_id, provision_status_.key_id());
}

// Checks that registration failure upon re-provisioning keeps the old cert
// in place.
TEST_F(CertProvisionTest, ReProvisionCertificateFailureRegister) {
  Provision();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  EXPECT_CALL(c_proxy_, Register(kCertLabel))
      .WillOnce(Return(TestError(Status::CryptohomeError)));
  EXPECT_CALL(key_store_, DeleteKeys(_, _)).Times(0);
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  ExpectProvisioned(true);
  EXPECT_EQ(old_key_id, provision_status_.key_id());
}

// Checks that a failure when deleting the old keys is reported even
// though the new cert is stored. Checks that the new cert is usable,
// if the old keys were not deleted.
TEST_F(CertProvisionTest, ReProvisionCertificateFailureDeleteKeys) {
  Provision();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  EXPECT_CALL(key_store_, DeleteKeys(old_key_id, kCertLabel))
      .WillOnce(Return(TestError(Status::KeyStoreError)));
  EXPECT_NE(Status::Success,
            ProvisionCertificate(PCAType::kDefaultPCA,
                                 std::string(),
                                 kCertLabel,
                                 CertificateProfile::CAST_CERTIFICATE,
                                 GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  ExpectProvisioned(true);
  EXPECT_NE(old_key_id, provision_status_.key_id());
}

// Checks that GetCertificate returns the provisioned certificate.
TEST_F(CertProvisionTest, GetCertificateSuccess) {
  std::string cert[] = {
      std::string(kBegCertificate) + "first" + kEndCertificate,
      std::string(kBegCertificate) + "second" + kEndCertificate};
  std::string cert_chain = cert[0] + cert[1];
  SecureBlob cert_chain_blob(cert_chain);
  EXPECT_CALL(c_proxy_, ProcessCertResponse(kCertLabel, _, _))
      .WillOnce(
          DoAll(SetArgPointee<2>(cert_chain_blob), Return(OpResult())));
  Provision();
  std::string result_cert;
  EXPECT_EQ(Status::Success, GetCertificate(kCertLabel, true, &result_cert));
  EXPECT_EQ(cert_chain, result_cert);
  EXPECT_EQ(Status::Success, GetCertificate(kCertLabel, false, &result_cert));
  EXPECT_EQ(cert[0], result_cert);
}

// Checks that getting a certificate if it is not provisioned returns an
// error.
TEST_F(CertProvisionTest, GetCertificateNotProvisioned) {
  ExpectProvisioned(false);
  std::string certificate;
  EXPECT_EQ(Status::NotProvisioned,
            GetCertificate(kCertLabel, true, &certificate));
  EXPECT_TRUE(certificate.empty());
}

// Checks that signing succeeds and returns the requested data.
TEST_F(CertProvisionTest, SignSuccess) {
  Provision();

  std::string data = "some data";
  std::string keystore_sig("signature");

  std::string sig;
  EXPECT_CALL(key_store_,
              Sign(GetTestKeyID(), kCertLabel, SHA1_RSA_PKCS, _, _))
      .WillOnce(DoAll(SetArgPointee<4>(keystore_sig), Return(OpResult())));
  EXPECT_EQ(Status::Success, Sign(kCertLabel, SHA1_RSA_PKCS, data, &sig));
  EXPECT_EQ("signature", sig);

  sig.clear();
  EXPECT_CALL(key_store_,
              Sign(GetTestKeyID(), kCertLabel, SHA256_RSA_PKCS, _, _))
      .WillOnce(DoAll(SetArgPointee<4>(keystore_sig), Return(OpResult())));
  EXPECT_EQ(Status::Success, Sign(kCertLabel, SHA256_RSA_PKCS, data, &sig));
  EXPECT_EQ("signature", sig);
}

// Checks that signing fails if there is no provisioned certificate.
TEST_F(CertProvisionTest, SignNotProvisioned) {
  ExpectProvisioned(false);
  std::string data = "some data";
  std::string sig;
  EXPECT_EQ(Status::NotProvisioned,
            Sign(kCertLabel, SHA1_RSA_PKCS, data, &sig));
  EXPECT_TRUE(sig.empty());
}

// Checks that signing fails if keystore Sign operation fails.
TEST_F(CertProvisionTest, SignFailure) {
  Provision();
  std::string data = "some data";
  std::string sig;
  EXPECT_CALL(key_store_, Sign(GetTestKeyID(), kCertLabel, SHA1_RSA_PKCS, _, _))
      .WillOnce(Return(TestError(Status::KeyStoreError)));
  EXPECT_NE(Status::Success, Sign(kCertLabel, SHA1_RSA_PKCS, data, &sig));
  EXPECT_TRUE(sig.empty());
}

// Checks that if a cert is provisioned for one label, it doesn't affect
// other labels.
TEST_F(CertProvisionTest, WrongLabel) {
  Provision();
  EXPECT_CALL(key_store_, ReadProvisionStatus(kWrongLabel, _))
      .WillRepeatedly(Return(OpResult()));
  EXPECT_CALL(key_store_, ReadProvisionStatus(kCertLabel, _)).Times(0);
  std::string certificate;
  EXPECT_EQ(Status::NotProvisioned,
            GetCertificate(kWrongLabel, true, &certificate));
  EXPECT_TRUE(certificate.empty());
  std::string data = "some data";
  std::string sig;
  EXPECT_EQ(Status::NotProvisioned,
            Sign(kWrongLabel, SHA1_RSA_PKCS, data, &sig));
  EXPECT_TRUE(sig.empty());
}

}  // namespace cert_provision
