// Copyright 2015 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 <attestation/proto_bindings/attestation_ca.pb.h>
#include <attestation/proto_bindings/pca_agent.pb.h>
#include <base/bind.h>
#include <base/callback.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/run_loop.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/synchronization/waitable_event.h>
#include <base/test/task_environment.h>
#include <brillo/data_encoding.h>
#include <brillo/errors/error.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <policy/mock_device_policy.h>
#include <policy/mock_libpolicy.h>
#if USE_TPM2
#include <trunks/tpm_utility.h>
#endif
#if USE_TPM2
extern "C" {
#include <trunks/cr50_headers/virtual_nvmem.h>
}
#endif

#include "attestation/common/mock_crypto_utility.h"
#include "attestation/common/mock_tpm_utility.h"
#include "attestation/pca_agent/client/fake_pca_agent_proxy.h"
#include "attestation/server/attestation_service.h"
#include "attestation/server/google_keys.h"
#include "attestation/server/mock_database.h"
#include "attestation/server/mock_key_store.h"

using testing::_;
using testing::AtMost;
using testing::DoAll;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::WithArgs;

namespace attestation {

namespace {

#if USE_TPM2
constexpr TpmVersion kTpmVersionUnderTest = TPM_2_0;
#else
constexpr TpmVersion kTpmVersionUnderTest = TPM_1_2;
#endif

std::string CreateChallenge(const std::string& prefix) {
  Challenge challenge;
  challenge.set_prefix(prefix);
  challenge.set_nonce("nonce");
  challenge.set_timestamp(100500);
  std::string serialized;
  challenge.SerializeToString(&serialized);
  return serialized;
}

std::string CreateSignedChallenge(const std::string& prefix) {
  SignedData signed_data;
  signed_data.set_data(CreateChallenge(prefix));
  signed_data.set_signature("challenge_signature");
  std::string serialized;
  signed_data.SerializeToString(&serialized);
  return serialized;
}

EncryptedData MockEncryptedData(std::string data) {
  EncryptedData encrypted_data;
  encrypted_data.set_wrapped_key("wrapped_key");
  encrypted_data.set_iv("iv");
  encrypted_data.set_mac("mac");
  encrypted_data.set_encrypted_data(data);
  encrypted_data.set_wrapping_key_id("wrapping_key_id");
  return encrypted_data;
}

KeyInfo CreateChallengeKeyInfo() {
  KeyInfo key_info;
  key_info.set_key_type(EUK);
  key_info.set_domain("domain");
  key_info.set_device_id("device_id");
  key_info.set_certificate("");
  return key_info;
}

KeyInfo CreateMachineChallengeKeyInfoWithSPKAC(
    const std::string& certified_credential_of_key_for_spkac,
    const std::string& spkac) {
  // Create a PEM encoding of |certified_credential_of_key_for_spkac|.
  std::string pem_certificate_of_key_for_spkac =
      "-----BEGIN CERTIFICATE-----\n" +
      brillo::data_encoding::Base64EncodeWrapLines(
          certified_credential_of_key_for_spkac) +
      "-----END CERTIFICATE-----";

  KeyInfo key_info;
  key_info.set_key_type(EMK);
  key_info.set_customer_id("customer_id");
  key_info.set_device_id("device_id");
  key_info.set_certificate(pem_certificate_of_key_for_spkac);
  key_info.set_signed_public_key_and_challenge(spkac);
  return key_info;
}

std::string GetFakeCertificateChain() {
  const std::string kBeginCertificate = "-----BEGIN CERTIFICATE-----\n";
  const std::string kEndCertificate = "-----END CERTIFICATE-----";
  std::string pem = kBeginCertificate;
  pem += brillo::data_encoding::Base64EncodeWrapLines("fake_cert");
  pem += kEndCertificate + "\n" + kBeginCertificate;
  pem += brillo::data_encoding::Base64EncodeWrapLines("fake_ca_cert");
  pem += kEndCertificate + "\n" + kBeginCertificate;
  pem += brillo::data_encoding::Base64EncodeWrapLines("fake_ca_cert2");
  pem += kEndCertificate;
  return pem;
}

// testing::InvokeArgument<N> does not work with base::Callback, need to use
// |ACTION_TAMPLATE| along with predefined |args| tuple.
ACTION_TEMPLATE(InvokeCallbackArgument,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(p0)) {
  std::get<k>(args).Run(p0);
}

}  // namespace

class AttestationServiceBaseTest : public testing::Test {
 public:
  ~AttestationServiceBaseTest() override = default;

  void SetUp() override {
    service_.reset(new AttestationService(nullptr));
    service_->set_database(&mock_database_);
    service_->set_crypto_utility(&mock_crypto_utility_);
    service_->set_key_store(&mock_key_store_);
    service_->set_tpm_utility(&mock_tpm_utility_);
    service_->set_hwid("fake_hwid");
    service_->set_pca_agent_proxy(&fake_pca_agent_proxy_);
    mock_policy_provider_ = new StrictMock<policy::MockPolicyProvider>();
    service_->set_policy_provider(mock_policy_provider_);
    // Setup a fake wrapped EK certificate by default.
    (*mock_database_.GetMutableProtobuf()
          ->mutable_credentials()
          ->mutable_encrypted_endorsement_credentials())[DEFAULT_ACA]
        .set_wrapping_key_id("default");
    (*mock_database_.GetMutableProtobuf()
          ->mutable_credentials()
          ->mutable_encrypted_endorsement_credentials())[TEST_ACA]
        .set_wrapping_key_id("test");
    EXPECT_CALL(mock_tpm_utility_, IsPCR0Valid()).WillRepeatedly(Return(true));
    // Run out initialize task(s) to avoid any race conditions with tests that
    // need to change the default setup.
    CHECK(
        CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  }

 protected:
  void Run() { run_loop_.Run(); }

  void RunUntilIdle() { run_loop_.RunUntilIdle(); }

  void Quit() { run_loop_.Quit(); }

  base::Closure QuitClosure() { return run_loop_.QuitClosure(); }

  template <typename T>
  T CallAndWait(
      base::OnceCallback<T(AttestationService::InitializeCompleteCallback)>
          func) {
    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                             base::WaitableEvent::InitialState::NOT_SIGNALED);
    T val = std::move(func).Run(
        base::BindOnce([](base::WaitableEvent* done, bool) { done->Signal(); },
                       base::Unretained(&done)));
    done.Wait();
    return val;
  }

  void SetUpIdentity(int identity) {
    auto* database = mock_database_.GetMutableProtobuf();
    AttestationDatabase::Identity* identity_data;
    if (database->identities().size() > identity) {
      identity_data = database->mutable_identities()->Mutable(identity);
    } else {
      for (int i = database->identities().size(); i <= identity; ++i) {
        identity_data = database->mutable_identities()->Add();
      }
    }
    identity_data->set_features(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID);
    identity_data->mutable_identity_key()->set_identity_public_key_der(
        "public_key");
    identity_data->mutable_identity_binding()
        ->set_identity_public_key_tpm_format("public_key_tpm");
    (*identity_data->mutable_pcr_quotes())[0].set_quote("pcr0");
    (*identity_data->mutable_pcr_quotes())[1].set_quote("pcr1");
#if USE_TPM2
    (*identity_data->mutable_nvram_quotes())[BOARD_ID].set_quote("board_id");
    (*identity_data->mutable_nvram_quotes())[SN_BITS].set_quote("sn_bits");
    if (service_->GetEndorsementKeyType() != KEY_TYPE_RSA) {
      (*identity_data->mutable_nvram_quotes())[RSA_PUB_EK_CERT].set_quote(
          "rsa_pub_ek_cert");
    }
#endif
  }

  // Generate a unique name for a certificate from an ACA.
  std::string GetCertificateName(int identity, ACAType aca_type) {
    std::ostringstream stream;
    stream << "certificate(" << identity << ", " << aca_type << ")";
    return stream.str();
  }

  // Create an identity certificate if needed and sets an ACA-signed
  // certificate. Once this exists, we consider that the identity has been
  // enrolled with the given ACA.
  void SetUpIdentityCertificate(int identity, ACAType aca_type) {
    auto identity_certificate = service_->FindOrCreateIdentityCertificate(
        identity, aca_type, nullptr /* cert_index */);
    EXPECT_NE(nullptr, identity_certificate);
    identity_certificate->set_identity_credential(
        GetCertificateName(identity, aca_type));
  }

  CertifiedKey GenerateFakeCertifiedKey() const {
    CertifiedKey key;
    key.set_public_key("public_key");
    key.set_certified_key_credential("fake_cert");
    key.set_intermediate_ca_cert("fake_ca_cert");
    *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
    key.set_key_name("label");
    key.set_certified_key_info("certify_info");
    key.set_certified_key_proof("signature");
    key.set_key_type(KEY_TYPE_RSA);
    key.set_key_usage(KEY_USAGE_SIGN);
    return key;
  }

  std::string GenerateSerializedFakeCertifiedKey() const {
    CertifiedKey key = GenerateFakeCertifiedKey();
    return key.SerializeAsString();
  }

  void ExpectGetCustomerId(std::string customer_id) {
    EXPECT_CALL(*mock_policy_provider_, Reload()).WillOnce(Return(true));
    EXPECT_CALL(*mock_policy_provider_, device_policy_is_loaded())
        .WillOnce(Return(true));
    EXPECT_CALL(*mock_policy_provider_, GetDevicePolicy())
        .WillOnce(ReturnRef(mock_device_policy_));
    EXPECT_CALL(mock_device_policy_, GetCustomerId(_))
        .WillOnce(DoAll(SetArgPointee<0>(customer_id), Return(true)));
  }

  // Verify Attestation CA-related data, including the default CA's identity
  // credential.
  void VerifyACAData(const AttestationDatabase& db,
                     const char* default_identity_credential) {
    ASSERT_EQ(default_identity_credential ? 1 : 0,
              db.identity_certificates().size());
    for (int aca = 0; aca < db.identity_certificates().size(); ++aca) {
      const AttestationDatabase::IdentityCertificate identity_certificate =
          db.identity_certificates().at(aca);
      ASSERT_EQ(0, identity_certificate.identity());
      ASSERT_EQ(aca, identity_certificate.aca());
      if (default_identity_credential && aca == DEFAULT_ACA) {
        ASSERT_EQ(default_identity_credential,
                  identity_certificate.identity_credential());
      } else {
        ASSERT_FALSE(identity_certificate.has_identity_credential());
      }
    }
    // All ACAs have encrypted credentials.
    for (int aca = AttestationService::kDefaultACA;
         aca < AttestationService::kMaxACATypeInternal; ++aca) {
      AttestationService::ACATypeInternal aca_int =
          static_cast<AttestationService::ACATypeInternal>(aca);
      ASSERT_TRUE(db.credentials().encrypted_endorsement_credentials().count(
          AttestationService::GetACAType(aca_int)));
    }
  }

