// 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/check.h>

// This group goes first so the next group can see the needed definitions.
#include <attestation/proto_bindings/interface.pb.h>

#include <attestation-client-test/attestation/dbus-proxy-mocks.h>
#include <base/bind.h>
#include <base/optional.h>
#include <chaps/attributes.h>
#include <chaps/chaps_proxy_mock.h>
#include <crypto/scoped_openssl_types.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

#include "cert/cert_provision.pb.h"
#include "cryptohome/cert/cert_provision_keystore.h"
#include "cryptohome/cert/cert_provision_util.h"
#include "cryptohome/cert/mock_cert_provision_keystore.h"
#include "cryptohome/cert_provision.h"

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;
using ::testing::StrictMock;

namespace {

// Some arbitrary certificate label used for testing.
constexpr char kCertLabel[] = "test";
constexpr char kWrongLabel[] = "some wrong label";
constexpr char kFakeErrorMessage[] = "fake error message";
constexpr char kFakeEndorsementPublicKey[] = "fake public ek";

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 {

namespace {
class RecordingAttestationProxy : public org::chromium::AttestationProxyMock {
 public:
  struct ReplySource {
    attestation::GetEndorsementInfoReply get_endorsement_info_reply;
    attestation::GetStatusReply get_status_reply;
    attestation::EnrollReply enroll_reply;
    attestation::GetCertificateReply get_cert_reply;
    attestation::RegisterKeyWithChapsTokenReply register_key_reply;
  };
  struct ErrorSource {
    brillo::ErrorPtr get_endorsement_info_error;
    brillo::ErrorPtr get_status_error;
    brillo::ErrorPtr enroll_error;
    brillo::ErrorPtr get_cert_error;
    brillo::ErrorPtr register_key_error;
  };
  struct RequestSink {
    attestation::GetEndorsementInfoRequest get_endorsement_info_request;
    attestation::GetStatusRequest get_status_request;
    attestation::EnrollRequest enroll_request;
    attestation::GetCertificateRequest get_cert_request;
    attestation::RegisterKeyWithChapsTokenRequest register_key_request;
  };

 public:
  RecordingAttestationProxy(ReplySource* reply_source,
                            ErrorSource* error_source,
                            RequestSink* request_sink)
      : reply_source_(reply_source),
        error_source_(error_source),
        request_sink_(request_sink) {
    ON_CALL(*this, GetEndorsementInfo(_, _, _, _))
        .WillByDefault(
            Invoke(this, &RecordingAttestationProxy::HandleGetEndorsementInfo));
    ON_CALL(*this, GetStatus(_, _, _, _))
        .WillByDefault(
            Invoke(this, &RecordingAttestationProxy::HandleGetStatus));
    ON_CALL(*this, Enroll(_, _, _, _))
        .WillByDefault(Invoke(this, &RecordingAttestationProxy::HandleEnroll));
    ON_CALL(*this, GetCertificate(_, _, _, _))
        .WillByDefault(
            Invoke(this, &RecordingAttestationProxy::HandleGetCertificate));
    ON_CALL(*this, RegisterKeyWithChapsToken(_, _, _, _))
        .WillByDefault(Invoke(
            this, &RecordingAttestationProxy::HandleRegisterKeyWithChapsToken));
  }

  bool HandleGetEndorsementInfo(
      const attestation::GetEndorsementInfoRequest& request,
      attestation::GetEndorsementInfoReply* reply,
      brillo::ErrorPtr* error,
      int /*timeout_ms*/) {
    if (error_source_->get_endorsement_info_error) {
      *error = std::move(error_source_->get_endorsement_info_error);
      return false;
    }
    request_sink_->get_endorsement_info_request = request;
    *reply = reply_source_->get_endorsement_info_reply;
    return true;
  }
  bool HandleGetStatus(const attestation::GetStatusRequest& request,
                       attestation::GetStatusReply* reply,
                       brillo::ErrorPtr* error,
                       int /*timeout_ms*/) {
    if (error_source_->get_status_error) {
      *error = std::move(error_source_->get_status_error);
      return false;
    }
    request_sink_->get_status_request = request;
    *reply = reply_source_->get_status_reply;
    return true;
  }
  bool HandleEnroll(const attestation::EnrollRequest& request,
                    attestation::EnrollReply* reply,
                    brillo::ErrorPtr* error,
                    int /*timeout_ms*/) {
    if (error_source_->enroll_error) {
      *error = std::move(error_source_->enroll_error);
      return false;
    }
    request_sink_->enroll_request = request;
    *reply = reply_source_->enroll_reply;
    return true;
  }
  bool HandleGetCertificate(const attestation::GetCertificateRequest& request,
                            attestation::GetCertificateReply* reply,
                            brillo::ErrorPtr* error,
                            int /*timeout_ms*/) {
    if (error_source_->get_cert_error) {
      *error = std::move(error_source_->get_cert_error);
      return false;
    }
    request_sink_->get_cert_request = request;
    *reply = reply_source_->get_cert_reply;
    return true;
  }
  bool HandleRegisterKeyWithChapsToken(
      const attestation::RegisterKeyWithChapsTokenRequest& request,
      attestation::RegisterKeyWithChapsTokenReply* reply,
      brillo::ErrorPtr* error,
      int /*timeout_ms*/) {
    if (error_source_->register_key_error) {
      *error = std::move(error_source_->register_key_error);
      return false;
    }
    request_sink_->register_key_request = request;
    *reply = reply_source_->register_key_reply;
    return true;
  }
  ReplySource* const reply_source_;
  ErrorSource* const error_source_;
  RequestSink* const request_sink_;
};

class FakeAttestationProxyFactory : public AttestationProxyFactory {
 public:
  FakeAttestationProxyFactory() {
    ReiniailizeProxyObject();
    DeferToFake(this);
  }
  ~FakeAttestationProxyFactory() override { DeferToFake(nullptr); }
  std::unique_ptr<org::chromium::AttestationProxyInterface> CreateObject()
      override {
    AssertProxyNotTaken();
    return std::move(mock_proxy_to_transfer_);
  }
  RecordingAttestationProxy::ReplySource* get_reply_source() {
    return &reply_source_;
  }
  RecordingAttestationProxy::ErrorSource* get_error_source() {
    return &error_source_;
  }
  RecordingAttestationProxy::RequestSink* get_request_sink() {
    return &request_sink_;
  }
  RecordingAttestationProxy* get_mock_proxy() { return mock_proxy_; }
  void ReiniailizeProxyObject() {
    mock_proxy_to_transfer_ =
        std::make_unique<StrictMock<RecordingAttestationProxy>>(
            &reply_source_, &error_source_, &request_sink_);
    mock_proxy_ = mock_proxy_to_transfer_.get();
  }

 private:
  void AssertProxyNotTaken() const {
    ASSERT_NE(mock_proxy_to_transfer_.get(), nullptr);
  }
  RecordingAttestationProxy::ReplySource reply_source_;
  RecordingAttestationProxy::ErrorSource error_source_;
  RecordingAttestationProxy::RequestSink request_sink_;
  std::unique_ptr<StrictMock<RecordingAttestationProxy>>
      mock_proxy_to_transfer_;
  RecordingAttestationProxy* mock_proxy_;
};

}  // namespace

// Test class for testing top-level functions.
class CertProvisionTest : public testing::Test {
 public:
  CertProvisionTest() { KeyStore::subst_obj = &key_store_; }
  CertProvisionTest(const CertProvisionTest&) = delete;
  CertProvisionTest& operator=(const CertProvisionTest&) = delete;

  ~CertProvisionTest() { KeyStore::subst_obj = nullptr; }

  void SetUp() {
    attestation_proxy_factory_.get_reply_source()
        ->get_cert_reply.set_public_key(GetTestPublicKey().to_string());

    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());
  }

  // Perform the same thing as `Provision()` does with expectations to
  // attestation proxy, which we don't really care about if it's just in order
  // to set provision state to "provisioned". Also, at the end of the function
  // the proxy object gets reset in the factory so the test body doesn't have to
  // do it.
  void SetupProvisionState() {
    InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);
    EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
                GetStatus(_, _, _, _));
    EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
                GetCertificate(_, _, _, _));
    EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
                RegisterKeyWithChapsToken(_, _, _, _));
    // We don't share the code with `Provision()` to get better verbosity when
    // gmock reports unsatisfied expectations.
    EXPECT_EQ(Status::Success,
              ProvisionCertificate(
                  PCAType::kDefaultPCA, std::string(), kCertLabel,
                  CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
    ExpectProvisioned(true);
    EXPECT_EQ(GetTestKeyID(), provision_status_.key_id());
    attestation_proxy_factory_.ReiniailizeProxyObject();
  }

  // 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_) {
      crypto::ScopedBIGNUM e(BN_new());
      CHECK(e);
      EXPECT_TRUE(BN_set_word(e.get(), 65537));
      rsa_.reset(RSA_new());
      CHECK(rsa_);
      EXPECT_TRUE(RSA_generate_key_ex(rsa_.get(), 2048, e.get(), nullptr));
    }
    return rsa_.get();
  }
  // Resets the current test RSA key. Next time it is requested through
  // GetTestPublicKey(), a new random key will be returned.
  void ResetObtainedTestKey() { rsa_.reset(); }
  // 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()); }

  void InitializeAttestationStatus(bool is_prepared, bool is_enrolled) {
    attestation_proxy_factory_.get_reply_source()
        ->get_status_reply.set_prepared_for_enrollment(is_prepared);
    attestation_proxy_factory_.get_reply_source()
        ->get_status_reply.set_enrolled(is_enrolled);
  }

  // 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_;

  FakeAttestationProxyFactory attestation_proxy_factory_;

  NiceMock<MockKeyStore> key_store_;

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

  crypto::ScopedRSA rsa_;
};

