// Copyright (c) 2012 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 "cryptohome/attestation.h"

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <brillo/data_encoding.h>
#include <brillo/http/http_transport_fake.h>
#include <brillo/mime_utils.h>
#include <brillo/secure_blob.h>
#include <gmock/gmock.h>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>

#include "cryptohome/crypto.h"
#include "cryptohome/cryptolib.h"
#include "cryptohome/mock_install_attributes.h"
#include "cryptohome/mock_keystore.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_tpm_init.h"

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

using base::FilePath;
using brillo::Blob;
using brillo::SecureBlob;
using google::protobuf::util::MessageDifferencer;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StartsWith;
using ::testing::WithArgs;

namespace cryptohome {

static const char* kTestPath = "/tmp/attestation_test.epb";
static const char* kTestUser = "test_user";

static const char kABEData[] =
    "2eac34fa74994262b907c15a3a1462e349e5108ca0d0e807f4b1a3ee741a5594";
static const char kDEN[] =
    "865cc962ffe14b3638b2d1f860e77b531644a3aba67e52e49e1f6c0a31d81daf";
static const char kEID[] =
    "809c6c9f425c59b86e551f4e8fdccd5a2200b08fe3250c4971f40d8bbcf7820a";

class AttestationBaseTest : public testing::Test {
 public:
  AttestationBaseTest() : crypto_(&platform_), attestation_() {
    crypto_.set_tpm(&tpm_);
    crypto_.set_use_tpm(true);
  }
  virtual ~AttestationBaseTest() {
    if (rsa_)
      RSA_free(rsa_);
  }

  void SetUpAttestation(Attestation* attestation) {
    attestation->set_database_path(kTestPath);
    attestation->set_key_store(&key_store_);
  }