  // Verify Attestation CA-related data, including the lack of default CA's
  // identity credential.
  void VerifyACAData(const AttestationDatabase& db) {
    VerifyACAData(db, nullptr);
  }

  std::string ComputeEnterpriseEnrollmentId() {
    return service_->ComputeEnterpriseEnrollmentId();
  }

  std::string GetEnrollmentId() {
    GetEnrollmentIdRequest request;
    auto result = std::make_shared<GetEnrollmentIdReply>();
    service_->GetEnrollmentIdTask(request, result);
    if (result->status() != STATUS_SUCCESS) {
      return "";
    }

    return result->enrollment_id();
  }

  NiceMock<MockCryptoUtility> mock_crypto_utility_;
  NiceMock<MockDatabase> mock_database_;
  NiceMock<MockKeyStore> mock_key_store_;
  NiceMock<MockTpmUtility> mock_tpm_utility_;
  StrictMock<policy::MockPolicyProvider>* mock_policy_provider_;  // Not Owned.
  StrictMock<policy::MockDevicePolicy> mock_device_policy_;
  StrictMock<pca_agent::client::FakePcaAgentProxy> fake_pca_agent_proxy_{
      kTpmVersionUnderTest};
  std::unique_ptr<AttestationService> service_;
  const int identity_ = AttestationService::kFirstIdentity;

 private:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
  base::RunLoop run_loop_;
};

TEST_F(AttestationServiceBaseTest, MigrateAttestationDatabase) {
  // Simulate an older database.
  auto* db = mock_database_.GetMutableProtobuf();
  db->mutable_credentials()->clear_encrypted_endorsement_credentials();
  db->mutable_credentials()->set_endorsement_credential("endorsement_cred");
  EncryptedData default_encrypted_endorsement_credential;
  default_encrypted_endorsement_credential.set_wrapped_key("default_key");
  db->mutable_credentials()
      ->mutable_default_encrypted_endorsement_credential()
      ->CopyFrom(default_encrypted_endorsement_credential);
  db->clear_identities();
  db->clear_identity_certificates();
  db->mutable_identity_binding()->set_identity_binding("identity_binding");
  db->mutable_identity_binding()->set_identity_public_key_tpm_format(
      "identity_public_key");
  db->mutable_identity_key()->set_identity_credential("identity_cred");
  db->mutable_pcr0_quote()->set_quote("pcr0_quote");
  db->mutable_pcr1_quote()->set_quote("pcr1_quote");
  // Persist that older database.
  mock_database_.SaveChanges();

  // Simulate login.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  service_->PrepareForEnrollment(base::DoNothing());

  const auto& const_db = mock_database_.GetProtobuf();
  // The default encrypted endorsement credential has been migrated.
  // The deprecated field has not been cleared so that older code can still
  // use the database.
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .encrypted_endorsement_credentials()
                .at(DEFAULT_ACA)
                .wrapped_key());
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .default_encrypted_endorsement_credential()
                .wrapped_key());

  // The default identity has data copied from the deprecated database fields.
  // The deprecated fields have not been cleared so that older code can still
  // use the database.
  const AttestationDatabase::Identity& default_identity_data =
      const_db.identities().Get(DEFAULT_ACA);
  EXPECT_EQ(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            default_identity_data.features());
  EXPECT_EQ("identity_binding",
            default_identity_data.identity_binding().identity_binding());
  EXPECT_EQ("identity_public_key", default_identity_data.identity_binding()
                                       .identity_public_key_tpm_format());
  EXPECT_EQ("identity_binding", const_db.identity_binding().identity_binding());
  EXPECT_EQ("identity_public_key",
            const_db.identity_binding().identity_public_key_tpm_format());
  EXPECT_EQ("pcr0_quote", default_identity_data.pcr_quotes().at(0).quote());
  EXPECT_EQ("pcr0_quote", const_db.pcr0_quote().quote());
  EXPECT_EQ("pcr1_quote", default_identity_data.pcr_quotes().at(1).quote());
  EXPECT_EQ("pcr1_quote", const_db.pcr1_quote().quote());

  // No other identity has been created.
  EXPECT_EQ(1, const_db.identities().size());

  // The identity credential was migrated into an identity certificate.
  // As a result, identity data does not use the identity credential. The
  // deprecated field has not been cleared so that older code can still
  // use the database.
  EXPECT_FALSE(default_identity_data.identity_key().has_identity_credential());
  EXPECT_EQ("identity_cred", const_db.identity_key().identity_credential());
  VerifyACAData(const_db, "identity_cred");
}

TEST_F(AttestationServiceBaseTest,
       MigrateAttestationDatabaseWithCorruptedFields) {
  // Simulate an older database.
  auto* db = mock_database_.GetMutableProtobuf();
  db->mutable_credentials()->clear_encrypted_endorsement_credentials();
  db->mutable_credentials()->set_endorsement_credential("endorsement_cred");
  EncryptedData default_encrypted_endorsement_credential;
  default_encrypted_endorsement_credential.set_wrapped_key("default_key");
  db->mutable_credentials()
      ->mutable_default_encrypted_endorsement_credential()
      ->CopyFrom(default_encrypted_endorsement_credential);
  db->clear_identities();
  db->clear_identity_certificates();
  db->mutable_identity_binding()->set_identity_binding("identity_binding");
  db->mutable_identity_binding()->set_identity_public_key_tpm_format(
      "identity_public_key");
  db->mutable_identity_key()->set_identity_credential("identity_cred");
  // Note that we are missing a PCR0 quote.
  db->mutable_pcr1_quote()->set_quote("pcr1_quote");
  // Persist that older database.
  mock_database_.SaveChanges();

  // Simulate login.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  service_->PrepareForEnrollment(base::DoNothing());

  const auto& const_db = mock_database_.GetProtobuf();
  // The default encrypted endorsement credential has been migrated.
  // The deprecated field has not been cleared so that older code can still
  // use the database.
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .encrypted_endorsement_credentials()
                .at(DEFAULT_ACA)
                .wrapped_key());
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .default_encrypted_endorsement_credential()
                .wrapped_key());

  // The default identity could not be copied from the deprecated database.
  // The deprecated fields have not been cleared so that older code can still
  // use the database.
  ASSERT_TRUE(const_db.identities().empty());
  ASSERT_EQ("identity_binding", const_db.identity_binding().identity_binding());
  ASSERT_EQ("identity_public_key",
            const_db.identity_binding().identity_public_key_tpm_format());
  EXPECT_EQ("pcr1_quote", const_db.pcr1_quote().quote());

  // There is no identity certificate since there is no identity.
  ASSERT_TRUE(const_db.identity_certificates().empty());
}

TEST_F(AttestationServiceBaseTest,
       MigrateAttestationDatabaseAllEndorsementCredentials) {
  // Simulate an older database.
  auto* db = mock_database_.GetMutableProtobuf();
  db->mutable_credentials()->clear_encrypted_endorsement_credentials();
  db->mutable_credentials()->set_endorsement_credential("endorsement_cred");
  EncryptedData default_encrypted_endorsement_credential;
  default_encrypted_endorsement_credential.set_wrapped_key("default_key");
  db->mutable_credentials()
      ->mutable_default_encrypted_endorsement_credential()
      ->CopyFrom(default_encrypted_endorsement_credential);
  EncryptedData test_encrypted_endorsement_credential;
  test_encrypted_endorsement_credential.set_wrapped_key("test_key");
  db->mutable_credentials()
      ->mutable_test_encrypted_endorsement_credential()
      ->CopyFrom(test_encrypted_endorsement_credential);
  db->clear_identities();
  db->clear_identity_certificates();
  db->mutable_identity_binding()->set_identity_binding("identity_binding");
  db->mutable_identity_binding()->set_identity_public_key_tpm_format(
      "identity_public_key");
  db->mutable_identity_key()->set_identity_credential("identity_cred");
  db->mutable_pcr0_quote()->set_quote("pcr0_quote");
  db->mutable_pcr1_quote()->set_quote("pcr1_quote");
  // Persist that older database.
  mock_database_.SaveChanges();

  // Simulate second login.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  service_->PrepareForEnrollment(base::DoNothing());

  const auto& const_db = mock_database_.GetProtobuf();
  // The encrypted endorsement credentials have both been migrated.
  // The deprecated fields have not been cleared so that older code can still
  // use the database.
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .encrypted_endorsement_credentials()
                .at(DEFAULT_ACA)
                .wrapped_key());
  EXPECT_EQ(default_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .default_encrypted_endorsement_credential()
                .wrapped_key());
  EXPECT_EQ(test_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .encrypted_endorsement_credentials()
                .at(TEST_ACA)
                .wrapped_key());
  EXPECT_EQ(test_encrypted_endorsement_credential.wrapped_key(),
            const_db.credentials()
                .test_encrypted_endorsement_credential()
                .wrapped_key());
}