// 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);

  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));
  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);

  // Verify if the recorded requests meet expectations.
  EXPECT_TRUE(attestation_proxy_factory_.get_request_sink()
                  ->get_cert_request.username()
                  .empty());
  EXPECT_TRUE(attestation_proxy_factory_.get_request_sink()
                  ->get_cert_request.request_origin()
                  .empty());
  EXPECT_TRUE(
      attestation_proxy_factory_.get_request_sink()->get_cert_request.forced());
  EXPECT_TRUE(attestation_proxy_factory_.get_request_sink()
                  ->get_cert_request.shall_trigger_enrollment());
  EXPECT_EQ(kCertLabel, attestation_proxy_factory_.get_request_sink()
                            ->get_cert_request.key_label());
  EXPECT_EQ(::attestation::CAST_CERTIFICATE,
            attestation_proxy_factory_.get_request_sink()
                ->get_cert_request.certificate_profile());
  EXPECT_EQ(::attestation::DEFAULT_ACA,
            attestation_proxy_factory_.get_request_sink()
                ->get_cert_request.aca_type());

  // Also, verify the right key is registered.
  EXPECT_TRUE(attestation_proxy_factory_.get_request_sink()
                  ->register_key_request.username()
                  .empty());
  EXPECT_EQ(kCertLabel, attestation_proxy_factory_.get_request_sink()
                            ->register_key_request.key_label());
}