  void SetUp() override {
    SetUpAttestation(&attestation_);
    http_transport_ = std::make_shared<brillo::http::fake::Transport>();
    attestation_.set_http_transport(http_transport_);
    // Fake up a single file by default.
    ON_CALL(platform_,
            WriteStringToFileAtomicDurable(
                Property(&FilePath::value, StartsWith(kTestPath)), _, _))
        .WillByDefault(
            WithArgs<1>(Invoke(this, &AttestationBaseTest::WriteDB)));
    ON_CALL(
        platform_,
        ReadFileToString(Property(&FilePath::value, StartsWith(kTestPath)), _))
        .WillByDefault(WithArgs<1>(Invoke(this, &AttestationBaseTest::ReadDB)));
    // Configure a TPM that is ready.
    ON_CALL(tpm_, IsEnabled()).WillByDefault(Return(true));
    ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));
    ON_CALL(tpm_, IsBeingOwned()).WillByDefault(Return(false));
    Initialize();
  }

  virtual void Initialize() {
    attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
                            &install_attributes_,
                            brillo::SecureBlob() /* abe_data */,
                            false /* retain_endorsement_data */);
  }

  virtual bool WriteDB(const std::string& db) {
    serialized_db_.assign(db);
    return true;
  }

  virtual bool ReadDB(std::string* db) {
    if (serialized_db_.empty()) {
      return false;
    }
    db->assign(serialized_db_);
    return true;
  }

  virtual bool ComputeEnterpriseEnrollmentId(brillo::SecureBlob* blob) {
    return attestation_.ComputeEnterpriseEnrollmentId(blob);
  }

  virtual std::string GetValidEndorsementKey() {
    const std::string hex_ek =
        "3082010A0282010100D3EE9D14FAC4C42B35FEDC87363CC29807A3F39D3E45D2"
        "49586F620C6425CE981E8619DCE50D964E934A1F1FD2C1066418DD75D8916D85"
        "DD9E82C27C82A8C2C9BC76BA914B5A43F7535AEAA2F7BD985F46A46C92334643"
        "C89F5598ABD191AA5439088778774DB3B07FD08F019997893BEC1A87571AC95F"
        "66ADE2F3631A2C9CF8EF0B94D2CA62E81F1FF9CC71339838E229E63CA59E0BB6"
        "4D2134C3AF705BCF0F614E58DF848897454FFA2FA42073F80174C1D3D0C54D5B"
        "DC45747FE662D6D321AEA5375F0AE489DF6ABB018D5D11707E546E8487641290"
        "F9F9B3CC3A1F8631FB0F3486A875F6005D3539A5823F7618B007779FB31CFB7F"
        "E36A1C2D9DEFD8F5030203010001";
    std::vector<uint8_t> ek_bytes;
    base::HexStringToBytes(hex_ek, &ek_bytes);
    return std::string(ek_bytes.begin(), ek_bytes.end());
  }

 protected:
  std::string serialized_db_;
  NiceMock<MockTpm> tpm_;
  NiceMock<MockTpmInit> tpm_init_;
  NiceMock<MockPlatform> platform_;
  Crypto crypto_;
  NiceMock<MockKeyStore> key_store_;
  NiceMock<MockInstallAttributes> install_attributes_;
  std::shared_ptr<brillo::http::fake::Transport> http_transport_;
  Attestation attestation_;
  RSA* rsa_ = nullptr;  // Access with rsa().
  bool is_enterprise_setup_ = false;

  RSA* rsa() {
    if (!rsa_) {
      rsa_ = RSA_generate_key(2048, 65537, nullptr, nullptr);
      CHECK(rsa_);
    }
    return rsa_;
  }

  virtual void SetUpEnterprise() {
    if (!is_enterprise_setup_) {
      attestation_.set_enterprise_test_keys(Attestation::kDefaultVA,
          RSA_generate_key(2048, 65537, nullptr, nullptr),
          RSA_generate_key(2048, 65537, nullptr, nullptr));
      attestation_.set_enterprise_test_keys(Attestation::kTestVA,
          RSA_generate_key(2048, 65537, nullptr, nullptr),
          RSA_generate_key(2048, 65537, nullptr, nullptr));
      is_enterprise_setup_ = true;
    }
  }

  RSA* enterprise_signing_rsa(Attestation::VAType va_type) {
    SetUpEnterprise();
    return attestation_.GetEnterpriseSigningKey(va_type);
  }

  RSA* enterprise_encryption_rsa(Attestation::VAType va_type) {
    SetUpEnterprise();
    return attestation_.GetEnterpriseEncryptionKey(va_type);
  }

  SecureBlob GetEnrollBlob() {
    AttestationEnrollmentResponse pb;
    pb.set_status(OK);
    pb.set_detail("");
    pb.mutable_encrypted_identity_credential()->set_asym_ca_contents("1234");
    pb.mutable_encrypted_identity_credential()->set_sym_ca_attestation("5678");
    std::string tmp;
    pb.SerializeToString(&tmp);
    return SecureBlob(tmp.begin(), tmp.end());
  }

  SecureBlob GetCertRequestBlob(const SecureBlob& request) {
    AttestationCertificateRequest request_pb;
    CHECK(request_pb.ParseFromArray(request.data(), request.size()));
    AttestationCertificateResponse pb;
    pb.set_message_id(request_pb.message_id());
    pb.set_status(OK);
    pb.set_detail("");
    pb.set_certified_key_credential("response_cert");
    pb.set_intermediate_ca_cert("response_ca_cert");
    std::string tmp;
    pb.SerializeToString(&tmp);
    return SecureBlob(tmp.begin(), tmp.end());
  }

  SecureBlob GetCertifiedKeyBlob(const std::string& payload,
                                 bool include_ca_cert) {
    CertifiedKey pb;
    pb.set_certified_key_credential("stored_cert");
    if (include_ca_cert)
      pb.set_intermediate_ca_cert("stored_ca_cert");
    pb.set_public_key(GetPKCS1PublicKey().to_string());
    pb.set_payload(payload);
    std::string tmp;
    pb.SerializeToString(&tmp);
    return SecureBlob(tmp.begin(), tmp.end());
  }

  bool CompareBlob(const SecureBlob& blob, const std::string& str) {
    return (blob.to_string() == str);
  }

  std::string EncodeCertChain(const std::string& cert1,
                              const std::string& cert2) {
    std::string chain = "-----BEGIN CERTIFICATE-----\n";
    chain += brillo::data_encoding::Base64EncodeWrapLines(cert1);
    chain += "-----END CERTIFICATE-----";
    if (!cert2.empty()) {
      chain += "\n-----BEGIN CERTIFICATE-----\n";
      chain += brillo::data_encoding::Base64EncodeWrapLines(cert2);
      chain += "-----END CERTIFICATE-----";
    }
    return chain;
  }

  SecureBlob GetPKCS1PublicKey() {
    unsigned char* buffer = nullptr;
    int length = i2d_RSAPublicKey(rsa(), &buffer);
    if (length <= 0)
      return SecureBlob();
    SecureBlob tmp(buffer, buffer + length);
    OPENSSL_free(buffer);
    return tmp;
  }

  SecureBlob GetX509PublicKey() {
    unsigned char* buffer = nullptr;
    int length = i2d_RSA_PUBKEY(rsa(), &buffer);
    if (length <= 0)
      return SecureBlob();
    SecureBlob tmp(buffer, buffer + length);
    OPENSSL_free(buffer);
    return tmp;
  }

  bool VerifySimpleChallenge(const SecureBlob& response,
                             const std::string& challenge,
                             const std::string& signature) {
    SignedData signed_data;
    if (!signed_data.ParseFromArray(response.data(), response.size()))
      return false;
    if (signed_data.data().find(challenge) != 0 ||
        signed_data.data() == challenge)
      return false;
    if (signed_data.signature() != signature)
      return false;
    return true;
  }

  bool VerifyEnterpriseVaChallenge(Attestation::VAType va_type,
                                   const SecureBlob& response,
                                   KeyType key_type,
                                   const std::string& domain,
                                   const std::string& device_id,
                                   const std::string& cert_chain,
                                   const std::string& signature) {
    SignedData signed_data;
    if (!signed_data.ParseFromArray(response.data(), response.size()))
      return false;
    ChallengeResponse response_pb;
    if (!response_pb.ParseFromString(signed_data.data()))
      return false;
    std::string expected_challenge = GetEnterpriseVaChallenge(
        va_type, "EnterpriseKeyChallenge", false).to_string();
    if (response_pb.challenge().data() != expected_challenge)
      return false;
    std::string key_info;
    if (!DecryptEnterpriseData(va_type, response_pb.encrypted_key_info(),
                               &key_info))
      return false;
    KeyInfo key_info_pb;
    if (!key_info_pb.ParseFromString(key_info))
      return false;
    if (key_info_pb.domain() != domain ||
        key_info_pb.device_id() != device_id ||
        key_info_pb.key_type() != key_type ||
        key_info_pb.certificate() != cert_chain)
      return false;
    if (signed_data.signature() != signature)
      return false;
    return true;
  }

  SecureBlob GetEnterpriseVaChallenge(Attestation::VAType va_type,
                                    const std::string& prefix,
                                    bool sign) {
    Challenge challenge;
    challenge.set_prefix(prefix);
    challenge.set_nonce("nonce");
    challenge.set_timestamp(123456789);
    std::string serialized;
    challenge.SerializeToString(&serialized);
    if (sign) {
      unsigned char buffer[256];
      unsigned int length = 0;
      SecureBlob digest = CryptoLib::Sha256(SecureBlob(serialized));
      RSA_sign(NID_sha256,
               digest.data(), digest.size(),
               buffer, &length,
               enterprise_signing_rsa(va_type));
      SignedData signed_challenge;
      signed_challenge.set_data(serialized);
      signed_challenge.set_signature(buffer, length);
      signed_challenge.SerializeToString(&serialized);
    }
    return SecureBlob(serialized);
  }

  bool DecryptEnterpriseData(Attestation::VAType va_type,
                             const EncryptedData& input,
                             std::string* output) {
    // Unwrap the AES key.
    unsigned char* wrapped_key_buffer = reinterpret_cast<unsigned char*>(
        const_cast<char*>(input.wrapped_key().data()));
    unsigned char buffer[256];
    int length = RSA_private_decrypt(input.wrapped_key().size(),
                                     wrapped_key_buffer,
                                     buffer,
                                     enterprise_encryption_rsa(va_type),
                                     RSA_PKCS1_OAEP_PADDING);
    if (length != 32)
      return false;
    SecureBlob aes_key(buffer, buffer + length);
    // Decrypt the blob.
    SecureBlob decrypted;
    brillo::Blob encrypted = brillo::BlobFromString(input.encrypted_data());
    SecureBlob aes_iv = SecureBlob(input.iv());
    if (!CryptoLib::AesDecryptSpecifyBlockMode(encrypted, 0, encrypted.size(),
                                               aes_key, aes_iv,
                                               CryptoLib::kPaddingStandard,
                                               CryptoLib::kCbc,
                                               &decrypted))
      return false;
    *output = decrypted.to_string();
    return true;
  }

  // Returns a copy of the database as it exists on 'disk'.
  AttestationDatabase GetPersistentDatabase() {
    AttestationDatabase db;
    attestation_.DecryptDatabase(serialized_db_, &db);
    return db;
  }

  // Returns a mutable reference to the current database instance.  If a test is
  // verifying database changes it should use GetPersistentDatabase() so it will
  // also verify that the changes are written to disk correctly.
  AttestationDatabase& GetMutableDatabase() {
    return attestation_.database_pb_;
  }

  // Verify Privacy CA-related data, including the default CA's identity
  // credential.
  void VerifyPCAData(const AttestationDatabase& db,
                     const char* default_identity_credential) {
    ASSERT_EQ(default_identity_credential ? 1 : 0,
              db.identity_certificates().size());
    for (int pca = 0; pca < db.identity_certificates().size(); ++pca) {
      const AttestationDatabase::IdentityCertificate identity_certificate =
          db.identity_certificates().at(pca);
      ASSERT_EQ(0, identity_certificate.identity());
      ASSERT_EQ(pca, identity_certificate.aca());
      if (default_identity_credential && pca == Attestation::kDefaultPCA) {
        ASSERT_EQ(default_identity_credential,
                  identity_certificate.identity_credential());
      } else {
        ASSERT_FALSE(identity_certificate.has_identity_credential());
      }
    }
    // All PCAs have encrypted credentials.
    for (int pca = Attestation::kDefaultPCA; pca < Attestation::kMaxPCAType;
         ++pca) {
      ASSERT_TRUE(
          db.credentials().encrypted_endorsement_credentials().count(pca));
    }
  }

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

  // Gets the Google Privacy CA web-origin -- this can change depending on
  // whether the test server is being targeted.
  std::string GetPCAWebOrigin(Attestation::PCAType pca_type) const {
    switch (pca_type) {
      default:
      case Attestation::kDefaultPCA:
        return attestation_.kDefaultPCAWebOrigin;
      case Attestation::kTestPCA:
        return attestation_.kTestPCAWebOrigin;
    }
  }

  size_t GetDigestSize() const { return Attestation::kDigestSize; }
};