TEST_F(AttestationServiceBaseTest, GetEndorsementInfoNoInfo) {
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementPublicKey(_, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetEndorsementInfoReply& reply) {
    EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status());
    EXPECT_FALSE(reply.has_ek_public_key());
    EXPECT_FALSE(reply.has_ek_certificate());
    quit_closure.Run();
  };
  GetEndorsementInfoRequest request;
  service_->GetEndorsementInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetEndorsementInfoNoCert) {
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementCertificate(_, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetEndorsementInfoReply& reply) {
    EXPECT_EQ(STATUS_UNEXPECTED_DEVICE_ERROR, reply.status());
    EXPECT_FALSE(reply.has_ek_public_key());
    EXPECT_FALSE(reply.has_ek_certificate());
    quit_closure.Run();
  };
  GetEndorsementInfoRequest request;
  service_->GetEndorsementInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetKeyInfoSuccess) {
  // Setup a certified key in the key store.
  CertifiedKey key;
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_certified_key_info("certify_info");
  key.set_certified_key_proof("signature");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(KEY_TYPE_RSA, reply.key_type());
    EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage());
    EXPECT_EQ("public_key", reply.public_key());
    EXPECT_EQ("certify_info", reply.certify_info());
    EXPECT_EQ("signature", reply.certify_info_signature());
    EXPECT_EQ(GetFakeCertificateChain(), reply.certificate());
    quit_closure.Run();
  };
  GetKeyInfoRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->GetKeyInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetKeyInfoSuccessNoUser) {
  // Setup a certified key in the device key store.
  CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_certified_key_info("certify_info");
  key.set_certified_key_proof("signature");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(KEY_TYPE_RSA, reply.key_type());
    EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage());
    EXPECT_EQ("public_key", reply.public_key());
    EXPECT_EQ("certify_info", reply.certify_info());
    EXPECT_EQ("signature", reply.certify_info_signature());
    EXPECT_EQ(GetFakeCertificateChain(), reply.certificate());
    quit_closure.Run();
  };
  GetKeyInfoRequest request;
  request.set_key_label("label");
  service_->GetKeyInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetKeyInfoNoKey) {
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillRepeatedly(Return(false));

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_INVALID_PARAMETER, reply.status());
    quit_closure.Run();
  };
  GetKeyInfoRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->GetKeyInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetKeyInfoBadPublicKey) {
  EXPECT_CALL(mock_crypto_utility_, GetRSASubjectPublicKeyInfo(_, _))
      .WillRepeatedly(Return(false));

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetKeyInfoReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  GetKeyInfoRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->GetKeyInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetEndorsementKeyTypeForExistingKey) {
  AttestationDatabase* database = mock_database_.GetMutableProtobuf();
  // Default key type is KEY_TYPE_RSA.
  database->mutable_credentials()->set_endorsement_public_key("public_key");
  database->mutable_credentials()->set_endorsement_credential("certificate");
  EXPECT_EQ(service_->GetEndorsementKeyType(), KEY_TYPE_RSA);

  database->mutable_credentials()->set_endorsement_key_type(KEY_TYPE_ECC);
  database->mutable_credentials()->set_endorsement_public_key("public_key");
  database->mutable_credentials()->set_endorsement_credential("certificate");
  EXPECT_EQ(service_->GetEndorsementKeyType(), KEY_TYPE_ECC);
}

TEST_F(AttestationServiceBaseTest,
       GetEndorsementKeyTypeForNewlyCreatedKeyInTpm2) {
  EXPECT_CALL(mock_tpm_utility_, GetVersion()).WillRepeatedly(Return(TPM_2_0));
  EXPECT_EQ(service_->GetEndorsementKeyType(), KEY_TYPE_ECC);
}

TEST_F(AttestationServiceBaseTest,
       GetEndorsementKeyTypeForNewlyCreatedKeyInTpm12) {
  EXPECT_CALL(mock_tpm_utility_, GetVersion()).WillRepeatedly(Return(TPM_1_2));
  EXPECT_EQ(service_->GetEndorsementKeyType(), KEY_TYPE_RSA);
}

TEST_F(AttestationServiceBaseTest, GetAttestationIdentityKeyTypeInTpm2) {
  EXPECT_CALL(mock_tpm_utility_, GetVersion()).WillRepeatedly(Return(TPM_2_0));
  EXPECT_EQ(service_->GetAttestationIdentityKeyType(), KEY_TYPE_ECC);
}

TEST_F(AttestationServiceBaseTest, GetAttestationIdentityKeyTypeInTpm12) {
  EXPECT_CALL(mock_tpm_utility_, GetVersion()).WillRepeatedly(Return(TPM_1_2));
  EXPECT_EQ(service_->GetAttestationIdentityKeyType(), KEY_TYPE_RSA);
}

TEST_F(AttestationServiceBaseTest, GetEndorsementInfoSuccess) {
  AttestationDatabase* database = mock_database_.GetMutableProtobuf();
  database->mutable_credentials()->set_endorsement_public_key("public_key");
  database->mutable_credentials()->set_endorsement_credential("certificate");
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetEndorsementInfoReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ("public_key", reply.ek_public_key());
    EXPECT_EQ("certificate", reply.ek_certificate());
    quit_closure.Run();
  };
  GetEndorsementInfoRequest request;
  service_->GetEndorsementInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, GetEnrollmentId) {
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementPublicKeyModulus(_, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<1>(std::string("ekm")), Return(true)));
  brillo::SecureBlob abe_data(0xCA, 32);
  service_->set_abe_data(&abe_data);
  CryptoUtilityImpl crypto_utility(&mock_tpm_utility_);
  service_->set_crypto_utility(&crypto_utility);
  std::string enrollment_id = GetEnrollmentId();
  EXPECT_EQ("635c4526dfa583362273e2987944007b09131cfa0f4e5874e7a76d55d333e3cc",
            base::ToLowerASCII(
                base::HexEncode(enrollment_id.data(), enrollment_id.size())));

  // Cache the EID in the database.
  AttestationDatabase database_pb;
  database_pb.set_enrollment_id(enrollment_id);
  EXPECT_CALL(mock_database_, GetProtobuf()).WillOnce(ReturnRef(database_pb));

  // Change abe_data, and yet the EID remains the same.
  brillo::SecureBlob abe_data_new(0x89, 32);
  service_->set_abe_data(&abe_data_new);
  enrollment_id = GetEnrollmentId();
  EXPECT_EQ("635c4526dfa583362273e2987944007b09131cfa0f4e5874e7a76d55d333e3cc",
            base::ToLowerASCII(
                base::HexEncode(enrollment_id.data(), enrollment_id.size())));
}

TEST_F(AttestationServiceBaseTest, SignSimpleChallengeSuccess) {
  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(std::string("signature")), Return(true)));
  auto callback = [](const base::Closure& quit_closure,
                     const SignSimpleChallengeReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_challenge_response());
    SignedData signed_data;
    EXPECT_TRUE(signed_data.ParseFromString(reply.challenge_response()));
    EXPECT_EQ("signature", signed_data.signature());
    EXPECT_EQ(0, signed_data.data().find("challenge"));
    EXPECT_NE("challenge", signed_data.data());
    quit_closure.Run();
  };
  SignSimpleChallengeRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_challenge("challenge");
  service_->SignSimpleChallenge(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_F(AttestationServiceBaseTest, SignSimpleChallengeInternalFailure) {
  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _)).WillRepeatedly(Return(false));
  auto callback = [](const base::Closure& quit_closure,
                     const SignSimpleChallengeReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_challenge_response());
    quit_closure.Run();
  };
  SignSimpleChallengeRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_challenge("challenge");
  service_->SignSimpleChallenge(request, base::Bind(callback, QuitClosure()));
  Run();
}

class AttestationServiceEnterpriseTest
    : public AttestationServiceBaseTest,
      public testing::WithParamInterface<VAType> {
 public:
  AttestationServiceEnterpriseTest() : va_type_(GetParam()) {}
  ~AttestationServiceEnterpriseTest() override = default;

 protected:
  VAType va_type_;
  // A default GoogleKeys instance that is supposed to be the identical key
  // database that |service_| uses.
  GoogleKeys google_keys_;
};

TEST_P(AttestationServiceEnterpriseTest, SignEnterpriseChallengeSuccess) {
  KeyInfo key_info = CreateChallengeKeyInfo();
  std::string key_info_str;
  key_info.SerializeToString(&key_info_str);
  EXPECT_CALL(
      mock_crypto_utility_,
      VerifySignatureUsingHexKey(
          _, google_keys_.va_signing_key(va_type_).modulus_in_hex(), _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(
      mock_crypto_utility_,
      EncryptDataForGoogle(
          key_info_str,
          google_keys_.va_encryption_key(va_type_).modulus_in_hex(), _, _))
      .WillRepeatedly(DoAll(SetArgPointee<3>(MockEncryptedData(key_info_str)),
                            Return(true)));
  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(std::string("signature")), Return(true)));
  auto callback = [](const base::Closure& quit_closure,
                     const SignEnterpriseChallengeReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_challenge_response());
    SignedData signed_data;
    EXPECT_TRUE(signed_data.ParseFromString(reply.challenge_response()));
    EXPECT_EQ("signature", signed_data.signature());
    ChallengeResponse response_pb;
    EXPECT_TRUE(response_pb.ParseFromString(signed_data.data()));
    EXPECT_EQ(CreateChallenge("EnterpriseKeyChallenge"),
              response_pb.challenge().data());
    KeyInfo key_info = CreateChallengeKeyInfo();
    std::string key_info_str;
    key_info.SerializeToString(&key_info_str);
    EXPECT_EQ(key_info_str, response_pb.encrypted_key_info().encrypted_data());
    quit_closure.Run();
  };
  SignEnterpriseChallengeRequest request;
  request.set_va_type(va_type_);
  request.set_username("user");
  request.set_key_label("label");
  request.set_domain(key_info.domain());
  request.set_device_id(key_info.device_id());
  request.set_include_signed_public_key(false);
  request.set_challenge(CreateSignedChallenge("EnterpriseKeyChallenge"));
  service_->SignEnterpriseChallenge(request,
                                    base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceEnterpriseTest,
       SignEnterpriseChallengeInternalFailure) {
  KeyInfo key_info = CreateChallengeKeyInfo();
  std::string key_info_str;
  key_info.SerializeToString(&key_info_str);
  EXPECT_CALL(mock_crypto_utility_, VerifySignatureUsingHexKey(_, _, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _)).WillRepeatedly(Return(false));
  auto callback = [](const base::Closure& quit_closure,
                     const SignEnterpriseChallengeReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_challenge_response());
    quit_closure.Run();
  };
  SignEnterpriseChallengeRequest request;
  request.set_va_type(va_type_);
  request.set_username("user");
  request.set_key_label("label");
  request.set_domain(key_info.domain());
  request.set_device_id(key_info.device_id());
  request.set_include_signed_public_key(false);
  request.set_challenge(CreateSignedChallenge("EnterpriseKeyChallenge"));
  service_->SignEnterpriseChallenge(request,
                                    base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceEnterpriseTest, SignEnterpriseChallengeBadPrefix) {
  KeyInfo key_info = CreateChallengeKeyInfo();
  std::string key_info_str;
  key_info.SerializeToString(&key_info_str);
  EXPECT_CALL(mock_crypto_utility_, VerifySignatureUsingHexKey(_, _, _, _))
      .WillRepeatedly(Return(true));
  auto callback = [](const base::Closure& quit_closure,
                     const SignEnterpriseChallengeReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_challenge_response());
    quit_closure.Run();
  };
  SignEnterpriseChallengeRequest request;
  request.set_va_type(va_type_);
  request.set_username("user");
  request.set_key_label("label");
  request.set_domain(key_info.domain());
  request.set_device_id(key_info.device_id());
  request.set_include_signed_public_key(false);
  request.set_challenge(CreateSignedChallenge("bad_prefix"));
  service_->SignEnterpriseChallenge(request,
                                    base::Bind(callback, QuitClosure()));
  Run();
}