// Checks that if enrollment is not prepared, provisioning fails.
TEST_F(CertProvisionTest, ProvisionCertificateNotPrepared) {
  ExpectProvisioned(false);

  InitializeAttestationStatus(/*is_prepared=*/false, /*is_enrolled=*/false);

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));

  EXPECT_EQ(Status::NotPrepared,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::NotPrepared));
  ExpectProvisioned(false);
}

TEST_F(CertProvisionTest, ProvisionCertificateDBusErrorGetStatus) {
  ExpectProvisioned(false);

  brillo::Error::AddTo(
      &attestation_proxy_factory_.get_error_source()->get_status_error,
      FROM_HERE, "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()
          ->get_status_error->GetMessage();

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));

  EXPECT_NE(Status::Success,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::DBusError));
  ExpectProvisioned(false);
  EXPECT_EQ(exepcted_error_message, progress_.back().message);
}

// Checks that a failure in CertRequest is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureCert) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  attestation_proxy_factory_.get_reply_source()->get_cert_reply.set_status(
      ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));

  EXPECT_NE(Status::Success,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  ExpectProvisioned(false);
}

TEST_F(CertProvisionTest, ProvisionCertificateDBusErrorCert) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  brillo::Error::AddTo(
      &attestation_proxy_factory_.get_error_source()->get_cert_error, FROM_HERE,
      "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()
          ->get_cert_error->GetMessage();
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));

  EXPECT_EQ(Status::DBusError,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::DBusError));
  ExpectProvisioned(false);
  EXPECT_EQ(exepcted_error_message, progress_.back().message);
}

// Checks that a failure when registering the keys is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateDBusErrorRegister) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  brillo::Error::AddTo(
      &attestation_proxy_factory_.get_error_source()->register_key_error,
      FROM_HERE, "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()
          ->register_key_error->GetMessage();
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  EXPECT_EQ(Status::DBusError,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::DBusError));
  ExpectProvisioned(false);
  EXPECT_EQ(exepcted_error_message, progress_.back().message);
}