TEST_F(AttestationBaseTest, NotPreparedForEnrollment) {
  ASSERT_FALSE(attestation_.IsPreparedForEnrollment());
}

TEST_F(AttestationBaseTest, PrepareForEnrollment) {
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.IsPreparedForEnrollment());
  AttestationDatabase db = GetPersistentDatabase();
  // One identity has been created.
  EXPECT_EQ(1, db.identities().size());
  const AttestationDatabase::Identity& identity_data = db.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(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            identity_data.features());
  // Deprecated identity-related values have not been set.
  EXPECT_FALSE(db.has_identity_binding());
  EXPECT_FALSE(db.has_identity_key());
  EXPECT_FALSE(db.has_pcr0_quote());
  EXPECT_FALSE(db.has_pcr1_quote());
  // We have a delegate to activate the AIK.
  EXPECT_TRUE(db.has_delegate());
  // Verify Privacy CA-related data.
  VerifyPCAData(db);
  // These deprecated fields have not been set either.
  EXPECT_TRUE(db.has_credentials());
  EXPECT_FALSE(db.credentials().has_default_encrypted_endorsement_credential());
}

TEST_F(AttestationBaseTest, PrepareForEnrollmentNoIdentityFeatures) {
  attestation_.set_default_identity_features_for_test(NO_IDENTITY_FEATURES);
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.IsPreparedForEnrollment());
  AttestationDatabase db = GetPersistentDatabase();
  // One identity has been created.
  EXPECT_EQ(1, db.identities().size());
  const AttestationDatabase::Identity& identity_data =
      db.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(NO_IDENTITY_FEATURES, identity_data.features());
  // Deprecated identity-related values have not been set.
  EXPECT_FALSE(db.has_identity_binding());
  EXPECT_FALSE(db.has_identity_key());
  EXPECT_FALSE(db.has_pcr0_quote());
  EXPECT_FALSE(db.has_pcr1_quote());
  // We have a delegate to activate the AIK.
  EXPECT_TRUE(db.has_delegate());
  // Verify Privacy CA-related data.
  VerifyPCAData(db);
  // These deprecated fields have not been set either.
  EXPECT_TRUE(db.has_credentials());
  EXPECT_FALSE(db.credentials().has_default_encrypted_endorsement_credential());
}