// Test that if |key_name_for_spkac| is not empty then the key associated to it
// is used for SignedPublicKeyAndChallenge.
TEST_P(AttestationServiceEnterpriseTest,
       SignEnterpriseChallengeUseKeyForSPKAC) {
  static const char kKeyNameForSpkac[] = "attest-ent-machine_temp_id";
  static const char kKeyNameForSpkacPublicKey[] =
      "attest-ent-machine_public_key";

  CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
  key.set_public_key("public_key");
  key.set_key_name("label");

  // Create a machine key for SPKAC
  CertifiedKey& key_for_spkac =
      *mock_database_.GetMutableProtobuf()->add_device_keys();
  key_for_spkac.set_key_blob("key_blob");
  key_for_spkac.set_public_key(kKeyNameForSpkacPublicKey);
  key_for_spkac.set_key_name(kKeyNameForSpkac);
  key_for_spkac.set_certified_key_credential("fake_cert_data");

  KeyInfo expected_key_info =
      CreateMachineChallengeKeyInfoWithSPKAC("fake_cert_data", "fake_spkac");
  std::string expected_key_info_str;
  expected_key_info.SerializeToString(&expected_key_info_str);

  ExpectGetCustomerId("customer_id");
  EXPECT_CALL(
      mock_crypto_utility_,
      VerifySignatureUsingHexKey(
          _, google_keys_.va_signing_key(va_type_).modulus_in_hex(), _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(
      mock_crypto_utility_,
      EncryptDataForGoogle(
          expected_key_info_str,
          google_keys_.va_encryption_key(va_type_).modulus_in_hex(), _, _))
      .WillOnce(
          DoAll(SetArgPointee<3>(MockEncryptedData(expected_key_info_str)),
                Return(true)));

  // Expect |CreateSPKAC| to be called for |key_name_for_spkac|.
  EXPECT_CALL(
      mock_crypto_utility_,
      CreateSPKAC(key_for_spkac.key_blob(), key_for_spkac.public_key(), _, _))
      .WillOnce(
          DoAll(SetArgPointee<3>(std::string("fake_spkac")), Return(true)));

  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _))
      .WillOnce(
          DoAll(SetArgPointee<2>(std::string("signature")), Return(true)));

  auto callback = [](const std::string& expected_key_info_str,
                     const base::Closure& quit_closure,
                     const SignEnterpriseChallengeReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_challenge_response());
    SignedData signed_data;
    EXPECT_TRUE(signed_data.ParseFromString(reply.challenge_response()));
    EXPECT_EQ("signature", signed_data.signature());
    ChallengeResponse response_pb;
    EXPECT_TRUE(response_pb.ParseFromString(signed_data.data()));
    // This relies on the fact that the mock for EncryptDataForGoogle just
    // passes the data unencrypted.
    EXPECT_EQ(expected_key_info_str,
              response_pb.encrypted_key_info().encrypted_data());
    quit_closure.Run();
  };
  SignEnterpriseChallengeRequest request;
  request.set_va_type(va_type_);
  request.set_key_label("label");
  request.set_domain("to_be_ignored");
  request.set_device_id(expected_key_info.device_id());
  request.set_include_signed_public_key(true);
  request.set_key_name_for_spkac(kKeyNameForSpkac);
  request.set_challenge(CreateSignedChallenge("EnterpriseKeyChallenge"));
  service_->SignEnterpriseChallenge(
      request, base::Bind(callback, expected_key_info_str, QuitClosure()));
  Run();
}

INSTANTIATE_TEST_SUITE_P(VerifiedAccessType,
                         AttestationServiceEnterpriseTest,
                         ::testing::Values(DEFAULT_VA, TEST_VA));

class AttestationServiceTest : public AttestationServiceBaseTest,
                               public testing::WithParamInterface<ACAType> {
 public:
  AttestationServiceTest() : aca_type_(GetParam()) {}
  ~AttestationServiceTest() override = default;

  void SetUp() override { AttestationServiceBaseTest::SetUp(); }

 protected:
  std::string CreateCAEnrollResponse(bool success) {
    AttestationEnrollmentResponse response_pb;
    if (success) {
      response_pb.set_status(OK);
      response_pb.set_detail("");
      response_pb.mutable_encrypted_identity_credential()->set_tpm_version(
          kTpmVersionUnderTest);
      response_pb.mutable_encrypted_identity_credential()->set_asym_ca_contents(
          "1234");
      response_pb.mutable_encrypted_identity_credential()
          ->set_sym_ca_attestation("5678");
      response_pb.mutable_encrypted_identity_credential()->set_encrypted_seed(
          "seed");
      response_pb.mutable_encrypted_identity_credential()->set_credential_mac(
          "mac");
      response_pb.mutable_encrypted_identity_credential()
          ->mutable_wrapped_certificate()
          ->set_wrapped_key("wrapped");
    } else {
      response_pb.set_status(SERVER_ERROR);
      response_pb.set_detail("fake_enroll_error");
    }
    std::string response_str;
    response_pb.SerializeToString(&response_str);
    return response_str;
  }

  std::string CreateCACertResponse(bool success, std::string message_id) {
    AttestationCertificateResponse response_pb;
    if (success) {
      response_pb.set_status(OK);
      response_pb.set_detail("");
      response_pb.set_message_id(message_id);
      response_pb.set_certified_key_credential("fake_cert");
      response_pb.set_intermediate_ca_cert("fake_ca_cert");
      *response_pb.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
    } else {
      response_pb.set_status(SERVER_ERROR);
      response_pb.set_message_id(message_id);
      response_pb.set_detail("fake_sign_error");
    }
    std::string response_str;
    response_pb.SerializeToString(&response_str);
    return response_str;
  }

  AttestationCertificateRequest GenerateCACertRequest() {
    SetUpIdentity(identity_);
    SetUpIdentityCertificate(identity_, DEFAULT_ACA);
    base::RunLoop loop;
    auto callback = [](base::RunLoop* loop,
                       AttestationCertificateRequest* pca_request,
                       const CreateCertificateRequestReply& reply) {
      pca_request->ParseFromString(reply.pca_request());
      loop->Quit();
    };
    CreateCertificateRequestRequest request;
    request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
    AttestationCertificateRequest pca_request;
    service_->CreateCertificateRequest(
        request, base::Bind(callback, &loop, &pca_request));
    loop.Run();
    return pca_request;
  }

  ACAType aca_type_;
};