TEST_F(CertProvisionTest, ProvisionCertificateFailureRegister) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  attestation_proxy_factory_.get_reply_source()->register_key_reply.set_status(
      ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  EXPECT_NE(Status::Success,
            ProvisionCertificate(
                PCAType::kDefaultPCA, std::string(), kCertLabel,
                CertificateProfile::CAST_CERTIFICATE, GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
  ExpectProvisioned(false);
}

// Checks that a failure when accessing the keystore is handled properly.
TEST_F(CertProvisionTest, ProvisionCertificateFailureKeyStore) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  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) {
  SetupProvisionState();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  attestation_proxy_factory_.get_reply_source()->get_cert_reply.set_public_key(
      GetTestPublicKey().to_string());

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  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) {
  SetupProvisionState();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  attestation_proxy_factory_.get_reply_source()->get_cert_reply.set_public_key(
      GetTestPublicKey().to_string());

  attestation_proxy_factory_.get_reply_source()->register_key_reply.set_status(
      ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  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) {
  SetupProvisionState();
  std::string old_key_id = provision_status_.key_id();
  ResetObtainedTestKey();

  attestation_proxy_factory_.get_reply_source()->get_cert_reply.set_public_key(
      GetTestPublicKey().to_string());

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));

  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];
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/false);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetCertificate(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              RegisterKeyWithChapsToken(_, _, _, _));
  attestation_proxy_factory_.get_reply_source()->get_cert_reply.set_certificate(
      cert_chain);

  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) {
  SetupProvisionState();

  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) {
  SetupProvisionState();
  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) {
  SetupProvisionState();
  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());
}

TEST_F(CertProvisionTest, ForceEnroll) {
  ExpectProvisioned(false);

  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/true);

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(), Enroll(_, _, _, _));
  EXPECT_EQ(Status::Success, ForceEnroll(PCAType::kDefaultPCA, std::string(),
                                         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);

  // Verify if the recorded requests meet expectations.
  EXPECT_TRUE(
      attestation_proxy_factory_.get_request_sink()->enroll_request.forced());
}

TEST_F(CertProvisionTest, ForceEnrollNotPrepared) {
  ExpectProvisioned(false);

  InitializeAttestationStatus(/*is_prepared=*/false, /*is_enrolled=*/false);

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));

  EXPECT_EQ(
      Status::NotPrepared,
      ForceEnroll(PCAType::kDefaultPCA, std::string(), GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::NotPrepared));
}

TEST_F(CertProvisionTest, ForceEnrollDBusErrorGetStatus) {
  ExpectProvisioned(false);

  brillo::Error::AddTo(
      &attestation_proxy_factory_.get_error_source()->get_status_error,
      FROM_HERE, "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()
          ->get_status_error->GetMessage();

  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));

  EXPECT_EQ(Status::DBusError, ForceEnroll(PCAType::kDefaultPCA, std::string(),
                                           GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::DBusError));
  EXPECT_EQ(exepcted_error_message, progress_.back().message);
}

TEST_F(CertProvisionTest, ForceEnrollFailure) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/true);

  attestation_proxy_factory_.get_reply_source()->enroll_reply.set_status(
      ::attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(), Enroll(_, _, _, _));

  EXPECT_NE(Status::Success, ForceEnroll(PCAType::kDefaultPCA, std::string(),
                                         GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsNotIn(Status::Success));
}

TEST_F(CertProvisionTest, ForceEnrollDBusError) {
  ExpectProvisioned(false);
  InitializeAttestationStatus(/*is_prepared=*/true, /*is_enrolled=*/true);

  brillo::Error::AddTo(
      &attestation_proxy_factory_.get_error_source()->enroll_error, FROM_HERE,
      "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()->enroll_error->GetMessage();
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetStatus(_, _, _, _));
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(), Enroll(_, _, _, _));

  EXPECT_EQ(Status::DBusError, ForceEnroll(PCAType::kDefaultPCA, std::string(),
                                           GetProgressCallback()));
  EXPECT_THAT(progress_, ResultsIn(Status::DBusError));
  EXPECT_EQ(exepcted_error_message, progress_.back().message);
}

TEST_F(CertProvisionTest, GetEndorsementPublicKeySuccess) {
  attestation_proxy_factory_.get_reply_source()
      ->get_endorsement_info_reply.set_ek_public_key(kFakeEndorsementPublicKey);
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetEndorsementInfo(_, _, _, _));
  std::string endorsment_public_key;
  EXPECT_EQ(Status::Success, GetEndorsementPublicKey(&endorsment_public_key));
  EXPECT_EQ(endorsment_public_key, kFakeEndorsementPublicKey);
}

TEST_F(CertProvisionTest, GetEndorsementPublicKeyDBusError) {
  brillo::Error::AddTo(&attestation_proxy_factory_.get_error_source()
                            ->get_endorsement_info_error,
                       FROM_HERE, "", "", kFakeErrorMessage);
  const std::string exepcted_error_message =
      attestation_proxy_factory_.get_error_source()
          ->get_endorsement_info_error->GetMessage();
  EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
              GetEndorsementInfo(_, _, _, _));
  std::string endorsment_public_key;
  EXPECT_NE(Status::Success, GetEndorsementPublicKey(&endorsment_public_key));
}

}  // namespace cert_provision