TEST_F(AttestationBaseTest, IdentityCertificateMapIsDeepCopied) {
  SecureBlob blob;
  EXPECT_FALSE(
      attestation_.CreateEnrollRequest(Attestation::kDefaultPCA, &blob));
  attestation_.PrepareForEnrollment();
  EXPECT_FALSE(attestation_.HasIdentityCertificate(Attestation::kFirstIdentity,
                                                   Attestation::kDefaultPCA));
  EXPECT_TRUE(
      attestation_.CreateEnrollRequest(Attestation::kDefaultPCA, &blob));
  EXPECT_TRUE(attestation_.Enroll(Attestation::kDefaultPCA, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.HasIdentityCertificate(Attestation::kFirstIdentity,
                                                  Attestation::kDefaultPCA));
  // Check that the identity certificate map is not the same as what the
  // database contains.
  Attestation::IdentityCertificateMap map =
      attestation_.GetIdentityCertificateMap();
  AttestationDatabase db = GetPersistentDatabase();
  db.mutable_identity_certificates()->at(Attestation::kDefaultPCA).set_aca(
      Attestation::kMaxPCAType);
  EXPECT_EQ(Attestation::kDefaultPCA, map.at(Attestation::kDefaultPCA).aca());
}

// Tests DeleteKeysByPrefix with device-wide keys stored in the attestation db.
TEST_F(AttestationBaseTest, DeleteByPrefixDevice) {
  // Test with an empty db.
  ASSERT_TRUE(attestation_.DeleteKeysByPrefix(false, "", "prefix"));

  // Test with a single matching key.
  AttestationDatabase& db = GetMutableDatabase();
  db.add_device_keys()->set_key_name("prefix1");
  ASSERT_TRUE(attestation_.DeleteKeysByPrefix(false, "", "prefix"));
  EXPECT_EQ(0, db.device_keys_size());

  // Test with a single non-matching key.
  db.add_device_keys()->set_key_name("other");
  ASSERT_TRUE(attestation_.DeleteKeysByPrefix(false, "", "prefix"));
  EXPECT_EQ(1, db.device_keys_size());

  // Test with an empty prefix.
  ASSERT_TRUE(attestation_.DeleteKeysByPrefix(false, "", ""));
  EXPECT_EQ(0, db.device_keys_size());

  // Test with multiple matching / non-matching keys.
  db.add_device_keys()->set_key_name("prefix1");
  db.add_device_keys()->set_key_name("other1");
  db.add_device_keys()->set_key_name("prefix2");
  db.add_device_keys()->set_key_name("other2");
  db.add_device_keys()->set_key_name("prefix3");
  db.add_device_keys()->set_key_name("other3");
  db.add_device_keys()->set_key_name("prefix4");

  ASSERT_TRUE(attestation_.DeleteKeysByPrefix(false, "", "prefix"));

  EXPECT_EQ(3, db.device_keys_size());
  for (int i = 0; i < db.device_keys_size(); ++i) {
    EXPECT_EQ(0, db.device_keys(i).key_name().find("other"));
  }
}

// Tests DeleteKeysByPrefix with user-owned keys. This object does not manage
// user-owned keys so the test is trivial.
TEST_F(AttestationBaseTest, DeleteByPrefixUser) {
  EXPECT_TRUE(attestation_.DeleteKeysByPrefix(true, kTestUser, "prefix"));
}

TEST_F(AttestationBaseTest, GetEKInfo) {
  std::string info;
  EXPECT_TRUE(attestation_.GetEKInfo(&info));
  EXPECT_TRUE(base::IsStringASCII(info));

  // Simulate owner password not available.
  EXPECT_CALL(tpm_, GetEndorsementCredential(_))
      .WillRepeatedly(Return(false));
  info.clear();
  EXPECT_FALSE(attestation_.GetEKInfo(&info));
  EXPECT_EQ(0, info.size());
}

TEST_F(AttestationBaseTest, FinalizeEndorsementData) {
  // Simulate first login.
  attestation_.PrepareForEnrollment();
  // Expect endorsement data to be available.
  AttestationDatabase db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials() &&
              db.credentials().has_endorsement_public_key() &&
              db.credentials().has_endorsement_credential());

  // Simulate second login.
  attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
      &install_attributes_, brillo::SecureBlob() /* abe_data */,
      false /* retain_endorsement_data */);
  // Expect endorsement data to be no longer available.
  db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials() &&
              !db.credentials().has_endorsement_public_key() &&
              !db.credentials().has_endorsement_credential());
}

TEST_F(AttestationBaseTest, RetainEndorsementData) {
  // Simulate first login.
  attestation_.PrepareForEnrollment();
  // Expect endorsement data to be available.
  AttestationDatabase db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials() &&
              db.credentials().has_endorsement_public_key() &&
              db.credentials().has_endorsement_credential());

  // Simulate second login.
  attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
      &install_attributes_, brillo::SecureBlob() /* abe_data */,
      true /* retain_endorsement_data */);
  // Expect endorsement data to be still available.
  db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials() &&
              db.credentials().has_endorsement_public_key() &&
              db.credentials().has_endorsement_credential());

  attestation_.FinalizeEndorsementData();
  // Expect endorsement data to be still available.
  db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials() &&
              db.credentials().has_endorsement_public_key() &&
              db.credentials().has_endorsement_credential());
}

TEST_F(AttestationBaseTest, MigrateAttestationDatabase) {
  // Simulate first login.
  attestation_.PrepareForEnrollment();

  // Simulate an older database.
  AttestationDatabase db = GetPersistentDatabase();
  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("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.
  attestation_.PersistDatabase(db);

  // Simulate second login.
  Initialize();
  attestation_.PrepareForEnrollment();
  db = GetPersistentDatabase();

  // The default encrypted endorsement credential has been migrated.
  // The deprecated field has not been cleared so that older code can still
  // use the database.
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().encrypted_endorsement_credentials().at(
          Attestation::kDefaultPCA)));
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().default_encrypted_endorsement_credential()));

  // 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 =
      db.identities().Get(Attestation::kDefaultPCA);
  EXPECT_EQ(IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID,
            default_identity_data.features());
  ASSERT_EQ("identity_binding",
            default_identity_data.identity_binding().identity_binding());
  ASSERT_EQ("identity_public_key",
            default_identity_data.identity_binding().identity_public_key());
  ASSERT_EQ("identity_binding", db.identity_binding().identity_binding());
  ASSERT_EQ("identity_public_key", db.identity_binding().identity_public_key());
  ASSERT_EQ("pcr0_quote", default_identity_data.pcr_quotes().at(0).quote());
  EXPECT_EQ("pcr0_quote", db.pcr0_quote().quote());
  ASSERT_EQ("pcr1_quote", default_identity_data.pcr_quotes().at(1).quote());
  EXPECT_EQ("pcr1_quote", db.pcr1_quote().quote());

  // No other identity has been created.
  ASSERT_EQ(1, 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.
  ASSERT_FALSE(default_identity_data.identity_key().has_identity_credential());
  ASSERT_EQ("identity_cred", db.identity_key().identity_credential());
  VerifyPCAData(db, "identity_cred");
}

TEST_F(AttestationBaseTest, MigrateAttestationDatabaseWithCorruptedFields) {
  // Simulate first login.
  attestation_.PrepareForEnrollment();

  // Simulate an older database.
  AttestationDatabase db = GetPersistentDatabase();
  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("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.
  attestation_.PersistDatabase(db);

  // Simulate second login.
  Initialize();
  attestation_.PrepareForEnrollment();
  db = GetPersistentDatabase();

  // The default encrypted endorsement credential has been migrated.
  // The deprecated field has not been cleared so that older code can still
  // use the database.
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().encrypted_endorsement_credentials().at(
          Attestation::kDefaultPCA)));
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().default_encrypted_endorsement_credential()));

  // 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(db.identities().empty());
  ASSERT_EQ("identity_binding", db.identity_binding().identity_binding());
  ASSERT_EQ("identity_public_key", db.identity_binding().identity_public_key());
  EXPECT_EQ("pcr1_quote", db.pcr1_quote().quote());

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