TEST_P(AttestationServiceTest, GetAttestationKeyInfoSuccess) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  // Set expectations on the outputs.
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const GetAttestationKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ("public_key", reply.public_key());
    EXPECT_EQ("public_key_tpm", reply.public_key_tpm_format());
    EXPECT_EQ(cert_name, reply.certificate());
    EXPECT_EQ("pcr0", reply.pcr0_quote().quote());
    EXPECT_EQ("pcr1", reply.pcr1_quote().quote());
    quit_closure.Run();
  };
  GetAttestationKeyInfoRequest request;
  request.set_aca_type(aca_type_);
  service_->GetAttestationKeyInfo(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetAttestationKeyInfoNoInfo) {
  SetUpIdentityCertificate(identity_, aca_type_);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const GetAttestationKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_public_key_tpm_format());
    EXPECT_FALSE(reply.has_certificate());
    EXPECT_FALSE(reply.has_pcr0_quote());
    EXPECT_FALSE(reply.has_pcr1_quote());
    quit_closure.Run();
  };
  GetAttestationKeyInfoRequest request;
  request.set_aca_type(aca_type_);
  service_->GetAttestationKeyInfo(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetAttestationKeyInfoSomeInfo) {
  SetUpIdentity(identity_);
  auto* identity_data =
      mock_database_.GetMutableProtobuf()->mutable_identities()->Mutable(
          identity_);
  identity_data->mutable_identity_key()->clear_identity_public_key_der();
  identity_data->mutable_identity_binding()
      ->clear_identity_public_key_tpm_format();
  identity_data->mutable_pcr_quotes()->erase(0);
  SetUpIdentityCertificate(identity_, aca_type_);
  // Set expectations on the outputs.
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const GetAttestationKeyInfoReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_public_key_tpm_format());
    EXPECT_EQ(cert_name, reply.certificate());
    EXPECT_FALSE(reply.has_pcr0_quote());
    EXPECT_EQ("pcr1", reply.pcr1_quote().quote());
    quit_closure.Run();
  };
  GetAttestationKeyInfoRequest request;
  request.set_aca_type(aca_type_);
  service_->GetAttestationKeyInfo(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, ActivateAttestationKeySuccess) {
  SetUpIdentity(identity_);
  EXPECT_CALL(mock_database_, SaveChanges()).Times(1);
  const std::string cert_name = GetCertificateName(identity_, aca_type_);
  if (kTpmVersionUnderTest == TPM_1_2) {
    EXPECT_CALL(mock_tpm_utility_,
                ActivateIdentity(_, "encrypted1", "encrypted2", _))
        .WillOnce(DoAll(SetArgPointee<3>(cert_name), Return(true)));
  } else {
    EXPECT_CALL(
        mock_tpm_utility_,
        ActivateIdentityForTpm2(KEY_TYPE_ECC, _, "seed", "mac", "wrapped", _))
        .WillOnce(DoAll(SetArgPointee<5>(cert_name), Return(true)));
  }
  // Set expectations on the outputs.
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const ActivateAttestationKeyReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(cert_name, reply.certificate());
    quit_closure.Run();
  };
  ActivateAttestationKeyRequest request;
  request.set_aca_type(aca_type_);
  request.mutable_encrypted_certificate()->set_tpm_version(
      kTpmVersionUnderTest);
  request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
  request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
  request.mutable_encrypted_certificate()->set_encrypted_seed("seed");
  request.mutable_encrypted_certificate()->set_credential_mac("mac");
  request.mutable_encrypted_certificate()
      ->mutable_wrapped_certificate()
      ->set_wrapped_key("wrapped");
  request.set_save_certificate(true);
  service_->ActivateAttestationKey(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, ActivateAttestationKeySuccessNoSave) {
  SetUpIdentity(identity_);
  EXPECT_CALL(mock_database_, GetMutableProtobuf()).Times(0);
  EXPECT_CALL(mock_database_, SaveChanges()).Times(0);
  const std::string cert_name = GetCertificateName(identity_, aca_type_);
  if (kTpmVersionUnderTest == TPM_1_2) {
    EXPECT_CALL(mock_tpm_utility_,
                ActivateIdentity(_, "encrypted1", "encrypted2", _))
        .WillOnce(DoAll(SetArgPointee<3>(cert_name), Return(true)));
  } else {
    EXPECT_CALL(
        mock_tpm_utility_,
        ActivateIdentityForTpm2(KEY_TYPE_ECC, _, "seed", "mac", "wrapped", _))
        .WillOnce(DoAll(SetArgPointee<5>(cert_name), Return(true)));
  }
  // Set expectations on the outputs.
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const ActivateAttestationKeyReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(cert_name, reply.certificate());
    quit_closure.Run();
  };
  ActivateAttestationKeyRequest request;
  request.set_aca_type(aca_type_);
  request.mutable_encrypted_certificate()->set_tpm_version(
      kTpmVersionUnderTest);
  request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
  request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
  request.mutable_encrypted_certificate()->set_encrypted_seed("seed");
  request.mutable_encrypted_certificate()->set_credential_mac("mac");
  request.mutable_encrypted_certificate()
      ->mutable_wrapped_certificate()
      ->set_wrapped_key("wrapped");
  service_->ActivateAttestationKey(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, ActivateAttestationKeySaveFailure) {
  SetUpIdentity(identity_);
  EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const ActivateAttestationKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  ActivateAttestationKeyRequest request;
  request.set_aca_type(aca_type_);
  request.mutable_encrypted_certificate()->set_tpm_version(
      kTpmVersionUnderTest);
  request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
  request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
  request.mutable_encrypted_certificate()->set_encrypted_seed("seed");
  request.mutable_encrypted_certificate()->set_credential_mac("mac");
  request.mutable_encrypted_certificate()
      ->mutable_wrapped_certificate()
      ->set_wrapped_key("wrapped");
  request.set_save_certificate(true);
  service_->ActivateAttestationKey(request,
                                   base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, ActivateAttestationKeyActivateFailure) {
  SetUpIdentity(identity_);
  if (kTpmVersionUnderTest == TPM_1_2) {
    EXPECT_CALL(mock_tpm_utility_,
                ActivateIdentity(_, "encrypted1", "encrypted2", _))
        .WillRepeatedly(Return(false));
  } else {
    EXPECT_CALL(
        mock_tpm_utility_,
        ActivateIdentityForTpm2(KEY_TYPE_ECC, _, "seed", "mac", "wrapped", _))
        .WillRepeatedly(Return(false));
  }
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const ActivateAttestationKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  ActivateAttestationKeyRequest request;
  request.set_aca_type(aca_type_);
  request.mutable_encrypted_certificate()->set_tpm_version(
      kTpmVersionUnderTest);
  request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1");
  request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2");
  request.mutable_encrypted_certificate()->set_encrypted_seed("seed");
  request.mutable_encrypted_certificate()->set_credential_mac("mac");
  request.mutable_encrypted_certificate()
      ->mutable_wrapped_certificate()
      ->set_wrapped_key("wrapped");
  request.set_save_certificate(true);
  service_->ActivateAttestationKey(request,
                                   base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeySuccess) {
  // We need an identity to create a certifiable key.
  SetUpIdentity(identity_);

  // Configure a fake TPM response.
  EXPECT_CALL(
      mock_tpm_utility_,
      CreateCertifiedKey(KEY_TYPE_RSA, KEY_USAGE_SIGN, _, _, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(std::string("public_key")),
                      SetArgPointee<7>(std::string("certify_info")),
                      SetArgPointee<8>(std::string("certify_info_signature")),
                      Return(true)));
  // Expect the key to be written exactly once.
  EXPECT_CALL(mock_key_store_, Write("user", "label", _)).Times(1);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ("public_key", reply.public_key());
    EXPECT_EQ("certify_info", reply.certify_info());
    EXPECT_EQ("certify_info_signature", reply.certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  request.set_username("user");
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeySuccessNoUser) {
  // We need an identity to create a certifiable key.
  SetUpIdentity(identity_);

  // Configure a fake TPM response.
  EXPECT_CALL(
      mock_tpm_utility_,
      CreateCertifiedKey(KEY_TYPE_RSA, KEY_USAGE_SIGN, _, _, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(std::string("public_key")),
                      SetArgPointee<7>(std::string("certify_info")),
                      SetArgPointee<8>(std::string("certify_info_signature")),
                      Return(true)));
  // Expect the key to be written exactly once.
  EXPECT_CALL(mock_database_, SaveChanges()).Times(1);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ("public_key", reply.public_key());
    EXPECT_EQ("certify_info", reply.certify_info());
    EXPECT_EQ("certify_info_signature", reply.certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeyRNGFailure) {
  // We need an identity to make sure it didn't fail because of that.
  SetUpIdentity(identity_);

  EXPECT_CALL(mock_crypto_utility_, GetRandom(_, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_certify_info());
    EXPECT_FALSE(reply.has_certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeyNoIdentityFailure) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_certify_info());
    EXPECT_FALSE(reply.has_certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeyTpmCreateFailure) {
  // We need an identity to create a certifiable key.
  SetUpIdentity(identity_);

  EXPECT_CALL(mock_tpm_utility_, CreateCertifiedKey(_, _, _, _, _, _, _, _, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_certify_info());
    EXPECT_FALSE(reply.has_certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeyDBFailure) {
  // We need an identity to make sure it didn't fail because of that.
  SetUpIdentity(identity_);

  EXPECT_CALL(mock_key_store_, Write(_, _, _)).WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_certify_info());
    EXPECT_FALSE(reply.has_certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  request.set_username("username");
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertifiableKeyDBFailureNoUser) {
  // We need an identity to make sure it didn't fail because of that.
  SetUpIdentity(identity_);

  EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertifiableKeyReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_public_key());
    EXPECT_FALSE(reply.has_certify_info());
    EXPECT_FALSE(reply.has_certify_info_signature());
    quit_closure.Run();
  };
  CreateCertifiableKeyRequest request;
  request.set_key_label("label");
  request.set_key_type(KEY_TYPE_RSA);
  request.set_key_usage(KEY_USAGE_SIGN);
  service_->CreateCertifiableKey(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DecryptSuccess) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DecryptReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(MockTpmUtility::Transform("Unbind", "data"),
              reply.decrypted_data());
    quit_closure.Run();
  };
  DecryptRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_encrypted_data("data");
  service_->Decrypt(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DecryptSuccessNoUser) {
  mock_database_.GetMutableProtobuf()->add_device_keys()->set_key_name("label");
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DecryptReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(MockTpmUtility::Transform("Unbind", "data"),
              reply.decrypted_data());
    quit_closure.Run();
  };
  DecryptRequest request;
  request.set_key_label("label");
  request.set_encrypted_data("data");
  service_->Decrypt(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DecryptKeyNotFound) {
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DecryptReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_decrypted_data());
    quit_closure.Run();
  };
  DecryptRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_encrypted_data("data");
  service_->Decrypt(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DecryptKeyNotFoundNoUser) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DecryptReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_decrypted_data());
    quit_closure.Run();
  };
  DecryptRequest request;
  request.set_key_label("label");
  request.set_encrypted_data("data");
  service_->Decrypt(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DecryptUnbindFailure) {
  EXPECT_CALL(mock_tpm_utility_, Unbind(_, _, _)).WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DecryptReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_decrypted_data());
    quit_closure.Run();
  };
  DecryptRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_encrypted_data("data");
  service_->Decrypt(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, SignSuccess) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const SignReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(MockTpmUtility::Transform("Sign", "data"), reply.signature());
    quit_closure.Run();
  };
  SignRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_data_to_sign("data");
  service_->Sign(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, SignSuccessNoUser) {
  mock_database_.GetMutableProtobuf()->add_device_keys()->set_key_name("label");
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const SignReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(MockTpmUtility::Transform("Sign", "data"), reply.signature());
    quit_closure.Run();
  };
  SignRequest request;
  request.set_key_label("label");
  request.set_data_to_sign("data");
  service_->Sign(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, SignKeyNotFound) {
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const SignReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_signature());
    quit_closure.Run();
  };
  SignRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_data_to_sign("data");
  service_->Sign(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, SignKeyNotFoundNoUser) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const SignReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_signature());
    quit_closure.Run();
  };
  SignRequest request;
  request.set_key_label("label");
  request.set_data_to_sign("data");
  service_->Sign(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, SignUnbindFailure) {
  EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _)).WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const SignReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_signature());
    quit_closure.Run();
  };
  SignRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_data_to_sign("data");
  service_->Sign(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterSuccess) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));
  // Cardinality is verified here to verify various steps are performed and to
  // catch performance regressions.
  EXPECT_CALL(mock_key_store_,
              Register("user", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN,
                       "key_blob", "public_key", ""))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _)).Times(0);
  EXPECT_CALL(mock_key_store_, Delete("user", "label")).Times(1);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterSuccessNoUser) {
  // Setup a key in the device_keys field.
  CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  // Cardinality is verified here to verify various steps are performed and to
  // catch performance regressions.
  EXPECT_CALL(mock_key_store_,
              Register("", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN, "key_blob",
                       "public_key", ""))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _)).Times(0);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure, Database* database,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(0, database->GetMutableProtobuf()->device_keys_size());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  service_->RegisterKeyWithChapsToken(
      request, base::Bind(callback, QuitClosure(), &mock_database_));
  Run();
}