TEST_F(AttestationBaseTest,
       MigrateAttestationDatabaseAllEndorsementCredentials) {
  // Simulate first login.
  attestation_.PrepareForEnrollment();

  // Simulate an older database.
  AttestationDatabase db = GetPersistentDatabase();
  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("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.
  attestation_.PersistDatabase(db);

  // Simulate second login.
  Initialize();
  attestation_.PrepareForEnrollment();
  db = GetPersistentDatabase();

  // The encrypted endorsement credentials have both been migrated.
  // The deprecated fields have not been cleared so that older code can still
  // use the database.
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().encrypted_endorsement_credentials().at(
          Attestation::kDefaultPCA)));
  ASSERT_TRUE(MessageDifferencer::Equals(
      default_encrypted_endorsement_credential,
      db.credentials().default_encrypted_endorsement_credential()));
  ASSERT_TRUE(MessageDifferencer::Equals(
      test_encrypted_endorsement_credential,
      db.credentials().encrypted_endorsement_credentials().at(
          Attestation::kTestPCA)));
  ASSERT_TRUE(MessageDifferencer::Equals(
      test_encrypted_endorsement_credential,
      db.credentials().test_encrypted_endorsement_credential()));
}

TEST_F(AttestationBaseTest, CertChainWithNoIntermediateCA) {
  EXPECT_CALL(key_store_, Read(true, kTestUser, "test", _))
      .WillRepeatedly(DoAll(
          SetArgPointee<3>(GetCertifiedKeyBlob("", false)),
          Return(true)));
  SecureBlob blob;
  EXPECT_TRUE(attestation_.GetCertificateChain(true, kTestUser, "test",
                                               &blob));
  EXPECT_TRUE(CompareBlob(blob, EncodeCertChain("stored_cert", "")));
}

TEST_F(AttestationBaseTest, IdentityResetRequest) {
  SecureBlob blob;
  EXPECT_TRUE(attestation_.GetIdentityResetRequest("token", &blob));
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.GetIdentityResetRequest("token", &blob));
}

// A test class which does not initialize the Attestation instance.
class AttestationBaseTestNoInitialize : public AttestationBaseTest {
 public:
  void Initialize() override {}
};

TEST_F(AttestationBaseTestNoInitialize, AutoExtendPCR1) {
  Blob default_pcr(GetDigestSize());
  EXPECT_CALL(tpm_, ReadPCR(1, _))
      .WillOnce(DoAll(SetArgPointee<1>(default_pcr), Return(true)));
  std::string fake_hwid = "hwid";
  Blob fake_hwid_expected_extension;
  ASSERT_TRUE(base::HexStringToBytes(
      "bc45e91a086497cd817cb3024ac5c0d733111a74378257b11991e1e435b7e71e",
      &fake_hwid_expected_extension));
  fake_hwid_expected_extension.resize(GetDigestSize());
  EXPECT_CALL(tpm_, ExtendPCR(1, fake_hwid_expected_extension))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, GetHardwareID()).WillRepeatedly(Return(fake_hwid));
  // Now initialize and the mocks will complain if PCR1 is not extended.
  AttestationBaseTest::Initialize();
}

TEST_F(AttestationBaseTestNoInitialize, AutoExtendPCR1NoHwID) {
  Blob default_pcr(GetDigestSize());
  EXPECT_CALL(tpm_, ReadPCR(1, _))
      .WillOnce(DoAll(SetArgPointee<1>(default_pcr), Return(true)));
  std::string no_hwid = "";
  EXPECT_CALL(tpm_, ExtendPCR(_, _)).Times(0);
  EXPECT_CALL(platform_, GetHardwareID()).WillRepeatedly(Return(no_hwid));
  // Now initialize and the mocks will complain if PCR1 is extended.
  AttestationBaseTest::Initialize();
}

class AttestationEnrollmentIdTest : public AttestationBaseTest {
 public:
  void Initialize() override {
    SecureBlob abe_data;
    EXPECT_TRUE(base::HexStringToBytes(kABEData, &abe_data));
    attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
                            &install_attributes_, abe_data,
                            false /* retain_endorsement_data */);
  }
};

TEST_F(AttestationEnrollmentIdTest, GetEnterpriseEnrollmentId) {
  brillo::SecureBlob pubek(GetValidEndorsementKey());
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pubek), Return(true)));
  brillo::SecureBlob blob;
  EXPECT_TRUE(attestation_.GetEnterpriseEnrollmentId(&blob));
  EXPECT_EQ(kEID,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
}

TEST_F(AttestationEnrollmentIdTest, GetEnterpriseEnrollmentIdCached) {
  brillo::SecureBlob pubek(GetValidEndorsementKey());
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pubek), Return(true)));
  attestation_.PrepareForEnrollment();
  SecureBlob enroll_blob;
  EXPECT_TRUE(attestation_.CreateEnrollRequest(Attestation::kDefaultPCA,
                                               &enroll_blob));
  attestation_.Enroll(Attestation::kDefaultPCA, GetEnrollBlob());
  // Change abe_data.
  attestation_.Initialize(
      &tpm_, &tpm_init_, &platform_, &crypto_, &install_attributes_,
      brillo::SecureBlob("new_abe_data"), false /* retain_endorsement_data */);
  // GetEnterpriseEnrollmentId should return a cached EID.
  brillo::SecureBlob blob;
  EXPECT_TRUE(attestation_.GetEnterpriseEnrollmentId(&blob));
  EXPECT_EQ(kEID,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
  // The EID should be different if recomputed since the abe_data has changed.
  EXPECT_CALL(tpm_, GetEndorsementPublicKeyWithDelegate(_, _, _))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pubek), Return(true)));
  EXPECT_TRUE(attestation_.ComputeEnterpriseEnrollmentId(&blob));
  EXPECT_NE(kEID,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
}

TEST_F(AttestationEnrollmentIdTest, ComputeEnterpriseEnrollmentId) {
  brillo::SecureBlob pubek(GetValidEndorsementKey());
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillOnce(DoAll(SetArgPointee<0>(pubek), Return(true)));
  brillo::SecureBlob blob;
  EXPECT_TRUE(ComputeEnterpriseEnrollmentId(&blob));
  EXPECT_EQ(kEID,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
}

TEST_F(AttestationEnrollmentIdTest, ComputeEnterpriseEnrollmentIdHasDelegate) {
  attestation_.PrepareForEnrollment();
  brillo::SecureBlob pubek(GetValidEndorsementKey());
  EXPECT_CALL(tpm_, GetEndorsementPublicKeyWithDelegate(_, _, _))
      .WillOnce(DoAll(SetArgPointee<0>(pubek), Return(true)));
  brillo::SecureBlob blob;
  EXPECT_TRUE(ComputeEnterpriseEnrollmentId(&blob));
  EXPECT_EQ(kEID,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
}

TEST_F(AttestationEnrollmentIdTest, ComputeEnterpriseEnrollmentIdEmptyAbeData) {
  attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
                          &install_attributes_, brillo::SecureBlob(""),
                          false /* retain_endorsement_data */);
  brillo::SecureBlob blob;
  EXPECT_TRUE(ComputeEnterpriseEnrollmentId(&blob));
  EXPECT_EQ("", base::HexEncode(blob.data(), blob.size()));
}

TEST_F(AttestationEnrollmentIdTest, ComputeEnterpriseEnrollmentIdEmptyEkm) {
  brillo::SecureBlob pubek("");
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pubek), Return(true)));
  brillo::SecureBlob blob;
  EXPECT_TRUE(ComputeEnterpriseEnrollmentId(&blob));
  EXPECT_EQ("", base::HexEncode(blob.data(), blob.size()));
}