TEST_P(AttestationServiceTest, RegisterSuccessWithCertificates) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));
  // Cardinality is verified here to verify various steps are performed and to
  // catch performance regressions.
  EXPECT_CALL(mock_key_store_,
              Register("user", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN,
                       "key_blob", "public_key", "fake_cert"))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate("user", "fake_ca_cert"))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate("user", "fake_ca_cert2"))
      .Times(1);
  EXPECT_CALL(mock_key_store_, Delete("user", "label")).Times(1);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_include_certificates(true);
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterSuccessNoUserWithCertificates) {
  // Setup a key in the device_keys field.
  CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  // Cardinality is verified here to verify various steps are performed and to
  // catch performance regressions.
  EXPECT_CALL(mock_key_store_,
              Register("", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN, "key_blob",
                       "public_key", "fake_cert"))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate("", "fake_ca_cert"))
      .Times(1);
  EXPECT_CALL(mock_key_store_, RegisterCertificate("", "fake_ca_cert2"))
      .Times(1);
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure, Database* database,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(0, database->GetMutableProtobuf()->device_keys_size());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_include_certificates(true);
  service_->RegisterKeyWithChapsToken(
      request, base::Bind(callback, QuitClosure(), &mock_database_));
  Run();
}

TEST_P(AttestationServiceTest, RegisterNoKey) {
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterNoKeyNoUser) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterFailure) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_name("label");
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));
  EXPECT_CALL(mock_key_store_, Register(_, _, _, _, _, _, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterIntermediateFailure) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_name("label");
  key.set_intermediate_ca_cert("fake_ca_cert");
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));
  EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_include_certificates(true);
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, RegisterAdditionalFailure) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_name("label");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  std::string key_bytes;
  key.SerializeToString(&key_bytes);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(key_bytes), Return(true)));
  EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _))
      .WillRepeatedly(Return(false));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const RegisterKeyWithChapsTokenReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  RegisterKeyWithChapsTokenRequest request;
  request.set_key_label("label");
  request.set_username("user");
  request.set_include_certificates(true);
  service_->RegisterKeyWithChapsToken(request,
                                      base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeysByLabelSuccess) {
  // Setup a key in the user key store.
  CertifiedKey key;
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);
  std::string key_bytes;
  key.SerializeToString(&key_bytes);

  EXPECT_CALL(mock_key_store_, Delete("user", "label"))
      .Times(1)
      .WillOnce(Return(true));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  request.set_match_behavior(DeleteKeysRequest::MATCH_BEHAVIOR_EXACT);
  request.set_username("user");
  service_->DeleteKeys(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeyByLabelNoUserSuccess) {
  // Setup a key in the device_keys field.
  CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
  key.set_key_blob("key_blob");
  key.set_public_key("public_key");
  key.set_certified_key_credential("fake_cert");
  key.set_intermediate_ca_cert("fake_ca_cert");
  *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
  key.set_key_name("label");
  key.set_key_type(KEY_TYPE_RSA);
  key.set_key_usage(KEY_USAGE_SIGN);

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure, Database* database,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(0, database->GetMutableProtobuf()->device_keys_size());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  request.set_match_behavior(DeleteKeysRequest::MATCH_BEHAVIOR_EXACT);
  service_->DeleteKeys(request,
                       base::Bind(callback, QuitClosure(), &mock_database_));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeysByLabelNoKey) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  request.set_match_behavior(DeleteKeysRequest::MATCH_BEHAVIOR_EXACT);
  request.set_username("user");
  service_->DeleteKeys(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeyByLabelNoUserNoKey) {
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  request.set_match_behavior(DeleteKeysRequest::MATCH_BEHAVIOR_EXACT);
  service_->DeleteKeys(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeysByPrefixSuccess) {
  EXPECT_CALL(mock_key_store_, DeleteByPrefix("user", "label"))
      .Times(1)
      .WillOnce(Return(true));
  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  request.set_username("user");
  service_->DeleteKeys(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, DeleteKeyByPrefixNoUserSuccess) {
  // Setup a key in the device_keys field.
  const std::string key_labels[] = {"label1", "label2", "otherprefix"};
  for (const auto& key_label : key_labels) {
    CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys();
    key.set_key_blob("key_blob");
    key.set_public_key("public_key");
    key.set_certified_key_credential("fake_cert");
    key.set_intermediate_ca_cert("fake_ca_cert");
    *key.add_additional_intermediate_ca_cert() = "fake_ca_cert2";
    key.set_key_name(key_label);
    key.set_key_type(KEY_TYPE_RSA);
    key.set_key_usage(KEY_USAGE_SIGN);
  }

  // Set expectations on the outputs.
  auto callback = [](const base::Closure& quit_closure, Database* database,
                     const DeleteKeysReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(1, database->GetMutableProtobuf()->device_keys_size());
    EXPECT_EQ("otherprefix",
              database->GetMutableProtobuf()->device_keys()[0].key_name());
    quit_closure.Run();
  };
  DeleteKeysRequest request;
  request.set_key_label_match("label");
  service_->DeleteKeys(request,
                       base::Bind(callback, QuitClosure(), &mock_database_));
  Run();
}

TEST_P(AttestationServiceTest, PrepareForEnrollment) {
  // Start with an empty database.
  mock_database_.GetMutableProtobuf()->Clear();
  // Schedule initialization again to make sure it runs after this point.
  EXPECT_CALL(mock_tpm_utility_, GetNVDataSize(_, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(9487), Return(true)));
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  // One identity has been created.
  EXPECT_EQ(1, mock_database_.GetProtobuf().identities().size());
  const AttestationDatabase::Identity& identity_data =
      mock_database_.GetProtobuf().identities().Get(0);
  EXPECT_TRUE(identity_data.has_identity_binding());
  EXPECT_TRUE(identity_data.has_identity_key());
  EXPECT_EQ(1, identity_data.pcr_quotes().count(0));
  EXPECT_EQ(1, identity_data.pcr_quotes().count(1));
#if USE_TPM2
  EXPECT_EQ(1, identity_data.nvram_quotes().count(BOARD_ID));
  EXPECT_EQ(1, identity_data.nvram_quotes().count(SN_BITS));
  EXPECT_EQ(service_->GetEndorsementKeyType() != KEY_TYPE_RSA ? 1 : 0,
            identity_data.nvram_quotes().count(RSA_PUB_EK_CERT));
#else
  EXPECT_TRUE(identity_data.nvram_quotes().empty());
#endif
  EXPECT_EQ(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            identity_data.features());
  // Deprecated identity-related values have not been set.
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_key());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_binding());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr0_quote());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr1_quote());
  // Verify Privacy CA-related data.
  VerifyACAData(mock_database_.GetProtobuf());
  // These deprecated fields have not been set either.
  EXPECT_TRUE(mock_database_.GetProtobuf().has_credentials());
  EXPECT_FALSE(mock_database_.GetProtobuf()
                   .credentials()
                   .has_default_encrypted_endorsement_credential());
}

#if USE_TPM2

TEST_P(AttestationServiceTest,
       PrepareForEnrollmentCannotQuoteOptionalNvramForRsaEK) {
  auto database_pb = mock_database_.GetMutableProtobuf();
  // Start with an empty database to trigger PrepareForEnrollment.
  database_pb->Clear();

  // Setup the database to make GetEndorsementKeyType to return specific key
  // type, but will still make IsPreparedForEnrollment return false.
  database_pb->mutable_credentials()->set_endorsement_key_type(KEY_TYPE_RSA);
  database_pb->mutable_credentials()->set_endorsement_public_key("pubkey");

  EXPECT_CALL(mock_tpm_utility_, CertifyNV(_, _, _, _, _))
      .WillRepeatedly(Return(false));

  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));

  // One identity has been created.
  EXPECT_EQ(1, mock_database_.GetProtobuf().identities().size());
  const AttestationDatabase::Identity& identity_data =
      mock_database_.GetProtobuf().identities().Get(0);
  EXPECT_TRUE(identity_data.has_identity_binding());
  EXPECT_TRUE(identity_data.has_identity_key());
  EXPECT_EQ(1, identity_data.pcr_quotes().count(0));
  EXPECT_EQ(1, identity_data.pcr_quotes().count(1));
  EXPECT_TRUE(identity_data.nvram_quotes().empty());
  EXPECT_EQ(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            identity_data.features());
}

TEST_P(AttestationServiceTest,
       PrepareForEnrollmentCannotQuoteOptionalNvramForEccEK) {
  auto database_pb = mock_database_.GetMutableProtobuf();

  // Start with an empty database to trigger PrepareForEnrollment.
  database_pb->Clear();

  // Setup the database to make GetEndorsementKeyType to return specific key
  // type, but will still make IsPreparedForEnrollment return false.
  database_pb->mutable_credentials()->set_endorsement_key_type(KEY_TYPE_ECC);
  database_pb->mutable_credentials()->set_endorsement_public_key("pubkey");

  // Assume the NV indexes doesn't exist, except RSA EK cert which is required
  // when ECC EK is enabled.
  EXPECT_CALL(mock_tpm_utility_, GetNVDataSize(_, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(9487), Return(true)));
  EXPECT_CALL(mock_tpm_utility_, CertifyNV(_, _, _, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_tpm_utility_,
              CertifyNV(trunks::kRsaEndorsementCertificateIndex, _, _, _, _))
      .WillRepeatedly(Return(true));

  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));

  // One identity has been created.
  EXPECT_EQ(1, mock_database_.GetProtobuf().identities().size());
  const AttestationDatabase::Identity& identity_data =
      mock_database_.GetProtobuf().identities().Get(0);
  EXPECT_TRUE(identity_data.has_identity_binding());
  EXPECT_TRUE(identity_data.has_identity_key());
  EXPECT_EQ(1, identity_data.pcr_quotes().count(0));
  EXPECT_EQ(1, identity_data.pcr_quotes().count(1));
  EXPECT_EQ(1, identity_data.nvram_quotes().size());
  EXPECT_EQ(1, identity_data.nvram_quotes().count(RSA_PUB_EK_CERT));
  EXPECT_EQ(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            identity_data.features());
}

TEST_P(AttestationServiceTest,
       PrepareForEnrollmentCannotQuoteRsaEKCertForEccEK) {
  auto database_pb = mock_database_.GetMutableProtobuf();

  // Start with an empty database to trigger PrepareForEnrollment.
  database_pb->Clear();

  // Setup the database to make GetEndorsementKeyType to return specific key
  // type, but will still make IsPreparedForEnrollment return false.
  database_pb->mutable_credentials()->set_endorsement_key_type(KEY_TYPE_ECC);
  database_pb->mutable_credentials()->set_endorsement_public_key("pubkey");

  EXPECT_CALL(mock_tpm_utility_, CertifyNV(_, _, _, _, _))
      .WillRepeatedly(Return(false));

  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));

  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_key());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_binding());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr0_quote());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr1_quote());
}