TEST_F(AttestationEnrollmentIdTest, ComputeEnterpriseEnrollmentIdFailToGetEkm) {
  brillo::SecureBlob pubek("ek");
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillOnce(DoAll(SetArgPointee<0>(pubek), Return(false)));
  brillo::SecureBlob blob;
  EXPECT_FALSE(ComputeEnterpriseEnrollmentId(&blob));
}

TEST_F(AttestationEnrollmentIdTest, CreateEnrollRequestCheckNonce) {
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.IsPreparedForEnrollment());
  brillo::SecureBlob enroll_request;
  EXPECT_TRUE(attestation_.CreateEnrollRequest(Attestation::kDefaultPCA,
                                               &enroll_request));
  AttestationEnrollmentRequest request_pb;
  ASSERT_TRUE(request_pb.ParseFromString(enroll_request.to_string()));
  ASSERT_TRUE(request_pb.has_enterprise_enrollment_nonce());
}

TEST_F(AttestationEnrollmentIdTest,
       CreateEnrollRequestNoIdentityFeaturesCheckNonce) {
  attestation_.set_default_identity_features_for_test(NO_IDENTITY_FEATURES);
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.IsPreparedForEnrollment());
  brillo::SecureBlob enroll_request;
  EXPECT_TRUE(attestation_.CreateEnrollRequest(Attestation::kDefaultPCA,
                                               &enroll_request));
  AttestationEnrollmentRequest request_pb;
  ASSERT_TRUE(request_pb.ParseFromString(enroll_request.to_string()));
  ASSERT_FALSE(request_pb.has_enterprise_enrollment_nonce());
}

class AttestationTest
    : public AttestationBaseTest,
      public testing::WithParamInterface<Attestation::PCAType> {
 public:
  void SetUp() override {
    AttestationBaseTest::SetUp();
    pca_type_ = GetParam();
  }

 protected:
  Attestation::PCAType pca_type_;
};

TEST_P(AttestationTest, FirstIdentityNotEnrolled) {
  ASSERT_FALSE(attestation_.HasIdentityCertificate(
                         Attestation::kFirstIdentity, pca_type_));
}

TEST_P(AttestationTest, NullTpm) {
  Crypto crypto(nullptr);
  InstallAttributes install_attributes(nullptr);
  Attestation without_tpm;
  without_tpm.Initialize(NULL, NULL, NULL, &crypto, &install_attributes,
                         brillo::SecureBlob() /* abe_data */,
                         false /* retain_endorsement_data */);
  without_tpm.PrepareForEnrollment();
  EXPECT_FALSE(without_tpm.IsPreparedForEnrollment());
  EXPECT_FALSE(without_tpm.Verify(false));
  EXPECT_FALSE(without_tpm.VerifyEK(false));
  EXPECT_FALSE(without_tpm.CreateEnrollRequest(pca_type_, NULL));
  EXPECT_FALSE(without_tpm.Enroll(pca_type_, SecureBlob()));
  EXPECT_FALSE(without_tpm.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", nullptr));
  EXPECT_FALSE(
      without_tpm.FinishCertRequest(SecureBlob(), false, "", "", nullptr));
  EXPECT_FALSE(without_tpm.SignEnterpriseChallenge(
      false, "", "", "", SecureBlob(), false, SecureBlob(), nullptr));
  EXPECT_FALSE(
      without_tpm.SignSimpleChallenge(false, "", "", SecureBlob(), nullptr));
  EXPECT_FALSE(without_tpm.GetEKInfo(nullptr));
}

TEST_P(AttestationTest, PCARequest_Enroll) {
  std::string expected_url = GetPCAWebOrigin(pca_type_) + "/enroll";
  http_transport_->AddSimpleReplyHandler(
      expected_url, brillo::http::request_type::kPost,
      brillo::http::status_code::Ok, "response",
      brillo::mime::application::kOctet_stream);
  SecureBlob response;
  EXPECT_TRUE(attestation_.SendPCARequestAndBlock(
      pca_type_, Attestation::kEnroll, SecureBlob("request"), &response));
  EXPECT_TRUE(CompareBlob(response, "response"));
}

TEST_P(AttestationTest, PCARequest_GetCertificate) {
  std::string expected_url = GetPCAWebOrigin(pca_type_) + "/sign";
  http_transport_->AddSimpleReplyHandler(
      expected_url, brillo::http::request_type::kPost,
      brillo::http::status_code::Ok, "response",
      brillo::mime::application::kOctet_stream);
  SecureBlob response;
  EXPECT_TRUE(attestation_.SendPCARequestAndBlock(
      pca_type_, Attestation::kGetCertificate, SecureBlob("request"),
      &response));
  EXPECT_TRUE(CompareBlob(response, "response"));
}

TEST_P(AttestationTest, PCARequestWithServerError) {
  std::string expected_url = GetPCAWebOrigin(pca_type_) + "/enroll";
  http_transport_->AddSimpleReplyHandler(
      expected_url, brillo::http::request_type::kPost,
      brillo::http::status_code::BadRequest, "response",
      brillo::mime::application::kOctet_stream);
  SecureBlob response;
  EXPECT_FALSE(attestation_.SendPCARequestAndBlock(
      pca_type_, Attestation::kEnroll, SecureBlob("request"), &response));
  EXPECT_FALSE(CompareBlob(response, "response"));
}

struct AbeDataParam {
  const char* data;
  const char* enterprise_enrollment_nonce;
  const char* enterprise_enrollment_id;

  AbeDataParam(const char* data,
               const char* enterprise_enrollment_nonce,
               const char* enterprise_enrollment_id)
      : data(data),
        enterprise_enrollment_nonce(enterprise_enrollment_nonce),
        enterprise_enrollment_id(enterprise_enrollment_id) {}
};

struct AbeDataTestParam {
  AbeDataParam abe_data;
  Attestation::PCAType pca_type;

  AbeDataTestParam(AbeDataParam abe_data, Attestation::PCAType pca_type)
      : abe_data(abe_data), pca_type(pca_type) {}
};

class AttestationWithAbeDataTest
    : public AttestationBaseTest,
      public testing::WithParamInterface<AbeDataTestParam> {
 public:
  void SetUp() override {
    AttestationBaseTest::SetUp();
    pca_type_ = GetParam().pca_type;
  }

  void Initialize() override {
    SecureBlob abe_data;
    const char* data = GetParam().abe_data.data;
    if (data != NULL) {
      if (!base::HexStringToBytes(data, &abe_data)) {
        abe_data.clear();
      }
    }
    attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
                            &install_attributes_, abe_data,
                            false /* retain_endorsement_data */);
  }

 protected:
  bool VerifyAttestationEnrollmentRequest(const SecureBlob& request) {
    AttestationEnrollmentRequest request_pb;
    if (!request_pb.ParseFromArray(request.data(), request.size())) {
      return false;
    }
    const AbeDataParam& param = GetParam().abe_data;
    if (param.data == nullptr) {
      return !request_pb.has_enterprise_enrollment_nonce();
    }
    SecureBlob expected;
    EXPECT_TRUE(
        base::HexStringToBytes(param.enterprise_enrollment_nonce, &expected));
    std::string nonce = request_pb.enterprise_enrollment_nonce();
    return expected == SecureBlob(nonce.begin(), nonce.end());
  }

  Attestation::PCAType pca_type_;
};

TEST_P(AttestationWithAbeDataTest,
       PrepareForEnrollmentInstallAttributesNotReady) {
  EXPECT_CALL(install_attributes_, is_first_install())
      .WillRepeatedly(Return(true));
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.IsPreparedForEnrollment());
  AttestationDatabase db = GetPersistentDatabase();
  EXPECT_TRUE(db.has_credentials());
  // One identity has been created.
  EXPECT_EQ(1, db.identities().size());
  const AttestationDatabase::Identity& identity_data = db.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));
  // Deprecated identity-related values have not been set.
  EXPECT_FALSE(db.has_identity_binding());
  EXPECT_FALSE(db.has_identity_key());
  EXPECT_FALSE(db.has_pcr0_quote());
  EXPECT_FALSE(db.has_pcr1_quote());
  // We have a delegate to activate the AIK.
  EXPECT_TRUE(db.has_delegate());
  // Verify Privacy CA-related data.
  VerifyPCAData(db);
  // These deprecated fields have not been set either.
  EXPECT_TRUE(db.has_credentials());
  EXPECT_FALSE(db.credentials().has_default_encrypted_endorsement_credential());
}

TEST_P(AttestationWithAbeDataTest, Enroll) {
  SecureBlob blob;
  EXPECT_FALSE(attestation_.CreateEnrollRequest(pca_type_, &blob));
  attestation_.PrepareForEnrollment();
  EXPECT_FALSE(attestation_.HasIdentityCertificate(Attestation::kFirstIdentity,
                                                   pca_type_));
  EXPECT_TRUE(attestation_.CreateEnrollRequest(pca_type_, &blob));
  EXPECT_TRUE(VerifyAttestationEnrollmentRequest(blob));
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.HasIdentityCertificate(
                         Attestation::kFirstIdentity, pca_type_));
  // Check that the database is only using the new fields.
  AttestationDatabase db = GetPersistentDatabase();
  EXPECT_FALSE(db.mutable_identity_key()->has_identity_credential());
}

TEST_P(AttestationWithAbeDataTest, GetEnterpriseEnrollmentIdCached) {
  brillo::SecureBlob pubek(GetValidEndorsementKey());
  EXPECT_CALL(tpm_, GetEndorsementPublicKey(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pubek), Return(true)));
  attestation_.PrepareForEnrollment();
  SecureBlob enroll_blob;
  EXPECT_TRUE(attestation_.CreateEnrollRequest(Attestation::kDefaultPCA,
                                               &enroll_blob));
  attestation_.Enroll(Attestation::kDefaultPCA, GetEnrollBlob());
  // Change abe_data.
  attestation_.Initialize(&tpm_, &tpm_init_, &platform_, &crypto_,
                          &install_attributes_,
                          brillo::SecureBlob("new_abe_data"),
                          false /* retain_endorsement_data */);
  // GetEnterpriseEnrollmentId should return a cached EID.
  brillo::SecureBlob blob;
  EXPECT_TRUE(attestation_.GetEnterpriseEnrollmentId(&blob));
  EXPECT_EQ(GetParam().abe_data.enterprise_enrollment_id,
            base::ToLowerASCII(base::HexEncode(blob.data(), blob.size())));
}

TEST_P(AttestationTest, CertRequest) {
  EXPECT_CALL(tpm_, CreateCertifiedKey(_, _, _, _, _, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<3>(GetPKCS1PublicKey()), Return(true)));
  SecureBlob blob;
  attestation_.PrepareForEnrollment();
  EXPECT_FALSE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_FALSE(attestation_.DoesKeyExist(false, kTestUser, "test"));
  EXPECT_TRUE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), false,
                                             kTestUser, "test", &blob));
  EXPECT_TRUE(CompareBlob(
      blob, EncodeCertChain("response_cert", "response_ca_cert")));
  EXPECT_TRUE(attestation_.DoesKeyExist(false, kTestUser, "test"));
  EXPECT_TRUE(
      attestation_.GetCertificateChain(false, kTestUser, "test", &blob));
  EXPECT_TRUE(CompareBlob(
      blob, EncodeCertChain("response_cert", "response_ca_cert")));
  EXPECT_TRUE(attestation_.GetPublicKey(false, kTestUser, "test", &blob));
  EXPECT_TRUE(blob == GetX509PublicKey());
}