#endif

TEST_P(AttestationServiceTest, PrepareForEnrollmentNoPublicKey) {
  // Start with an empty database.
  mock_database_.GetMutableProtobuf()->Clear();
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementPublicKey(_, _))
      .WillRepeatedly(Return(false));
  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  EXPECT_FALSE(mock_database_.GetProtobuf().has_credentials());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_key());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_binding());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr0_quote());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr1_quote());
}

TEST_P(AttestationServiceTest, PrepareForEnrollmentNoCert) {
  // Start with an empty database.
  mock_database_.GetMutableProtobuf()->Clear();
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementCertificate(_, _))
      .WillRepeatedly(Return(false));
  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  EXPECT_FALSE(mock_database_.GetProtobuf().has_credentials());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_key());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_binding());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr0_quote());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr1_quote());
}

TEST_P(AttestationServiceTest, PrepareForEnrollmentFailAIK) {
  // Start with an empty database.
  mock_database_.GetMutableProtobuf()->Clear();
  EXPECT_CALL(mock_tpm_utility_, CreateIdentity(_, _))
      .WillRepeatedly(Return(false));
  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  // No identity was created.
  EXPECT_EQ(0, mock_database_.GetProtobuf().identities().size());
  // And no credentials were stored.
  EXPECT_FALSE(mock_database_.GetProtobuf().has_credentials());
}

TEST_P(AttestationServiceTest, PrepareForEnrollmentFailQuote) {
  // Start with an empty database.
  mock_database_.GetMutableProtobuf()->Clear();
  EXPECT_CALL(mock_tpm_utility_, QuotePCR(_, _, _, _, _))
      .WillRepeatedly(Return(false));
  // Schedule initialization again to make sure it runs after this point.
  CHECK(CallAndWait(base::BindOnce(&AttestationService::InitializeWithCallback,
                                   base::Unretained(service_.get()))));
  EXPECT_FALSE(mock_database_.GetProtobuf().has_credentials());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_key());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_identity_binding());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr0_quote());
  EXPECT_FALSE(mock_database_.GetProtobuf().has_pcr1_quote());
}

TEST_P(AttestationServiceTest, ComputeEnterpriseEnrollmentId) {
  EXPECT_CALL(mock_tpm_utility_, GetEndorsementPublicKeyModulus(_, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<1>(std::string("ekm")), Return(true)));
  brillo::SecureBlob abe_data(0xCA, 32);
  service_->set_abe_data(&abe_data);
  CryptoUtilityImpl crypto_utility(&mock_tpm_utility_);
  service_->set_crypto_utility(&crypto_utility);
  std::string enrollment_id = ComputeEnterpriseEnrollmentId();
  EXPECT_EQ("635c4526dfa583362273e2987944007b09131cfa0f4e5874e7a76d55d333e3cc",
            base::ToLowerASCII(
                base::HexEncode(enrollment_id.data(), enrollment_id.size())));
}

TEST_P(AttestationServiceTest, CreateCertificateRequestSuccess) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationCertificateRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE, pca_request.profile());
    EXPECT_TRUE(pca_request.nvram_quotes().empty());
    EXPECT_EQ(cert_name, pca_request.identity_credential());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateEnrollmentCertificateRequestSuccess) {
#if USE_TPM2
  EXPECT_CALL(mock_tpm_utility_,
              CertifyNV(VIRTUAL_NV_INDEX_RSU_DEV_ID, _, _, _, _))
      .WillRepeatedly(DoAll(SetArgPointee<3>("rsu_device_id_quoted_data"),
                            SetArgPointee<4>("rsu_device_id"), Return(true)));
#endif
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationCertificateRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ(ENTERPRISE_ENROLLMENT_CERTIFICATE, pca_request.profile());
#if USE_TPM2
    EXPECT_EQ(3, pca_request.nvram_quotes().size());
    EXPECT_EQ("board_id", pca_request.nvram_quotes().at(BOARD_ID).quote());
    EXPECT_EQ("sn_bits", pca_request.nvram_quotes().at(SN_BITS).quote());
    EXPECT_EQ("rsu_device_id",
              pca_request.nvram_quotes().at(RSU_DEVICE_ID).quote());
    EXPECT_EQ("rsu_device_id_quoted_data",
              pca_request.nvram_quotes().at(RSU_DEVICE_ID).quoted_data());
#else
    EXPECT_TRUE(pca_request.nvram_quotes().empty());
#endif
    EXPECT_EQ(cert_name, pca_request.identity_credential());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_ENROLLMENT_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest,
       CreateEnrollmentCertificateRequestSuccessWithUnattestedRsuDeviceId) {
#if USE_TPM2
  EXPECT_CALL(mock_tpm_utility_,
              CertifyNV(VIRTUAL_NV_INDEX_RSU_DEV_ID, _, _, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_tpm_utility_, GetRsuDeviceId(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>("rsu_device_id"), Return(true)));
#endif
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationCertificateRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ(ENTERPRISE_ENROLLMENT_CERTIFICATE, pca_request.profile());
#if USE_TPM2
    EXPECT_EQ(2, pca_request.nvram_quotes().size());
    EXPECT_EQ("board_id", pca_request.nvram_quotes().at(BOARD_ID).quote());
    EXPECT_EQ("sn_bits", pca_request.nvram_quotes().at(SN_BITS).quote());
    EXPECT_EQ(pca_request.nvram_quotes().end(),
              pca_request.nvram_quotes().find(RSU_DEVICE_ID));
#else
    EXPECT_TRUE(pca_request.nvram_quotes().empty());
#endif
    EXPECT_EQ(cert_name, pca_request.identity_credential());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_ENROLLMENT_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest,
       CreateEnrollmentCertificateRequestWithoutRsuDeviceIdSuccess) {
#if USE_TPM2
  EXPECT_CALL(mock_tpm_utility_,
              CertifyNV(VIRTUAL_NV_INDEX_RSU_DEV_ID, _, _, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_tpm_utility_, GetRsuDeviceId(_))
      .WillRepeatedly(Return(false));
#endif
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const std::string& cert_name,
                     const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationCertificateRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ(ENTERPRISE_ENROLLMENT_CERTIFICATE, pca_request.profile());
#if USE_TPM2
    EXPECT_EQ(2, pca_request.nvram_quotes().size());
    EXPECT_EQ("board_id", pca_request.nvram_quotes().at(BOARD_ID).quote());
    EXPECT_EQ("sn_bits", pca_request.nvram_quotes().at(SN_BITS).quote());
    EXPECT_EQ(pca_request.nvram_quotes().find(RSU_DEVICE_ID),
              pca_request.nvram_quotes().cend());
#else
    EXPECT_TRUE(pca_request.nvram_quotes().empty());
#endif
    EXPECT_EQ(cert_name, pca_request.identity_credential());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_ENROLLMENT_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(
      request, base::Bind(callback, GetCertificateName(identity_, aca_type_),
                          QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertificateRequestInternalFailure) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  EXPECT_CALL(mock_crypto_utility_, GetRandom(_, _))
      .WillRepeatedly(Return(false));
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_pca_request());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateCertificateRequestNotEnrolled) {
  // No identiy certificate, so not enrolled.
  mock_database_.GetMutableProtobuf()->Clear();
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const CreateCertificateRequestReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_pca_request());
    quit_closure.Run();
  };
  CreateCertificateRequestRequest request;
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  service_->CreateCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, FinishCertificateRequestSuccess) {
  auto callback = [](const base::Closure& quit_closure,
                     const FinishCertificateRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_certificate());
    quit_closure.Run();
  };
  AttestationCertificateRequest pca_request = GenerateCACertRequest();
  FinishCertificateRequestRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_pca_response(
      CreateCACertResponse(true, pca_request.message_id()));
  service_->FinishCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, FinishCertificateRequestInternalFailure) {
  EXPECT_CALL(mock_key_store_, Write(_, _, _)).WillRepeatedly(Return(false));
  auto callback = [](const base::Closure& quit_closure,
                     const FinishCertificateRequestReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_certificate());
    quit_closure.Run();
  };
  AttestationCertificateRequest pca_request = GenerateCACertRequest();
  FinishCertificateRequestRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_pca_response(
      CreateCACertResponse(true, pca_request.message_id()));
  service_->FinishCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, FinishCertificateRequestWrongMessageId) {
  auto callback = [](const base::Closure& quit_closure,
                     const FinishCertificateRequestReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_certificate());
    quit_closure.Run();
  };
  // Generate some request to populate pending_requests, but ignore its fields.
  GenerateCACertRequest();
  FinishCertificateRequestRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_pca_response(CreateCACertResponse(true, "wrong_id"));
  service_->FinishCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, FinishCertificateRequestServerFailure) {
  auto callback = [](const base::Closure& quit_closure,
                     const FinishCertificateRequestReply& reply) {
    EXPECT_NE(STATUS_SUCCESS, reply.status());
    EXPECT_FALSE(reply.has_certificate());
    quit_closure.Run();
  };
  // Generate some request to populate pending_requests, but ignore its fields.
  GenerateCACertRequest();
  FinishCertificateRequestRequest request;
  request.set_username("user");
  request.set_key_label("label");
  request.set_pca_response(CreateCACertResponse(false, ""));
  service_->FinishCertificateRequest(request,
                                     base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateEnrollRequestSuccessWithoutAbeData) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const CreateEnrollRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationEnrollmentRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ("wrapped_key",
              pca_request.encrypted_endorsement_credential().wrapped_key());
    EXPECT_EQ("public_key_tpm", pca_request.identity_public_key());
    EXPECT_EQ("pcr0", pca_request.pcr0_quote().quote());
    EXPECT_EQ("pcr1", pca_request.pcr1_quote().quote());
    EXPECT_FALSE(pca_request.has_enterprise_enrollment_nonce());
    quit_closure.Run();
  };
  CreateEnrollRequestRequest request;
  request.set_aca_type(aca_type_);
  service_->CreateEnrollRequest(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateEnrollRequestSuccessWithEmptyAbeData) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const CreateEnrollRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationEnrollmentRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ("wrapped_key",
              pca_request.encrypted_endorsement_credential().wrapped_key());
    EXPECT_EQ("public_key_tpm", pca_request.identity_public_key());
    EXPECT_EQ("pcr0", pca_request.pcr0_quote().quote());
    EXPECT_EQ("pcr1", pca_request.pcr1_quote().quote());
    EXPECT_FALSE(pca_request.has_enterprise_enrollment_nonce());
    quit_closure.Run();
  };
  brillo::SecureBlob abe_data;
  service_->set_abe_data(&abe_data);
  CreateEnrollRequestRequest request;
  request.set_aca_type(aca_type_);
  service_->CreateEnrollRequest(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, CreateEnrollRequestSuccessWithAbeData) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const CreateEnrollRequestReply& reply) {
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.has_pca_request());
    AttestationEnrollmentRequest pca_request;
    EXPECT_TRUE(pca_request.ParseFromString(reply.pca_request()));
    EXPECT_EQ(kTpmVersionUnderTest, pca_request.tpm_version());
    EXPECT_EQ("wrapped_key",
              pca_request.encrypted_endorsement_credential().wrapped_key());
    EXPECT_EQ("public_key_tpm", pca_request.identity_public_key());
    EXPECT_EQ("pcr0", pca_request.pcr0_quote().quote());
    EXPECT_EQ("pcr1", pca_request.pcr1_quote().quote());
    EXPECT_TRUE(pca_request.has_enterprise_enrollment_nonce());

    // Mocked CryptoUtility->HmacSha256 returns always a zeroed buffer.
    EXPECT_EQ(std::string(32, '\0'), pca_request.enterprise_enrollment_nonce());
    quit_closure.Run();
  };

  CreateEnrollRequestRequest request;
  request.set_aca_type(aca_type_);
  brillo::SecureBlob abe_data(0xCA, 32);
  service_->set_abe_data(&abe_data);
  service_->CreateEnrollRequest(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollSuccess) {
  SetUpIdentity(identity_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    quit_closure.Run();
  };

  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollSuccessNoop) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    quit_closure.Run();
  };
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(0);
  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollSuccessForced) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    quit_closure.Run();
  };

  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  request.set_forced(true);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollFailureNoIdentity) {
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(0);
  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollFailureBadPcaAgentStatus) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };

  fake_pca_agent_proxy_.SetEnrollDBusError();
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollFailureBadPcaAgentResponse) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_INVALID_PARAMETER);
    quit_closure.Run();
  };
  fake_pca_agent_proxy_.SetBadEnrollStatus(STATUS_INVALID_PARAMETER);
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, EnrollFailureBadPcaServerResponse) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_REQUEST_DENIED_BY_CA);
    quit_closure.Run();
  };

  fake_pca_agent_proxy_.SetBadEnrollPcaResponse();
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  service_->Enroll(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateSuccess) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    EXPECT_TRUE(reply.has_certificate());
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));

  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateSuccessNoop) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    EXPECT_TRUE(reply.has_public_key());
    EXPECT_TRUE(reply.has_certificate());
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(GenerateSerializedFakeCertifiedKey()),
                      Return(true)));
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(0);
  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateSuccessSavedBadPublicKey) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(DoAll(SetArgPointee<2>(GenerateSerializedFakeCertifiedKey()),
                      Return(true)));
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(0);
  EXPECT_CALL(mock_crypto_utility_, GetRSASubjectPublicKeyInfo(_, _))
      .WillOnce(Return(false));
  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateSuccessForced) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    EXPECT_TRUE(reply.has_certificate());
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  request.set_forced(true);
  // We shouldn't even check the key store.
  EXPECT_CALL(mock_key_store_, Read("user", "label", _)).Times(0);

  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateFailureNoIdentity) {
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(0);
  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateFailureBadPcaAgentStatus) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));
  brillo::ErrorPtr err = brillo::Error::Create(base::Location(), "", "", "");
  fake_pca_agent_proxy_.SetGetCertificateDBusError();
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateFailureBadPcaAgentResponse) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_NOT_AVAILABLE);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));

  pca_agent::GetCertificateReply reply;
  fake_pca_agent_proxy_.SetBadGetCertificateStatus(STATUS_NOT_AVAILABLE);
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, GetCertificateFailureBadPcaServerResponse) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_REQUEST_DENIED_BY_CA);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));

  fake_pca_agent_proxy_.SetBadGetCertificatePcaResponse();
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, AttestationFlowSuccess) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    EXPECT_TRUE(reply.has_certificate());
    EXPECT_TRUE(reply.has_public_key());
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  request.set_shall_trigger_enrollment(true);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));

  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, AttestationFlowBadPublicKey) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  request.set_shall_trigger_enrollment(true);
  EXPECT_CALL(mock_key_store_, Read("user", "label", _))
      .WillOnce(Return(false));

  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);
  EXPECT_CALL(mock_crypto_utility_, GetRSASubjectPublicKeyInfo(_, _))
      .WillOnce(Return(false));

  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