TEST_P(AttestationTest, CertRequestStorageFailure) {
  EXPECT_CALL(key_store_, Write(true, kTestUser, "test", _))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(key_store_, Read(true, kTestUser, "test", _))
      .WillOnce(Return(false))
      .WillRepeatedly(DoAll(SetArgPointee<3>(GetCertifiedKeyBlob("", true)),
                            Return(true)));
  SecureBlob blob;
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  // Expect storage failure here.
  EXPECT_FALSE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), true,
                                              kTestUser, "test", &blob));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_TRUE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), true,
                                             kTestUser, "test", &blob));
  EXPECT_TRUE(CompareBlob(
      blob, EncodeCertChain("response_cert", "response_ca_cert")));
  // Expect storage failure here.
  EXPECT_FALSE(
      attestation_.GetCertificateChain(true, kTestUser, "test", &blob));
  EXPECT_TRUE(attestation_.DoesKeyExist(true, kTestUser, "test"));
  EXPECT_TRUE(
      attestation_.GetCertificateChain(true, kTestUser, "test", &blob));
  EXPECT_TRUE(
      CompareBlob(blob, EncodeCertChain("stored_cert", "stored_ca_cert")));
  EXPECT_TRUE(attestation_.GetPublicKey(true, kTestUser, "test", &blob));
  EXPECT_TRUE(blob == GetX509PublicKey());
}

TEST_P(AttestationTest, SimpleChallenge) {
  EXPECT_CALL(tpm_, Sign(_, _, _, _))
      .WillOnce(Return(false))
      .WillRepeatedly(
          DoAll(SetArgPointee<3>(SecureBlob("signature")), Return(true)));
  brillo::SecureBlob blob;
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.CreateEnrollRequest(pca_type_, &blob));
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_TRUE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), false,
                                             kTestUser, "test", &blob));
  // Expect tpm_.Sign() failure the first attempt.
  EXPECT_FALSE(attestation_.SignSimpleChallenge(
      false, kTestUser, "test", SecureBlob("challenge"), &blob));
  EXPECT_TRUE(attestation_.SignSimpleChallenge(
      false, kTestUser, "test", SecureBlob("challenge"), &blob));
  EXPECT_TRUE(VerifySimpleChallenge(blob, "challenge", "signature"));
}

TEST_P(AttestationTest, EMKChallenge) {
  EXPECT_CALL(tpm_, Sign(_, _, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<3>(SecureBlob("signature")), Return(true)));
  brillo::SecureBlob blob;
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.CreateEnrollRequest(pca_type_, &blob));
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_TRUE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), false,
                                             kTestUser, "test", &blob));
  // Try all the VA servers in turn. We don't parameterize the test because
  // not doing so allows us to verify that the attestation code uses the
  // proper key when it has more than one.
  for (int t = Attestation::kDefaultVA; t < Attestation::kMaxVAType; ++t) {
    Attestation::VAType va_type = static_cast<Attestation::VAType>(t);
    SecureBlob bad_prefix_challenge =
        GetEnterpriseVaChallenge(va_type, "bad", true);
    EXPECT_FALSE(attestation_.SignEnterpriseVaChallenge(
        va_type, false, kTestUser, "test", "test_domain",
        SecureBlob("test_id"), false, bad_prefix_challenge, &blob));
    SecureBlob challenge =
        GetEnterpriseVaChallenge(va_type, "EnterpriseKeyChallenge", true);
    EXPECT_TRUE(attestation_.SignEnterpriseVaChallenge(
        va_type, false, kTestUser, "test", "test_domain",
        SecureBlob("test_id"), false, challenge, &blob));
    EXPECT_TRUE(VerifyEnterpriseVaChallenge(va_type, blob, EMK, "test_domain",
                                            "test_id", "", "signature"));
  }
  // Try the default VA server.
  SecureBlob bad_prefix_challenge =
      GetEnterpriseVaChallenge(Attestation::kDefaultVA, "bad", true);
  EXPECT_FALSE(attestation_.SignEnterpriseChallenge(
      false, kTestUser, "test", "test_domain", SecureBlob("test_id"), false,
      bad_prefix_challenge, &blob));
  SecureBlob challenge = GetEnterpriseVaChallenge(
      Attestation::kDefaultVA, "EnterpriseKeyChallenge", true);
  EXPECT_TRUE(attestation_.SignEnterpriseChallenge(
      false, kTestUser, "test", "test_domain", SecureBlob("test_id"), false,
      challenge, &blob));
  EXPECT_TRUE(VerifyEnterpriseVaChallenge(Attestation::kDefaultVA, blob, EMK,
                                          "test_domain", "test_id", "",
                                          "signature"));
}

TEST_P(AttestationTest, Payload) {
  EXPECT_CALL(key_store_, Write(true, kTestUser, "test",
                                GetCertifiedKeyBlob("test_payload", true)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(key_store_, Read(true, kTestUser, "test", _))
      .WillRepeatedly(
          DoAll(SetArgPointee<3>(GetCertifiedKeyBlob("stored_payload", true)),
                Return(true)));
  EXPECT_CALL(tpm_, CreateCertifiedKey(_, _, _, _, _, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<3>(GetPKCS1PublicKey()), Return(true)));
  SecureBlob blob;
  attestation_.PrepareForEnrollment();
  EXPECT_TRUE(attestation_.Enroll(pca_type_, GetEnrollBlob()));
  EXPECT_TRUE(attestation_.CreateCertRequest(
      pca_type_, ENTERPRISE_USER_CERTIFICATE, "", "", &blob));
  EXPECT_TRUE(attestation_.FinishCertRequest(GetCertRequestBlob(blob), false,
                                             kTestUser, "test", &blob));
  attestation_.GetKeyPayload(false, kTestUser, "test", &blob);
  EXPECT_EQ(0, blob.size());
  attestation_.SetKeyPayload(false, kTestUser, "test",
                             SecureBlob("test_payload"));
  attestation_.GetKeyPayload(false, kTestUser, "test", &blob);
  EXPECT_TRUE(CompareBlob(blob, "test_payload"));

  attestation_.SetKeyPayload(true, kTestUser, "test",
                             SecureBlob("test_payload"));
  attestation_.GetKeyPayload(true, kTestUser, "test", &blob);
  EXPECT_TRUE(CompareBlob(blob, "stored_payload"));
}

INSTANTIATE_TEST_CASE_P(
    PcaType, AttestationTest,
    ::testing::Values(Attestation::kDefaultPCA, Attestation::kTestPCA));

INSTANTIATE_TEST_CASE_P(
    AbeData, AttestationWithAbeDataTest,
    ::testing::Values(AbeDataTestParam(AbeDataParam(nullptr, nullptr, ""),
                                       Attestation::kDefaultPCA),
                      AbeDataTestParam(AbeDataParam(nullptr, nullptr, ""),
                                       Attestation::kTestPCA),
                      AbeDataTestParam(AbeDataParam(kABEData, kDEN, kEID),
                                       Attestation::kDefaultPCA),
                      AbeDataTestParam(AbeDataParam(kABEData, kDEN, kEID),
                                       Attestation::kTestPCA)));

}  // namespace cryptohome