TEST_P(AttestationServiceTest, AttestationFlowFailureNotEnrolled) {
  SetUpIdentity(identity_);
  auto callback = [](const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
    quit_closure.Run();
  };
  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(0);
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(0);
  service_->GetCertificate(request, base::Bind(callback, QuitClosure()));
  Run();
}

// the extensive unittests that are worth being kept but unable to be in the
// standard set of unittest for any reason, e.g., flakiness.
#ifdef EXTENSIVE_UNITTEST

TEST_P(AttestationServiceTest, EnrollSuccessQueued) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");

  // Offset by 1; for enrollment request the request under process doesn't
  // count.
  int request_count = service_->kEnrollmentRequestLimit + 1;
  auto callback = [](int* count, const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    *count -= 1;
    if (*count == 0) {
      quit_closure.Run();
    }
  };

  auto failure_callback = [](const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
  };

  fake_pca_agent_proxy_.SetEnrollCallbackDelay(
      base::TimeDelta::FromMilliseconds(125));
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  request.set_forced(true);
  for (int i = 0; i < request_count; ++i) {
    service_->Enroll(request,
                     base::Bind(callback, &request_count, QuitClosure()));
  }
  // Reaching the limit, this request should get error.
  service_->Enroll(request, base::Bind(failure_callback));
  Run();
  ASSERT_EQ(request_count, 0);
}

TEST_P(AttestationServiceTest, EnrollFailureQueued) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);
  (*mock_database_.GetMutableProtobuf()
        ->mutable_credentials()
        ->mutable_encrypted_endorsement_credentials())[aca_type_]
      .set_wrapped_key("wrapped_key");

  // Offset by 1; for enrollment request the request under process doesn't
  // count.
  int request_count = service_->kEnrollmentRequestLimit + 1;
  auto callback = [](int* count, const base::Closure& quit_closure,
                     const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_INVALID_PARAMETER);
    *count -= 1;
    if (*count == 0) {
      quit_closure.Run();
    }
  };

  auto failure_callback = [](const EnrollReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
  };

  fake_pca_agent_proxy_.SetBadEnrollStatus(STATUS_INVALID_PARAMETER);
  fake_pca_agent_proxy_.SetEnrollCallbackDelay(
      base::TimeDelta::FromMilliseconds(125));
  EXPECT_CALL(fake_pca_agent_proxy_, EnrollAsync(_, _, _, _)).Times(1);

  EnrollRequest request;
  request.set_aca_type(aca_type_);
  request.set_forced(true);
  for (int i = 0; i < request_count; ++i) {
    service_->Enroll(request,
                     base::Bind(callback, &request_count, QuitClosure()));
  }
  // Reaching the limit, this request should get error.
  service_->Enroll(request, base::Bind(failure_callback));
  Run();
  ASSERT_EQ(request_count, 0);
}

TEST_P(AttestationServiceTest, GetCertificateSuccessQueued) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);

  int request_count = service_->kCertificateRequestAliasLimit;
  auto callback = [](int* count, const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_SUCCESS);
    *count -= 1;
    if (*count == 0) {
      quit_closure.Run();
    }
  };
  auto failure_callback = [](const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
  };

  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  request.set_forced(true);
  // We shouldn't even check the key store.
  EXPECT_CALL(mock_key_store_, Read("user", "label", _)).Times(0);

  fake_pca_agent_proxy_.SetGetCertificateCallbackDelay(
      base::TimeDelta::FromMilliseconds(125));
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  for (int i = 0; i < request_count; ++i) {
    service_->GetCertificate(
        request, base::Bind(callback, &request_count, QuitClosure()));
  }
  // This should due to alias contention.
  service_->GetCertificate(request, base::Bind(failure_callback));
  Run();
  ASSERT_EQ(request_count, 0);
}

TEST_P(AttestationServiceTest, GetCertificateFailureQueued) {
  SetUpIdentity(identity_);
  SetUpIdentityCertificate(identity_, aca_type_);

  int request_count = service_->kCertificateRequestAliasLimit;
  auto callback = [](int* count, const base::Closure& quit_closure,
                     const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_NOT_AVAILABLE);
    *count -= 1;
    if (*count == 0) {
      quit_closure.Run();
    }
  };
  auto failure_callback = [](const GetCertificateReply& reply) {
    EXPECT_EQ(reply.status(), STATUS_UNEXPECTED_DEVICE_ERROR);
  };

  GetCertificateRequest request;
  request.set_aca_type(aca_type_);
  request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE);
  request.set_username("user");
  request.set_request_origin("origin");
  request.set_key_label("label");
  request.set_forced(true);
  // We shouldn't even check the key store.
  EXPECT_CALL(mock_key_store_, Read("user", "label", _)).Times(0);

  fake_pca_agent_proxy_.SetBadGetCertificateStatus(STATUS_NOT_AVAILABLE);
  fake_pca_agent_proxy_.SetGetCertificateCallbackDelay(
      base::TimeDelta::FromMilliseconds(125));
  EXPECT_CALL(fake_pca_agent_proxy_, GetCertificateAsync(_, _, _, _)).Times(1);

  for (int i = 0; i < request_count; ++i) {
    service_->GetCertificate(
        request, base::Bind(callback, &request_count, QuitClosure()));
  }
  // This should due to alias contention.
  service_->GetCertificate(request, base::Bind(failure_callback));
  Run();
  ASSERT_EQ(request_count, 0);
}

#endif

INSTANTIATE_TEST_SUITE_P(AcaType,
                         AttestationServiceTest,
                         ::testing::Values(DEFAULT_ACA, TEST_ACA));

}  // namespace attestation
