// 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 <algorithm>
#include <memory>
#include <string>
#include <vector>

#include <arpa/inet.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/data_encoding.h>
#include <brillo/http/http_utils.h>
#include <brillo/mime_utils.h>
#include <brillo/secure_blob.h>
#include <google/protobuf/repeated_field.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

#include "cryptohome/cryptohome_metrics.h"
#include "cryptohome/cryptolib.h"
#include "cryptohome/keystore.h"
#include "cryptohome/pkcs11_keystore.h"
#include "cryptohome/platform.h"
#include "cryptohome/tpm.h"
#include "cryptohome/tpm_init.h"

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

using brillo::SecureBlob;

namespace {

// Resets a boolean when it falls out of scope.
class ScopedBool {
 public:
  ScopedBool(bool* target, bool reset_value) : target_(target),
                                               reset_value_(reset_value) {}
  ~ScopedBool() { *target_ = reset_value_; }
 private:
  bool* target_;
  bool reset_value_;
};

}  // namespace

namespace cryptohome {

const size_t Attestation::kQuoteExternalDataSize = 20;
const size_t Attestation::kCipherKeySize = 32;
#if USE_TPM2
const size_t Attestation::kNonceSize = 32;
const size_t Attestation::kDigestSize = 32;
#else
const size_t Attestation::kNonceSize = 20;  // As per TPM_NONCE definition.
const size_t Attestation::kDigestSize = 20;  // As per TPM_DIGEST definition.
#endif
const size_t Attestation::kChallengeSignatureNonceSize = 20;  // For all TPMs.
const mode_t Attestation::kDatabasePermissions = 0600;
const char Attestation::kDatabaseOwner[] = "attestation";
const char Attestation::kDefaultDatabasePath[] =
    "/mnt/stateful_partition/unencrypted/preserve/attestation.epb";

// This has been extracted from the Chrome OS PCA's encryption certificate
// for the production PCA server.
const char Attestation::kDefaultPCAPublicKey[] =
    "A2976637E113CC457013F4334312A416395B08D4B2A9724FC9BAD65D0290F39C"
    "866D1163C2CD6474A24A55403C968CF78FA153C338179407FE568C6E550949B1"
    "B3A80731BA9311EC16F8F66060A2C550914D252DB90B44D19BC6C15E923FFCFB"
    "E8A366038772803EE57C7D7E5B3D5E8090BF0960D4F6A6644CB9A456708508F0"
    "6C19245486C3A49F807AB07C65D5E9954F4F8832BC9F882E9EE1AAA2621B1F43"
    "4083FD98758745CBFFD6F55DA699B2EE983307C14C9990DDFB48897F26DF8FB2"
    "CFFF03E631E62FAE59CBF89525EDACD1F7BBE0BA478B5418E756FF3E14AC9970"
    "D334DB04A1DF267D2343C75E5D282A287060D345981ABDA0B2506AD882579FEF";

// This value is opaque; it is proprietary to the system managing the private
// key.  In this case the value has been supplied by the PCA maintainers.
const char Attestation::kDefaultPCAPublicKeyID[] = "\x00\xc7\x0e\x50\xb1";
const char Attestation::kDefaultPCAWebOrigin[] =
    "https://chromeos-ca.gstatic.com";

// This has been extracted from the Chrome OS PCA's encryption certificate
// for the test PCA server.
const char Attestation::kTestPCAPublicKey[] =
    "A1D50D088994000492B5F3ED8A9C5FC8772706219F4C063B2F6A8C6B74D3AD6B"
    "212A53D01DABB34A6261288540D420D3BA59ED279D859DE6227A7AB6BD88FADD"
    "FC3078D465F4DF97E03A52A587BD0165AE3B180FE7B255B7BEDC1BE81CB1383F"
    "E9E46F9312B1EF28F4025E7D332E33F4416525FEB8F0FC7B815E8FBB79CDABE6"
    "327B5A155FEF13F559A7086CB8A543D72AD6ECAEE2E704FF28824149D7F4E393"
    "D3C74E721ACA97F7ADBE2CCF7B4BCC165F7380F48065F2C8370F25F066091259"
    "D14EA362BAF236E3CD8771A94BDEDA3900577143A238AB92B6C55F11DEFAFB31"
    "7D1DC5B6AE210C52B008D87F2A7BFF6EB5C4FB32D6ECEC6505796173951A3167";

// This value is opaque; it is proprietary to the system managing the private
// key.  In this case the value has been supplied by the PCA maintainers.
const char Attestation::kTestPCAPublicKeyID[] = "\x00\xc2\xb0\x56\x2d";
const char Attestation::kTestPCAWebOrigin[] =
    "https://asbestos-qa.corp.google.com";

#ifdef USE_TEST_PCA
#error "Do not compile with USE_TEST_PCA"
       " but provide the right PCA_type in calls."
#endif

const char Attestation::kEnterpriseSigningPublicKey[] =
    "bf7fefa3a661437b26aed0801db64d7ba8b58875c351d3bdc9f653847d4a67b3"
    "b67479327724d56aa0f71a3f57c2290fdc1ff05df80589715e381dfbbda2c4ac"
    "114c30d0a73c5b7b2e22178d26d8b65860aa8dd65e1b3d61a07c81de87c1e7e4"
    "590145624936a011ece10434c1d5d41f917c3dc4b41dd8392479130c4fd6eafc"
    "3bb4e0dedcc8f6a9c28428bf8fbba8bd6438a325a9d3eabee1e89e838138ad99"
    "69c292c6d9f6f52522333b84ddf9471ffe00f01bf2de5faa1621f967f49e158b"
    "f2b305360f886826cc6fdbef11a12b2d6002d70d8d1e8f40e0901ff94c203cb2"
    "01a36a0bd6e83955f14b494f4f2f17c0c826657b85c25ffb8a73599721fa17ab";

const char Attestation::kEnterpriseEncryptionPublicKey[] =
    "edba5e723da811e41636f792c7a77aef633fbf39b542aa537c93c93eaba7a3b1"
    "0bc3e484388c13d625ef5573358ec9e7fbeb6baaaa87ca87d93fb61bf5760e29"
    "6813c435763ed2c81f631e26e3ff1a670261cdc3c39a4640b6bbf4ead3d6587b"
    "e43ef7f1f08e7596b628ec0b44c9b7ad71c9ee3a1258852c7a986c7614f0c4ec"
    "f0ce147650a53b6aa9ae107374a2d6d4e7922065f2f6eb537a994372e1936c87"
    "eb08318611d44daf6044f8527687dc7ce5319b51eae6ab12bee6bd16e59c499e"
    "fa53d80232ae886c7ee9ad8bc1cbd6e4ac55cb8fa515671f7e7ad66e98769f52"
    "c3c309f98bf08a3b8fbb0166e97906151b46402217e65c5d01ddac8514340e8b";

// This value is opaque; it is proprietary to the system managing the private
// key.  In this case the value has been supplied by the enterprise server
// maintainers.
const char Attestation::kEnterpriseEncryptionPublicKeyID[] =
    "\x00\x4a\xe2\xdc\xae";

const Attestation::CertificateAuthority Attestation::kKnownEndorsementCA[] = {
  { "IFX TPM EK Intermediate CA 06",
    "de9e58a353313d21d683c687d6aaaab240248717557c077161c5e515f41d8efa"
    "48329f45658fb550f43f91d1ba0c2519429fb6ef964f89657098c90a9783ad6d"
    "3baea625db044734c478768db53b6022c556d8174ed744bd6e4455665715cd5c"
    "beb7c3fcb822ab3dfab1ecee1a628c3d53f6085983431598fb646f04347d5ae0"
    "021d5757cc6e3027c1e13f10633ae48bbf98732c079c17684b0db58bd0291add"
    "e277b037dd13fa3db910e81a4969622a79c85ac768d870f079b54c2b98c856e7"
    "15ef0ba9c01ee1da1241838a1307fe94b1ddfa65cdf7eeaa7e5b4b8a94c3dcd0"
    "29bb5ebcfc935e56641f4c8cb5e726c68f9dd6b41f8602ef6dc78d870a773571" },
  { "IFX TPM EK Intermediate CA 07",
    "f04c9b5b9f3cbc2509179f5e0f31dceb302900f528458e002c3e914d6b29e5e0"
    "924b0bcab2dd053f65d9d4a8eea8269c85c419dba640a88e14dc5f8c8c1a4269"
    "7a5ac4594b36f923110f91d1803d385540c01a433140b06054c77a144ee3a6a6"
    "5950c20f9215be3473b1002eb6b1756a22fbc18d21efacbbc8c270c66cf74982"
    "e24f057825cab51c0dd840a4f2d059032239c33e3f52c6ca06fe49bf4f60cc28"
    "a0fb1173d2ee05a141d30e8ffa32dbb86c1aeb5b309f76c2e462965612ec929a"
    "0d3b04acfa4525912c76f765e948be71f505d619cc673a889f0ed9e1d75f237b"
    "7af6a68550253cb4c3a8ff16c8091dbcbdea0ff8eee3d5bd92f49c53c5a15c93" },
  { "IFX TPM EK Intermediate CA 14",
    "D5B2EB8F8F23DD0B5CA0C15D4376E27A0380FD8EB1E52C2C270D961E8C0F66FD"
    "62E6ED6B3660FFBD8B0735179476F5E9C2EA4C762F5FEEDD3B5EB91785A724BC"
    "4C0617B83966336DD9DC407640871BF99DF4E1701EB5A1F5647FC57879CBB973"
    "B2A72BABA8536B2646A37AA5B73E32A4C8F03E35C8834B391AD363F1F7D1DF2B"
    "EE39233F47384F3E2D2E8EF83C9539B4DFC360C8AEB88B6111E757AF646DC01A"
    "68DAA908C7F8068894E9E991C59005068DD9B0F87113E6A80AB045DB4C1B23FF"
    "38A106098C2E184E1CF42A43EA68753F2649999048E8A3C3406032BEB1457070"
    "BCBE3A93E122638F6F18FF505C35FB827CE5D0C12F27F45C0F59C8A4A8697849" },
  { "IFX TPM EK Intermediate CA 16",
    "B98D42D5284620036A6613ED05A1BE11431AE7DE435EC55F72814652B9265EC2"
    "9035D401B538A9C84BB5B875450FAE8FBEDEF3430C4108D8516404F3DE4D4615"
    "2F471013673A7C7F236304C7363B91C0E0FD9FC7A9EC751521A60A6042839CF7"
    "7AEDE3243D0F51F47ACC39676D236BD5298E18B9A4783C60B2A1CD1B32124909"
    "D5844649EE4539D6AA05A5902C147B4F062D5145708EAE224EC65A8B51D7A418"
    "6327DA8F3B9E7C796F8B2DB3D2BDB39B829BDEBA8D2BF882CBADDB75D76FA8FA"
    "313682688BCD2835533A3A68A4AFDF7E597D8B965402FF22A5A4A418FDB4B549"
    "F218C3908E66BDCEAB3E2FE5EE0A4A1D9EB41A286ED07B6C112581FDAEA088D9" },
  { "IFX TPM EK Intermediate CA 17",
    "B0F3CC6F02E8C0486501102731069644A815F631ED41676C05CE3F7E5E5E40DF"
    "B3BF6D99787F2A9BE8F8B8035C03D5C2226072985230D4CE8407ACD6403F72E1"
    "A4DBF069504E56FA8C0807A704526EAC1E379AE559EB4BBAD9DB4E652B3B14E5"
    "38497A5E7768BCE0BFFAF800C61F1F2262775C526E1790A2BECF9A072A58F6A0"
    "F3042B5279FE9957BCADC3C9725428B66B15D5263F00C528AC47716DE6938199"
    "0FF23BC28F2C33B72D89B5F8EEEF9053B60D230431081D656EA8EC16C7CEFD9E"
    "F5A9061A3C921394D453D9AC77397D59B4C3BAF258266F65559469C3007987D5"
    "A8338E10FC54CD930303C37007D6E1E6C63F36BCFBA1E494AFB3ECD9A2407FF9" },
  { "IFX TPM EK Intermediate CA 21",
    "8149397109974D6C0850C8A60304ED7D209B1B88F435B695394DAD9FB4E64180"
    "02A3940966D2F04103C88659600EEA8E2A5C697C5F989F62D33A06DA10B50075"
    "F37F3CE6AD070413A0E109E16FE652B393C4DAFC5579CCB9915E9A70F5C05BCE"
    "0D341D6B887F43C4334BD8EC6A293FFAB737F77A45069CD0345D3D534E84D029"
    "029C37A267C0CC2D8DCE3E2C76F21A40F5D8D463882A8CBB92D8235685266753"
    "E8F051E78B681E87810A5B21EF719662A8208DFD94C55A126A112E39E0D732D7"
    "3C599095FAFF52BBC0E8C5B3DCD904D05DE00D5C5112F3DF7B76602ABE5DC0F8"
    "F89B55889A24C54EDBA1234AE498BE9B02CB5C8048D1DC90210705BAFC0E2837" },
  { "IFX TPM EK Intermediate CA 29",
    "cd424370776890ace339c62d7faae843bb2c765d27685c0441d278361a929062"
    "b4c95cc57213c864e91cbb92b1151f17a346a4e754c666f2a3e07ea9ffb9c80f"
    "e54d9479f73458c64bf7b0ca4e38821dd318e82d6fe387903ca73ca3e59db48e"
    "fe3b3c7c89599be87bb5e439a6f5843a412d4a321f154955448b71ca0b5fda47"
    "5c86a1c999dde7a01aa16436e65f0b04874c0db3970546bd806157058c5576a5"
    "c00b2bce7173c887f388dc4d5267c68fa5c47fcee3d8491071cd7742d43162cb"
    "285f5ba5e0daa0e910fdce566c5bbf7b3701d51660090344195fd7278456bd98"
    "48382fc5fceaebf93a2ec88c5722723519692e90d23f869c34d8b1af499d4127" },
  { "IFX TPM EK Intermediate CA 30",
    "a01cc43c4b66076d483086d0713a336f435e33ed23d3cda05f3c60a6f707416a"
    "9e53f0ef0de62c82a720e9ad94df29805b56b44279fd7389de4c60d498c81e3b"
    "a27692a045d993e9aaae152768588e5c62213721154529c95b09b201bcb3e573"
    "3d98e398d6e05215867d94e3d222e5b7df9f948c14533285821658b282be4bd7"
    "fe7197baa642f556d4f18738adef26b2eebfc64045cf4c5dcbff661aa95429f4"
    "e2c4921a8723bd8116f0efc038cd4530bb6e9299b7d70327e3fe8790d3d6db3a"
    "ebd3ccd12aef3d43cf89463a28ad1306a9d430b08c3411bfeeda63b9fdcc9a23"
    "1ff5cc203a7f5ee713d50e1930add1cd32ff64637fc740edb63380a5e6725381" },
  { "NTC TPM EK Root CA 01",
    "e836ac61b43e3252d5e1a8a4061997a6a0a272ba3d519d6be6360cc8b4b79e8c"
    "d53c07a7ce9e9310ca84b82bbdad32184544ada357d458cf224c4a3130c97d00"
    "4933b5db232d8b6509412eb4777e9e1b093c58b82b1679c84e57a6b218b4d61f"
    "6dd4c3a66b2dd33b52cb1ffdff543289fa36dd71b7c83b66c1aae37caf7fe88d"
    "851a3523e3ea92b59a6b0ca095c5e1d191484c1bff8a33048c3976e826d4c12a"
    "e198f7199d183e0e70c8b46e8106edec3914397e051ae2b9a7f0b4bb9cd7f2ed"
    "f71064eb0eb473df27b7ccef9a018d715c5fe6ab012a8315f933c7f4fc35d34c"
    "efc27de224b2e3de3b3ba316d5df8b90b2eb879e219d270141b78dbb671a3a05" },
  { "STM TPM EK Intermediate CA 03",
    "a5152b4fbd2c70c0c9a0dd919f48ddcde2b5c0c9988cff3b04ecd844f6cc0035"
    "6c4e01b52463deb5179f36acf0c06d4574327c37572292fcd0f272c2d45ea7f2"
    "2e8d8d18aa62354c279e03be9220f0c3822d16de1ea1c130b59afc56e08f22f1"
    "902a07f881ebea3703badaa594ecbdf8fd1709211ba16769f73e76f348e2755d"
    "bba2f94c1869ef71e726f56f8ece987f345c622e8b5c2a5466d41093c0dc2982"
    "e6203d96f539b542347a08e87fc6e248a346d61a505f52add7f768a5203d70b8"
    "68b6ec92ef7a83a4e6d1e1d259018705755d812175489fae83c4ab2957f69a99"
    "9394ac7a243a5c1cd85f92b8648a8e0d23165fdd86fad06990bfd16fb3293379" },
  /* TODO(ngm): remove by: Aug 30 08:44:33 2020 GMT */
  { "CROS TPM DEV EK ROOT CA",
    "cdc108745dc50dd6a1098c31486fb31578607fd64f64b0d91b994244ca1a9a69"
    "a74c6bccc7f24923e1513e132dc0d9dbcb1b22089299bb6cb669cbf4b704c992"
    "27bb769fa1f91ab11f67fb464a065b34b1a0e824136af5e59d1ac04bda22c199"
    "9f7a5b34bd6b50c81b4a88cc097d4dfeb4dc695096463d9529d69f116e2a26de"
    "070ef3118287072bdbe94466b8737049809bb8e1276b245930051b2bbbad71dd"
    "20d26349d1d83cdb2ff9c65251a17dae4f400ecc3e77f89e27a75fe0709dc81f"
    "e172008a3e65de685d9df43e036c557e88f1a9aedf7a91644391523d9728f946"
    "45c0e8adaf37e9a15777021ad43b675583302402912d66233c59ad05fa3b34ed"
  },
  { "CROS TPM PRD EK ROOT CA",
    "bd6f0198ffa7f7d20c15f81642096e335e2cd74734f73008265fc9957bbe018d"
    "fbac0d2a0ea99f5fb7bbff6f0d367b81199e837c390527972aa5392c2ca0f2a3"
    "506ee7d4a938f47158a7c56a390df2b781344a82b885a62f1de78f37ec105749"
    "69d8abf3163f0cf5c67fa05dd4fb3eb07a7571888b7a87ed57735ce476156bf7"
    "d6eff6cb8c8b303c21ebfe0e11b660edbdf903c70ac16927345d0b38c72f1e60"
    "1460743584f5a3eaef303dbc5cfda48e4c7a1f338108c7f0c70a694f814b6691"
    "ba9d058ab988152bb7097a010e400462187811c3e062001bce8aa808db485bd8"
    "2f7f0e1e2a2ddb95c364dffea4c23e872fc3874c4756e85e6cf8eca6eb6a07bf"
  },
};

const Attestation::CertificateAuthority
    Attestation::kKnownCrosCoreEndorsementCA[] = {
  { "IFX TPM EK Intermediate CA 24",
    "9D3F39677EBDB7B95F383021EA6EF90AD2BEA4E38B10CA65DCD84D0B33D400FA"
    "E7E56FC553975FDADD425227F055C029B6544331E3BA50ED33F6CC02D833EA4E"
    "0EECFE9AD1ADD7095F3A804C560F031E8705A3AD5189CBD62678B5B8205C37ED"
    "780A3EDE8DE64A08980C048872E789937A49FC4048EADCAC9B3FD0F0DD085E76"
    "30DDF9C0C31EFF3B77C6C3601AA7C3DCD10F08616C01435697746A61F920335C"
    "0C45A41149F5D22FCD23DBE35003A9AF7FD91C18715E3709F86A38AB149113C4"
    "D5273C3C90599734FF627ACBF408B082C76E486091F27446E175C50D340DA0FE"
    "5C3FE3D590B8729F4E364E5BF7D854D9AE28EFBCD0CE8F19E6462B3A593983DF" }
};

const Attestation::PCRValue Attestation::kKnownPCRValues[] = {
  { false, false, kVerified  },
  { false, false, kDeveloper },
  { false, true,  kVerified  },
  { false, true,  kDeveloper },
  { true,  false, kVerified  },
  { true,  false, kDeveloper },
  { true,  true,  kVerified  },
  { true,  true,  kDeveloper }
};

const int Attestation::kNumTemporalValues = 5;

const char Attestation::kAlternatePCAKeyAttributeName[] =
    "enterprise.alternate_pca_key";
const char Attestation::kAlternatePCAKeyIDAttributeName[] =
    "enterprise.alternate_pca_key_id";
const char Attestation::kAlternatePCAUrlAttributeName[] =
    "enterprise.alternate_pca_url";

const char Attestation::kAttestationBasedEnterpriseEnrollmentContextName[] =
    "attestation_based_enrollment";

Attestation::Attestation()
    : database_path_(kDefaultDatabasePath),
      pkcs11_key_store_(new Pkcs11KeyStore()),
      key_store_(pkcs11_key_store_.get()),
      enterprise_test_key_(NULL),
      install_attributes_observer_(this),
      is_tpm_ready_(false),
      is_prepare_in_progress_(false),
      retain_endorsement_data_(false),
      attestation_user_(0),
      attestation_group_(0) {
}

Attestation::~Attestation() {
  if (!thread_.is_null())
    base::PlatformThread::Join(thread_);
  ClearDatabase();
}

void Attestation::Initialize(Tpm* tpm,
                             TpmInit* tpm_init,
                             Platform* platform,
                             Crypto* crypto,
                             InstallAttributes* install_attributes,
                             const SecureBlob& abe_data,
                             bool retain_endorsement_data) {
  base::AutoLock lock(lock_);
  // Inject dependencies.
  tpm_ = tpm;
  tpm_init_ = tpm_init;
  platform_ = platform;
  crypto_ = crypto;
  if (install_attributes_ != install_attributes) {
    install_attributes_ = install_attributes;
    install_attributes_observer_.Add(install_attributes_);
  }
  abe_data_ = abe_data;
  retain_endorsement_data_ = retain_endorsement_data;

  if (tpm_) {
    if (!platform_->GetUserId(kDatabaseOwner, &attestation_user_,
                              &attestation_group_)) {
      LOG(WARNING) << "Attestation: Falling back to root.";
    }
    ExtendPCR1IfClear();
    std::string serial_encrypted_db;
    if (!LoadDatabase(&serial_encrypted_db)) {
      LOG(INFO) << "Attestation: Attestation data not found.";
      return;
    }
    if (!DecryptDatabase(serial_encrypted_db, &database_pb_)) {
      LOG(WARNING) << "Attestation: Attestation data invalid.  "
                      "This is normal if the TPM has been cleared.";
      return;
    }
    FinalizeEndorsementData();
    LOG(INFO) << "Attestation: Valid attestation data exists.";
    // Make sure the owner password is not being held on our account.
    tpm_init_->RemoveTpmOwnerDependency(Tpm::TpmOwnerDependency::kAttestation);
  }
}

bool Attestation::IsPreparedForEnrollment() {
  base::AutoLock lock(lock_);
  if (!database_pb_.has_credentials()) {
    return false;
  }
  return (database_pb_.credentials().has_endorsement_credential() ||
          database_pb_.credentials()
              .has_default_encrypted_endorsement_credential());
}

bool Attestation::IsEnrolled() {
  bool enable_alternate_pca =
      install_attributes_->Get(kAlternatePCAKeyAttributeName, NULL);
  base::AutoLock lock(lock_);
  bool default_enrolled = database_pb_.has_identity_key() &&
                          database_pb_.identity_key().has_identity_credential();
  bool alternate_enrolled =
      database_pb_.has_alternate_identity_key() &&
      database_pb_.alternate_identity_key().has_identity_credential();
  return default_enrolled && (alternate_enrolled || !enable_alternate_pca);
}

void Attestation::PrepareForEnrollment() {
  // There are a few ways to trigger PrepareForEnrollment, make sure it only
  // does the work once.
  {
    base::AutoLock lock(lock_);
    if (is_prepare_in_progress_)
      return;
    is_prepare_in_progress_ = true;
  }
  // In the event of an error it is important to reset |is_prepare_in_progress_|
  // so subsequent attempts are possible.
  ScopedBool reset(&is_prepare_in_progress_, false);

  // If there is no TPM, we have no work to do.
  if (!IsTPMReady())
    return;
  if (IsPreparedForEnrollment())
    return;
  if (install_attributes_->is_first_install()) {
    // We'll proceed now but we'll pick the default PCA as a result.
    LOG(WARNING) << "Attestation: Using default PCA. Alternate PCA will not be"
                    " available.";
  }
  bool enable_alternate_pca =
      install_attributes_->Get(kAlternatePCAKeyAttributeName, NULL);
  base::TimeTicks start = base::TimeTicks::Now();
  LOG(INFO) << "Attestation: Preparing for enrollment...";
  SecureBlob ek_public_key;
  if (!tpm_->GetEndorsementPublicKey(&ek_public_key)) {
    LOG(ERROR) << "Attestation: Failed to get EK public key.";
    return;
  }
  // Create an AIK.
  SecureBlob identity_public_key_der;
  SecureBlob identity_public_key;
  SecureBlob identity_key_blob;
  SecureBlob identity_binding;
  SecureBlob identity_label;
  SecureBlob pca_public_key;
  SecureBlob endorsement_credential;
  SecureBlob platform_credential;
  SecureBlob conformance_credential;
  if (!tpm_->MakeIdentity(&identity_public_key_der,
                          &identity_public_key,
                          &identity_key_blob,
                          &identity_binding,
                          &identity_label,
                          &pca_public_key,
                          &endorsement_credential,
                          &platform_credential,
                          &conformance_credential)) {
    LOG(ERROR) << "Attestation: Failed to make AIK.";
    return;
  }

  // Quote PCR0.
  SecureBlob external_data;
  if (!tpm_->GetRandomData(kQuoteExternalDataSize, &external_data)) {
    LOG(ERROR) << "Attestation: GetRandomData failed.";
    return;
  }
  SecureBlob quoted_pcr_value0;
  SecureBlob quoted_data0;
  SecureBlob quote0;
  if (!tpm_->QuotePCR(0,
                      identity_key_blob,
                      external_data,
                      &quoted_pcr_value0,
                      &quoted_data0,
                      &quote0)) {
    LOG(ERROR) << "Attestation: Failed to generate quote.";
    return;
  }
  // Quote PCR1.
  SecureBlob quoted_pcr_value1;
  SecureBlob quoted_data1;
  SecureBlob quote1;
  if (!tpm_->QuotePCR(1,
                      identity_key_blob,
                      external_data,
                      &quoted_pcr_value1,
                      &quoted_data1,
                      &quote1)) {
    LOG(ERROR) << "Attestation: Failed to generate quote.";
    return;
  }
  // Create an AIK and quotes for the alternate PCA.
  SecureBlob alternate_identity_public_key_der;
  SecureBlob alternate_identity_public_key;
  SecureBlob alternate_identity_key_blob;
  SecureBlob alternate_identity_binding;
  SecureBlob alternate_identity_label;
  SecureBlob alternate_pca_public_key;
  SecureBlob alternate_quoted_pcr_value0;
  SecureBlob alternate_quoted_data0;
  SecureBlob alternate_quote0;
  SecureBlob alternate_quoted_pcr_value1;
  SecureBlob alternate_quoted_data1;
  SecureBlob alternate_quote1;
  if (enable_alternate_pca) {
    if (!tpm_->MakeIdentity(&alternate_identity_public_key_der,
                            &alternate_identity_public_key,
                            &alternate_identity_key_blob,
                            &alternate_identity_binding,
                            &alternate_identity_label,
                            &alternate_pca_public_key,
                            &endorsement_credential,
                            &platform_credential,
                            &conformance_credential)) {
      LOG(ERROR) << "Attestation: Failed to make AIK.";
      return;
    }
    if (!tpm_->QuotePCR(0,
                        alternate_identity_key_blob,
                        external_data,
                        &alternate_quoted_pcr_value0,
                        &alternate_quoted_data0,
                        &alternate_quote0)) {
      LOG(ERROR) << "Attestation: Failed to generate quote.";
      return;
    }
    if (!tpm_->QuotePCR(1,
                        alternate_identity_key_blob,
                        external_data,
                        &alternate_quoted_pcr_value1,
                        &alternate_quoted_data1,
                        &alternate_quote1)) {
      LOG(ERROR) << "Attestation: Failed to generate quote.";
      return;
    }
  }

  // Create a delegate so we can activate the AIK later.
  SecureBlob delegate_blob;
  SecureBlob delegate_secret;
  if (!tpm_->CreateDelegate(identity_key_blob, &delegate_blob,
                            &delegate_secret)) {
    LOG(ERROR) << "Attestation: Failed to create delegate.";
    return;
  }

  // Assemble a protobuf to store locally.
  base::AutoLock lock(lock_);
  TPMCredentials* credentials_pb = database_pb_.mutable_credentials();
  credentials_pb->set_endorsement_public_key(ek_public_key.data(),
                                             ek_public_key.size());
  credentials_pb->set_endorsement_credential(endorsement_credential.data(),
                                             endorsement_credential.size());
  credentials_pb->set_platform_credential(platform_credential.data(),
                                          platform_credential.size());
  credentials_pb->set_conformance_credential(conformance_credential.data(),
                                             conformance_credential.size());
  if (!EncryptEndorsementCredential(
      kDefaultPCA,
      endorsement_credential,
      credentials_pb->mutable_default_encrypted_endorsement_credential())) {
    LOG(ERROR) << "Attestation: Failed to encrypt EK cert.";
    return;
  }
  if (!EncryptEndorsementCredential(
      kTestPCA,
      endorsement_credential,
      credentials_pb->mutable_test_encrypted_endorsement_credential())) {
    LOG(ERROR) << "Attestation: Failed to encrypt EK cert (test).";
    return;
  }
  if (enable_alternate_pca) {
    if (!EncryptEndorsementCredential(
        kAlternatePCA,
        endorsement_credential,
        credentials_pb->mutable_alternate_encrypted_endorsement_credential())) {
      LOG(ERROR) << "Attestation: Failed to encrypt EK cert (alternate).";
      return;
    }
  }
  IdentityKey* key_pb = database_pb_.mutable_identity_key();
  key_pb->set_identity_public_key(identity_public_key_der.data(),
                                  identity_public_key_der.size());
  key_pb->set_identity_key_blob(identity_key_blob.data(),
                                identity_key_blob.size());
  IdentityBinding* binding_pb = database_pb_.mutable_identity_binding();
  binding_pb->set_identity_binding(identity_binding.data(),
                                   identity_binding.size());
  binding_pb->set_identity_public_key_der(identity_public_key_der.data(),
                                          identity_public_key_der.size());
  binding_pb->set_identity_public_key(identity_public_key.data(),
                                      identity_public_key.size());
  binding_pb->set_identity_label(identity_label.data(), identity_label.size());
  binding_pb->set_pca_public_key(pca_public_key.data(), pca_public_key.size());
  Quote* quote_pb0 = database_pb_.mutable_pcr0_quote();
  quote_pb0->set_quote(quote0.data(), quote0.size());
  quote_pb0->set_quoted_data(quoted_data0.data(), quoted_data0.size());
  quote_pb0->set_quoted_pcr_value(quoted_pcr_value0.data(),
                                  quoted_pcr_value0.size());
  Quote* quote_pb1 = database_pb_.mutable_pcr1_quote();
  quote_pb1->set_quote(quote1.data(), quote1.size());
  quote_pb1->set_quoted_data(quoted_data1.data(), quoted_data1.size());
  quote_pb1->set_quoted_pcr_value(quoted_pcr_value1.data(),
                                  quoted_pcr_value1.size());
  quote_pb1->set_pcr_source_hint(platform_->GetHardwareID());
  if (enable_alternate_pca) {
    IdentityKey* alternate_key_pb =
        database_pb_.mutable_alternate_identity_key();
    alternate_key_pb->set_identity_public_key(
        alternate_identity_public_key_der.data(),
        alternate_identity_public_key_der.size());
    alternate_key_pb->set_identity_key_blob(alternate_identity_key_blob.data(),
                                            alternate_identity_key_blob.size());
    IdentityBinding* alternate_binding_pb =
        database_pb_.mutable_alternate_identity_binding();
    alternate_binding_pb->set_identity_binding(
        alternate_identity_binding.data(),
        alternate_identity_binding.size());
    alternate_binding_pb->set_identity_public_key_der(
        alternate_identity_public_key_der.data(),
        alternate_identity_public_key_der.size());
    alternate_binding_pb->set_identity_public_key(
        alternate_identity_public_key.data(),
        alternate_identity_public_key.size());
    alternate_binding_pb->set_identity_label(alternate_identity_label.data(),
                                             alternate_identity_label.size());
    alternate_binding_pb->set_pca_public_key(alternate_pca_public_key.data(),
                                             alternate_pca_public_key.size());
    Quote* alternate_quote_pb0 = database_pb_.mutable_alternate_pcr0_quote();
    alternate_quote_pb0->set_quote(alternate_quote0.data(),
                                   alternate_quote0.size());
    alternate_quote_pb0->set_quoted_data(alternate_quoted_data0.data(),
                                         alternate_quoted_data0.size());
    alternate_quote_pb0->set_quoted_pcr_value(
        alternate_quoted_pcr_value0.data(),
        alternate_quoted_pcr_value0.size());
    Quote* alternate_quote_pb1 = database_pb_.mutable_alternate_pcr1_quote();
    alternate_quote_pb1->set_quote(alternate_quote1.data(),
                                   alternate_quote1.size());
    alternate_quote_pb1->set_quoted_data(alternate_quoted_data1.data(),
                                         alternate_quoted_data1.size());
    alternate_quote_pb1->set_quoted_pcr_value(
        alternate_quoted_pcr_value1.data(),
        alternate_quoted_pcr_value1.size());
  }
  Delegation* delegate_pb = database_pb_.mutable_delegate();
  delegate_pb->set_blob(delegate_blob.data(), delegate_blob.size());
  delegate_pb->set_secret(delegate_secret.data(), delegate_secret.size());
  delegate_pb->set_has_reset_lock_permissions(true);

  std::string serial_encrypted_db;
  if (!EncryptDatabase(database_pb_, &serial_encrypted_db)) {
    LOG(ERROR) << "Attestation: Failed to encrypt db.";
    return;
  }
  if (!StoreDatabase(serial_encrypted_db)) {
    LOG(ERROR) << "Attestation: Failed to store db.";
    return;
  }
  tpm_init_->RemoveTpmOwnerDependency(Tpm::TpmOwnerDependency::kAttestation);
  base::TimeDelta delta = (base::TimeTicks::Now() - start);
  LOG(INFO) << "Attestation: Prepared successfully (" << delta.InMilliseconds()
            << "ms).";
}

void Attestation::PrepareForEnrollmentAsync() {
  base::AutoLock lock(lock_);
  if (!thread_.is_null()) {
    if (!is_prepare_in_progress_) {
      // Join the old thread and reuse the handle.
      base::PlatformThread::Join(thread_);
    } else {
      LOG(WARNING) << "PrepareForEnrollmentAsync called multiple times.";
      return;
    }
  }
  base::PlatformThread::Create(0, this, &thread_);
}

bool Attestation::Verify(bool is_cros_core) {
  if (!IsTPMReady())
    return false;
  LOG(INFO) << "Attestation: Verifying data.";
  base::AutoLock lock(lock_);
  const TPMCredentials& credentials = database_pb_.credentials();
  SecureBlob ek_public_key;
  SecureBlob ek_cert;
  if (credentials.has_endorsement_credential()) {
    ek_cert = SecureBlob(credentials.endorsement_credential());
  } else {
    if (!tpm_->GetEndorsementCredential(&ek_cert)) {
      LOG(ERROR) << "Attestation: Endorsement cert not available.";
      return false;
    }
  }
  if (credentials.has_endorsement_public_key()) {
    ek_public_key = SecureBlob(credentials.endorsement_public_key());
  } else {
    if (!tpm_->GetEndorsementPublicKey(&ek_public_key)) {
      LOG(ERROR) << "Attestation: Endorsement key not available.";
      return false;
    }
  }
  if (!VerifyEndorsementCredential(ek_cert, ek_public_key, is_cros_core)) {
    LOG(ERROR) << "Attestation: Bad endorsement credential.";
    return false;
  }
  if (!VerifyIdentityBinding(database_pb_.identity_binding())) {
    LOG(ERROR) << "Attestation: Bad identity binding.";
    return false;
  }
  SecureBlob aik_public_key = SecureBlob(
      database_pb_.identity_binding().identity_public_key_der());
  if (!VerifyPCR0Quote(aik_public_key, database_pb_.pcr0_quote())) {
    LOG(ERROR) << "Attestation: Bad PCR0 quote.";
    return false;
  }
  if (!VerifyPCR1Quote(aik_public_key, database_pb_.pcr1_quote())) {
    // Don't fail because many devices don't use PCR1.
    LOG(WARNING) << "Attestation: Bad PCR1 quote.";
  }
  SecureBlob nonce;
  if (!tpm_->GetRandomData(kNonceSize, &nonce)) {
    LOG(ERROR) << "Attestation: GetRandomData failed.";
    return false;
  }
  SecureBlob identity_key_blob(database_pb_.identity_key().identity_key_blob());
  SecureBlob public_key;
  SecureBlob public_key_der;
  SecureBlob key_blob;
  SecureBlob key_info;
  SecureBlob proof;
  if (!tpm_->CreateCertifiedKey(identity_key_blob, nonce,
                                &public_key, &public_key_der,
                                &key_blob, &key_info, &proof)) {
    LOG(ERROR) << "Attestation: Failed to create certified key.";
    return false;
  }
  if (!VerifyCertifiedKey(aik_public_key, public_key_der, key_info, proof)) {
    LOG(ERROR) << "Attestation: Bad certified key.";
    return false;
  }
  SecureBlob delegate_blob(database_pb_.delegate().blob());
  SecureBlob delegate_secret(database_pb_.delegate().secret());
  SecureBlob aik_public_key_tpm(
      database_pb_.identity_binding().identity_public_key());
  if (!VerifyActivateIdentity(delegate_blob, delegate_secret,
                              identity_key_blob, aik_public_key_tpm,
                              ek_public_key)) {
    LOG(ERROR) << "Attestation: Failed to verify owner delegation.";
    return false;
  }
  LOG(INFO) << "Attestation: Verified OK.";
  return true;
}

bool Attestation::VerifyEK(bool is_cros_core) {
  if (!IsTPMReady())
    return false;
  base::AutoLock lock(lock_);
  SecureBlob ek_cert;
  SecureBlob ek_public_key;
  if (database_pb_.has_credentials()) {
    const TPMCredentials& credentials = database_pb_.credentials();
    if (credentials.has_endorsement_credential()) {
      ek_public_key = SecureBlob(credentials.endorsement_public_key());
      ek_cert = SecureBlob(credentials.endorsement_credential());
    }
  }
  if (ek_cert.size() == 0 && !tpm_->GetEndorsementCredential(&ek_cert)) {
    LOG(ERROR) << __func__ << ": Failed to get EK certificate.";
    return false;
  }
  if (ek_public_key.size() == 0 &&
      !tpm_->GetEndorsementPublicKey(&ek_public_key)) {
    LOG(ERROR) << __func__ << ": Failed to get EK public key.";
    return false;
  }
  return VerifyEndorsementCredential(ek_cert, ek_public_key, is_cros_core);
}

bool Attestation::CreateEnrollRequest(PCAType pca_type,
                                      SecureBlob* pca_request) {
  if (!IsTPMReady())
    return false;
  if (!IsPreparedForEnrollment()) {
    LOG(ERROR) << __func__ << ": Enrollment is not possible, attestation data "
               << "does not exist.";
    return false;
  }
  base::AutoLock lock(lock_);
  AttestationEnrollmentRequest request_pb;
  *request_pb.mutable_encrypted_endorsement_credential() =
      GetEncryptedEndorsementCredential(pca_type);
  bool use_alternate_pca = (pca_type == kAlternatePCA);
  request_pb.set_identity_public_key(use_alternate_pca ?
      database_pb_.alternate_identity_binding().identity_public_key() :
      database_pb_.identity_binding().identity_public_key());
  *request_pb.mutable_pcr0_quote() = use_alternate_pca ?
      database_pb_.alternate_pcr0_quote() :
      database_pb_.pcr0_quote();
  *request_pb.mutable_pcr1_quote() = use_alternate_pca ?
      database_pb_.alternate_pcr1_quote() :
      database_pb_.pcr1_quote();
  SecureBlob enterprise_enrollment_nonce;
  if (!ComputeEnterpriseEnrollmentNonce(&enterprise_enrollment_nonce)) {
    LOG(ERROR) << "Attestation: Failed to compute enterprise enrollment nonce.";
    return false;
  }
  if (!enterprise_enrollment_nonce.empty()) {
    request_pb.set_enterprise_enrollment_nonce(
        enterprise_enrollment_nonce.data(),
        enterprise_enrollment_nonce.size());
  }

  std::string tmp;
  if (!request_pb.SerializeToString(&tmp)) {
    LOG(ERROR) << __func__ << ": Failed to serialize protobuf.";
    return false;
  }
  *pca_request = SecureBlob(tmp);
  return true;
}

bool Attestation::Enroll(PCAType pca_type,
                         const SecureBlob& pca_response) {
  if (!IsTPMReady())
    return false;
  AttestationEnrollmentResponse response_pb;
  if (!response_pb.ParseFromArray(pca_response.data(), pca_response.size())) {
    LOG(ERROR) << __func__ << ": Failed to parse response from Privacy CA.";
    return false;
  }
  if (response_pb.status() != OK) {
    LOG(ERROR) << __func__ << ": Error received from Privacy CA: "
               << response_pb.detail();
    return false;
  }
  base::AutoLock lock(lock_);
  SecureBlob delegate_blob(database_pb_.delegate().blob());
  SecureBlob delegate_secret(database_pb_.delegate().secret());
  bool use_alternate_pca = (pca_type == kAlternatePCA);
  SecureBlob aik_blob(use_alternate_pca ?
      database_pb_.alternate_identity_key().identity_key_blob() :
      database_pb_.identity_key().identity_key_blob());
  SecureBlob encrypted_asym(
      response_pb.encrypted_identity_credential().asym_ca_contents());
  SecureBlob encrypted_sym(
      response_pb.encrypted_identity_credential().sym_ca_attestation());
  SecureBlob aik_credential;
  if (!tpm_->ActivateIdentity(delegate_blob, delegate_secret,
                              aik_blob, encrypted_asym, encrypted_sym,
                              &aik_credential)) {
    LOG(ERROR) << __func__ << ": Failed to activate identity.";
    return false;
  }
  IdentityKey* key_pb = use_alternate_pca ?
      database_pb_.mutable_alternate_identity_key() :
      database_pb_.mutable_identity_key();
  key_pb->set_identity_credential(
      aik_credential.to_string());
  if (!PersistDatabaseChanges()) {
    LOG(ERROR) << __func__ << ": Failed to persist database changes.";
    return false;
  }
  LOG(INFO) << "Attestation: Enrollment complete.";
  return true;
}

bool Attestation::CreateCertRequest(PCAType pca_type,
                                    CertificateProfile profile,
                                    const std::string& username,
                                    const std::string& origin,
                                    SecureBlob* pca_request) {
  if (!IsTPMReady())
    return false;
  if (!IsEnrolled()) {
    LOG(ERROR) << __func__ << ": Device is not enrolled for attestation.";
    return false;
  }
  bool use_alternate_pca = (pca_type == kAlternatePCA);
  base::AutoLock lock(lock_);
  AttestationCertificateRequest request_pb;
  SecureBlob message_id(kNonceSize);
  CryptoLib::GetSecureRandom(message_id.data(), message_id.size());
  request_pb.set_message_id(message_id.to_string());
  request_pb.set_identity_credential(use_alternate_pca ?
      database_pb_.alternate_identity_key().identity_credential() :
      database_pb_.identity_key().identity_credential());
  request_pb.set_profile(profile);
  if (!origin.empty() &&
      (profile == CONTENT_PROTECTION_CERTIFICATE_WITH_STABLE_ID)) {
    request_pb.set_origin(origin);
    request_pb.set_temporal_index(ChooseTemporalIndex(username, origin));
  }
  SecureBlob nonce;
  if (!tpm_->GetRandomData(kNonceSize, &nonce)) {
    LOG(ERROR) << __func__ << ": GetRandomData failed.";
    return false;
  }
  SecureBlob identity_key_blob(
      use_alternate_pca ?
      database_pb_.alternate_identity_key().identity_key_blob() :
      database_pb_.identity_key().identity_key_blob());
  SecureBlob public_key;
  SecureBlob public_key_der;
  SecureBlob key_blob;
  SecureBlob key_info;
  SecureBlob proof;
  if (!tpm_->CreateCertifiedKey(identity_key_blob, nonce,
                                &public_key, &public_key_der,
                                &key_blob, &key_info, &proof)) {
    LOG(ERROR) << __func__ << ": Failed to create certified key.";
    return false;
  }
  request_pb.set_certified_public_key(public_key.to_string());
  request_pb.set_certified_key_info(key_info.to_string());
  request_pb.set_certified_key_proof(proof.to_string());
  std::string tmp;
  if (!request_pb.SerializeToString(&tmp)) {
    LOG(ERROR) << __func__ << ": Failed to serialize protobuf.";
    return false;
  }
  *pca_request = SecureBlob(tmp);
  ClearString(&tmp);
  // Save certified key blob so we can finish the operation later.
  CertifiedKey certified_key_pb;
  certified_key_pb.set_key_blob(key_blob.to_string());
  certified_key_pb.set_public_key(public_key_der.to_string());
  if (!certified_key_pb.SerializeToString(&tmp)) {
    LOG(ERROR) << __func__ << ": Failed to serialize protobuf.";
    return false;
  }
  pending_cert_requests_[message_id.to_string()] = SecureBlob(tmp);
  ClearString(&tmp);
  return true;
}

bool Attestation::FinishCertRequest(const SecureBlob& pca_response,
                                    bool is_user_specific,
                                    const std::string& username,
                                    const std::string& key_name,
                                    SecureBlob* certificate_chain) {
  if (!IsTPMReady())
    return false;
  AttestationCertificateResponse response_pb;
  if (!response_pb.ParseFromArray(pca_response.data(), pca_response.size())) {
    LOG(ERROR) << __func__ << ": Failed to parse response from Privacy CA.";
    return false;
  }
  base::AutoLock lock(lock_);
  CertRequestMap::iterator iter = pending_cert_requests_.find(
      response_pb.message_id());
  if (iter == pending_cert_requests_.end()) {
    LOG(ERROR) << __func__ << ": Pending request not found.";
    return false;
  }
  if (response_pb.status() != OK) {
    LOG(ERROR) << __func__ << ": Error received from Privacy CA: "
               << response_pb.detail();
    pending_cert_requests_.erase(iter);
    return false;
  }
  CertifiedKey certified_key_pb;
  if (!certified_key_pb.ParseFromArray(iter->second.data(),
                                       iter->second.size())) {
    LOG(ERROR) << __func__ << ": Failed to parse pending request.";
    pending_cert_requests_.erase(iter);
    return false;
  }
  pending_cert_requests_.erase(iter);

  // The PCA issued a certificate and the response matched a pending request.
  // Now we want to finish populating the CertifiedKey and store it for later.
  certified_key_pb.set_certified_key_credential(
      response_pb.certified_key_credential());
  certified_key_pb.set_intermediate_ca_cert(response_pb.intermediate_ca_cert());
  certified_key_pb.mutable_additional_intermediate_ca_cert()->MergeFrom(
      response_pb.additional_intermediate_ca_cert());
  certified_key_pb.set_key_name(key_name);
  if (!SaveKey(is_user_specific, username, key_name, certified_key_pb))
    return false;
  LOG(INFO) << "Attestation: Certified key credential received and stored.";
  return CreatePEMCertificateChain(certified_key_pb, certificate_chain);
}

bool Attestation::GetCertificateChain(bool is_user_specific,
                                      const std::string& username,
                                      const std::string& key_name,
                                      SecureBlob* certificate_chain) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Could not find certified key: " << key_name;
    return false;
  }
  return CreatePEMCertificateChain(key, certificate_chain);
}

bool Attestation::GetPublicKey(bool is_user_specific,
                               const std::string& username,
                               const std::string& key_name,
                               SecureBlob* public_key) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Could not find certified key: " << key_name;
    return false;
  }
  SecureBlob public_key_der(key.public_key());

  // Convert from PKCS #1 RSAPublicKey to X.509 SubjectPublicKeyInfo.
  const unsigned char* asn1_ptr = public_key_der.data();
  std::unique_ptr<RSA, RSADeleter> rsa(
      d2i_RSAPublicKey(NULL, &asn1_ptr, public_key_der.size()));
  if (!rsa.get()) {
    LOG(ERROR) << __func__ << ": Failed to decode public key.";
    return false;
  }
  unsigned char* buffer = NULL;
  int length = i2d_RSA_PUBKEY(rsa.get(), &buffer);
  if (length <= 0) {
    LOG(ERROR) << __func__ << ": Failed to encode public key.";
    return false;
  }
  SecureBlob tmp(buffer, buffer + length);
  brillo::SecureMemset(buffer, 0, length);
  OPENSSL_free(buffer);
  public_key->swap(tmp);
  return true;
}

bool Attestation::DoesKeyExist(bool is_user_specific,
                               const std::string& username,
                               const std::string& key_name) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  return FindKeyByName(is_user_specific, username, key_name, &key);
}

bool Attestation::SignEnterpriseChallenge(
      bool is_user_specific,
      const std::string& username,
      const std::string& key_name,
      const std::string& domain,
      const SecureBlob& device_id,
      bool include_signed_public_key,
      const SecureBlob& challenge,
      SecureBlob* response) {
  if (!IsTPMReady())
    return false;
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Key not found.";
    return false;
  }

  // Validate that the challenge is coming from the expected source.
  SignedData signed_challenge;
  if (!signed_challenge.ParseFromArray(challenge.data(),
                                       challenge.size())) {
    LOG(ERROR) << __func__ << ": Failed to parse signed challenge.";
    return false;
  }
  if (!ValidateEnterpriseChallenge(signed_challenge)) {
    LOG(ERROR) << __func__ << ": Invalid challenge.";
    return false;
  }

  // Assemble a response protobuf.
  ChallengeResponse response_pb;
  *response_pb.mutable_challenge() = signed_challenge;
  SecureBlob nonce;
  if (!tpm_->GetRandomData(kChallengeSignatureNonceSize, &nonce)) {
    LOG(ERROR) << __func__ << ": Failed to generate nonce.";
    return false;
  }
  response_pb.set_nonce(nonce.to_string());
  KeyInfo key_info;
  // EUK -> Enterprise User Key
  // EMK -> Enterprise Machine Key
  key_info.set_key_type(is_user_specific ? EUK : EMK);
  key_info.set_domain(domain);
  key_info.set_device_id(device_id.to_string());
  // Only include the certificate if this is a user key.
  if (is_user_specific) {
    SecureBlob certificate_chain;
    if (!CreatePEMCertificateChain(key, &certificate_chain)) {
      LOG(ERROR) << __func__ << ": Failed to construct certificate chain.";
      return false;
    }
    key_info.set_certificate(certificate_chain.to_string());
  }
  if (is_user_specific && include_signed_public_key) {
    SecureBlob spkac;
    if (!CreateSignedPublicKey(key, &spkac)) {
      LOG(ERROR) << __func__ << ": Failed to create signed public key.";
      return false;
    }
    key_info.set_signed_public_key_and_challenge(spkac.to_string());
  }
  if (!EncryptEnterpriseKeyInfo(key_info,
                                response_pb.mutable_encrypted_key_info())) {
    LOG(ERROR) << __func__ << ": Failed to encrypt KeyInfo.";
    return false;
  }

  // Serialize and sign the response protobuf.
  std::string serialized;
  if (!response_pb.SerializeToString(&serialized)) {
    LOG(ERROR) << __func__ << ": Failed to serialize response protobuf.";
    return false;
  }
  SecureBlob input_data(serialized);
  ClearString(&serialized);
  if (!SignChallengeData(key, input_data, response)) {
    LOG(ERROR) << __func__ << ": Failed to sign data.";
    return false;
  }
  return true;
}

bool Attestation::SignSimpleChallenge(bool is_user_specific,
                                      const std::string& username,
                                      const std::string& key_name,
                                      const SecureBlob& challenge,
                                      SecureBlob* response) {
  if (!IsTPMReady())
    return false;
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Key not found.";
    return false;
  }
  // Add a nonce to ensure this service cannot be used to sign arbitrary data.
  SecureBlob nonce;
  if (!tpm_->GetRandomData(kChallengeSignatureNonceSize, &nonce)) {
    LOG(ERROR) << __func__ << ": Failed to generate nonce.";
    return false;
  }
  SecureBlob input_data = SecureBlob::Combine(challenge, nonce);
  if (!SignChallengeData(key, input_data, response)) {
    LOG(ERROR) << __func__ << ": Failed to sign data.";
    return false;
  }
  return true;
}

bool Attestation::RegisterKey(bool is_user_specific,
                              const std::string& username,
                              const std::string& key_name,
                              bool include_certificates) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Key not found.";
    return false;
  }
  SecureBlob certificate;
  if (include_certificates) {
    certificate = SecureBlob(key.certified_key_credential());
  }
  if (!key_store_->Register(is_user_specific,
                            username,
                            key_name,
                            SecureBlob(key.key_blob()),
                            SecureBlob(key.public_key()),
                            certificate)) {
    LOG(ERROR) << __func__ << ": Failed to register key.";
    return false;
  }
  if (include_certificates) {
    if (key.has_intermediate_ca_cert()) {
      if (!key_store_->RegisterCertificate(
          is_user_specific,
          username,
          SecureBlob(key.intermediate_ca_cert()))) {
        LOG(WARNING) << __func__ << ": Failed to register certificate.";
      }
    }
    for (int i = 0; i < key.additional_intermediate_ca_cert_size(); ++i) {
      if (!key_store_->RegisterCertificate(
          is_user_specific,
          username,
          SecureBlob(key.additional_intermediate_ca_cert(i)))) {
        LOG(WARNING) << __func__ << ": Failed to register certificate.";
      }
    }
  }
  // Once registered with key store, we don't want to keep our copy.
  DeleteKey(is_user_specific, username, key_name);
  return true;
}

bool Attestation::GetKeyPayload(bool is_user_specific,
                                const std::string& username,
                                const std::string& key_name,
                                SecureBlob* payload) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Key not found.";
    return false;
  }
  SecureBlob tmp(key.payload());
  payload->swap(tmp);
  return true;
}

bool Attestation::SetKeyPayload(bool is_user_specific,
                                const std::string& username,
                                const std::string& key_name,
                                const SecureBlob& payload) {
  base::AutoLock lock(lock_);
  CertifiedKey key;
  if (!FindKeyByName(is_user_specific, username, key_name, &key)) {
    LOG(ERROR) << __func__ << ": Key not found.";
    return false;
  }
  key.set_payload(payload.to_string());
  return SaveKey(is_user_specific, username, key_name, key);
}

bool Attestation::DeleteKeysByPrefix(bool is_user_specific,
                                     const std::string& username,
                                     const std::string& key_prefix) {
  base::AutoLock lock(lock_);
  if (is_user_specific) {
    return key_store_->DeleteByPrefix(is_user_specific, username, key_prefix);
  }
  // Manipulate the device keys protobuf field.  Linear time strategy is to swap
  // all elements we want to keep to the front and then truncate.
  google::protobuf::RepeatedPtrField<CertifiedKey>* device_keys =
      database_pb_.mutable_device_keys();
  int next_keep_index = 0;
  for (int i = 0; i < device_keys->size(); ++i) {
    if (device_keys->Get(i).key_name().find(key_prefix) != 0) {
      // Prefix doesn't match -> keep.
      if (i != next_keep_index)
        device_keys->SwapElements(next_keep_index, i);
      ++next_keep_index;
    }
  }
  while (next_keep_index < device_keys->size()) {
    device_keys->RemoveLast();
  }
  return PersistDatabaseChanges();
}

bool Attestation::GetEKInfo(std::string* ek_info) {
  if (!IsTPMReady())
    return false;
  SecureBlob ek_cert;
  if (!tpm_->GetEndorsementCredential(&ek_cert)) {
    LOG(ERROR) << "Cannot get EK certificate from TPM.  EK info not available.";
    return false;
  }
  SecureBlob hash = CryptoLib::Sha256(ek_cert);
  *ek_info = base::StringPrintf(
      "EK Certificate:\n%s\nHash:\n%s\n",
      CreatePEMCertificate(ek_cert.to_string()).c_str(),
      base::HexEncode(hash.data(), hash.size()).c_str());
  return true;
}

bool Attestation::GetIdentityResetRequest(const std::string& reset_token,
                                          SecureBlob* reset_request) {
  base::AutoLock lock(lock_);
  AttestationResetRequest proto;
  proto.set_token(reset_token);
  // This only works with the default PCA right now.
  *proto.mutable_encrypted_endorsement_credential() =
      database_pb_.credentials().default_encrypted_endorsement_credential();
  std::string serial;
  if (!proto.SerializeToString(&serial)) {
    LOG(ERROR) << __func__ << "Failed to serialize protobuf.";
    return false;
  }
  SecureBlob tmp(serial);
  ClearString(&serial);
  reset_request->swap(tmp);
  return true;
}

bool Attestation::IsPCR0VerifiedMode() {
  if (!IsTPMReady())
    return false;
  SecureBlob current_pcr_value;
  if (!tpm_->ReadPCR(0, &current_pcr_value) ||
      current_pcr_value.size() != kDigestSize) {
    LOG(WARNING) << "Failed to read PCR0.";
    return false;
  }
  SecureBlob settings_blob(3);
  settings_blob[0] = false;  // Developer mode enabled.
  settings_blob[1] = false;  // Recovery mode enabled.
  settings_blob[2] = kVerified;  // Firmware type.
  SecureBlob settings_digest = CryptoLib::Sha1(settings_blob);
  brillo::Blob extend_pcr_value(kDigestSize, 0);
  extend_pcr_value.insert(extend_pcr_value.end(), settings_digest.begin(),
                          settings_digest.end());
  SecureBlob expected_pcr_value = CryptoLib::Sha1(extend_pcr_value);
  return (current_pcr_value.size() == expected_pcr_value.size() &&
          0 == memcmp(current_pcr_value.data(),
                      expected_pcr_value.data(),
                      kDigestSize));
}

bool Attestation::EncryptDatabase(const AttestationDatabase& db,
                                  std::string* serial_encrypted_db) {
  CHECK(crypto_);
  std::string serial_string;
  if (!db.SerializeToString(&serial_string)) {
    LOG(ERROR) << "Failed to serialize db.";
    return false;
  }
  SecureBlob serial_data(serial_string.begin(), serial_string.end());
  if (database_key_.empty() || sealed_database_key_.empty()) {
    if (!crypto_->CreateSealedKey(&database_key_, &sealed_database_key_)) {
      LOG(ERROR) << "Failed to generate database key.";
      return false;
    }
  }
  if (!crypto_->EncryptData(serial_data, database_key_, sealed_database_key_,
                            serial_encrypted_db)) {
    LOG(ERROR) << "Attestation: Failed to encrypt database.";
    return false;
  }
  return true;
}

bool Attestation::DecryptDatabase(const std::string& serial_encrypted_db,
                                  AttestationDatabase* db) {
  CHECK(crypto_);
  if (!crypto_->UnsealKey(serial_encrypted_db, &database_key_,
                         &sealed_database_key_)) {
    LOG(ERROR) << "Attestation: Could not unseal decryption key.";
    return false;
  }
  SecureBlob serial_blob;
  if (!crypto_->DecryptData(serial_encrypted_db, database_key_, &serial_blob)) {
    LOG(ERROR) << "Attestation: Failed to decrypt database with Tpm.";
    return false;
  }
  std::string serial_string = serial_blob.to_string();
  if (!db->ParseFromString(serial_string)) {
    // Previously the DB was encrypted with CryptoLib::AesEncrypt which appends
    // a SHA-1.  This can be safely ignored.
    const size_t kLegacyJunkSize = 20;
    if (serial_string.size() < kLegacyJunkSize ||
        !db->ParseFromArray(serial_string.data(),
                            serial_string.length() - kLegacyJunkSize)) {
      LOG(ERROR) << "Failed to parse database.";
      return false;
    }
  }
  return true;
}

bool Attestation::StoreDatabase(const std::string& serial_encrypted_db) {
  if (!platform_->WriteStringToFileAtomicDurable(database_path_,
                                                 serial_encrypted_db,
                                                 kDatabasePermissions)) {
    LOG(ERROR) << "Failed to write db.";
    return false;
  }
  if (!platform_->SetOwnership(database_path_, attestation_user_,
                               attestation_group_)) {
    PLOG(ERROR) << "Failed to set db ownership";
    return false;
  }
  return true;
}

bool Attestation::LoadDatabase(std::string* serial_encrypted_db) {
  CheckDatabasePermissions();
  if (!platform_->ReadFileToString(database_path_, serial_encrypted_db)) {
    PLOG(ERROR) << "Failed to read db";
    return false;
  }
  return true;
}

bool Attestation::PersistDatabaseChanges() {
  std::string serial_encrypted_db;
  if (!EncryptDatabase(database_pb_, &serial_encrypted_db))
    return false;
  return StoreDatabase(serial_encrypted_db);
}

void Attestation::CheckDatabasePermissions() {
  const mode_t kMask = 0007;  // No permissions for 'others'.
  CHECK(platform_);
  mode_t permissions = 0;
  uid_t user = 0;
  gid_t group = 0;
  if (!platform_->GetPermissions(database_path_, &permissions) ||
      !platform_->GetOwnership(database_path_, &user, &group)) {
    if (errno != ENOENT) {
      PLOG(WARNING) << "Failed to read database permissions";
    }
    return;
  }
  if ((permissions & kMask) != 0) {
    LOG(WARNING) << "Fixing database permissions.";
    if (!platform_->SetPermissions(database_path_, permissions & ~kMask)) {
      PLOG(WARNING) << "Failed to fix database permissions";
    }
  }
  if (user != attestation_user_ || group != attestation_group_) {
    LOG(WARNING) << "Fixing database ownership.";
    if (!platform_->SetOwnership(database_path_, attestation_user_,
                                 attestation_group_)) {
      PLOG(WARNING) << "Failed to fix database ownership";
    }
  }
}

bool Attestation::VerifyEndorsementCredential(const SecureBlob& credential,
                                              const SecureBlob& public_key,
                                              bool is_cros_core) {
  const unsigned char* asn1_ptr = credential.data();
  std::unique_ptr<X509, X509Deleter> x509(
      d2i_X509(NULL, &asn1_ptr, credential.size()));
  if (!x509.get()) {
    LOG(ERROR) << "Failed to parse endorsement credential.";
    return false;
  }
  // Manually verify the certificate signature.
  char issuer[100];  // A longer CN will truncate.
  X509_NAME_get_text_by_NID(x509.get()->cert_info->issuer,
                            NID_commonName,
                            issuer,
                            arraysize(issuer));
  std::unique_ptr<EVP_PKEY, EVP_PKEYDeleter> issuer_key =
      GetAuthorityPublicKey(issuer, is_cros_core);
  if (!issuer_key.get()) {
    LOG(ERROR) << "Unknown endorsement credential issuer.";
    return false;
  }
  if (X509_verify(x509.get(), issuer_key.get()) != 1) {
    LOG(ERROR) << "Bad endorsement credential signature.";
    return false;
  }
  // Verify that the given public key matches the public key in the credential.
  // Note: Do not use any openssl functions that attempt to decode the public
  // key. These will fail because openssl does not recognize the OAEP key type.
  auto public_key_data = x509.get()->cert_info->key->public_key->data;
  SecureBlob credential_public_key(
      public_key_data,
      public_key_data + x509.get()->cert_info->key->public_key->length);
  if (credential_public_key.size() != public_key.size() ||
      memcmp(credential_public_key.data(),
             public_key.data(),
             public_key.size()) != 0) {
    LOG(ERROR) << "Bad endorsement credential public key.";
    return false;
  }
  return true;
}

bool Attestation::VerifyIdentityBinding(const IdentityBinding& binding) {
  // Reconstruct and hash a serialized TPM_IDENTITY_CONTENTS structure.
  const unsigned char header[] = {1, 1, 0, 0, 0, 0, 0, 0x79};
  std::string label_ca = binding.identity_label() + binding.pca_public_key();
  SecureBlob label_ca_digest = CryptoLib::Sha1(
      SecureBlob(label_ca));
  ClearString(&label_ca);
  // The signed data is header + digest + pubkey.
  SecureBlob contents = SecureBlob::Combine(SecureBlob::Combine(
      SecureBlob(std::begin(header), std::end(header)),
      label_ca_digest),
      SecureBlob(binding.identity_public_key()));
  // Now verify the signature.
  if (!VerifySignature(SecureBlob(
      binding.identity_public_key_der()),
      contents,
      SecureBlob(binding.identity_binding()))) {
    LOG(ERROR) << "Failed to verify identity binding signature.";
    return false;
  }
  return true;
}

bool Attestation::VerifyPCR0Quote(const SecureBlob& aik_public_key,
                                  const Quote& quote) {
  if (!VerifyQuoteSignature(aik_public_key, quote, 0)) {
    return false;
  }

  // Check if the PCR0 value represents a known mode.
  for (size_t i = 0; i < arraysize(kKnownPCRValues); ++i) {
    SecureBlob settings_blob(3);
    settings_blob[0] = kKnownPCRValues[i].developer_mode_enabled;
    settings_blob[1] = kKnownPCRValues[i].recovery_mode_enabled;
    settings_blob[2] = kKnownPCRValues[i].firmware_type;
    SecureBlob settings_digest = CryptoLib::Sha1(settings_blob);
    brillo::Blob extend_pcr_value(kDigestSize, 0);
    extend_pcr_value.insert(extend_pcr_value.end(), settings_digest.begin(),
                            settings_digest.end());
    SecureBlob final_pcr_value = CryptoLib::Sha1(extend_pcr_value);
    if (quote.quoted_pcr_value().size() == final_pcr_value.size() &&
        0 == memcmp(quote.quoted_pcr_value().data(), final_pcr_value.data(),
                    final_pcr_value.size())) {
      std::string description = "Developer Mode: ";
      description += kKnownPCRValues[i].developer_mode_enabled ? "On" : "Off";
      description += ", Recovery Mode: ";
      description += kKnownPCRValues[i].recovery_mode_enabled ? "On" : "Off";
      description += ", Firmware Type: ";
      description += (kKnownPCRValues[i].firmware_type == 1) ? "Verified" :
                     "Developer";
      LOG(INFO) << "PCR0: " << description;
      return true;
    }
  }
  LOG(WARNING) << "PCR0 value not recognized.";
  return true;
}

bool Attestation::VerifyPCR1Quote(const SecureBlob& aik_public_key,
                                  const Quote& quote) {
  if (!VerifyQuoteSignature(aik_public_key, quote, 1)) {
    return false;
  }

  // Check that the source hint is correctly populated.
  std::string hwid = platform_->GetHardwareID();
  if (hwid != quote.pcr_source_hint()) {
    LOG(ERROR) << "PCR1 source hint does not match HWID: " << hwid;
    return false;
  }

  LOG(INFO) << "PCR1 verified as " << hwid;
  return true;
}

bool Attestation::VerifyQuoteSignature(const SecureBlob& aik_public_key,
                                       const Quote& quote,
                                       int pcr_index) {
  if (!VerifySignature(aik_public_key,
                       SecureBlob(quote.quoted_data()),
                       SecureBlob(quote.quote()))) {
    LOG(ERROR) << "Failed to verify quote signature.";
    return false;
  }

  // Check that the quoted value matches the given PCR value. We can verify this
  // by reconstructing the TPM_PCR_COMPOSITE structure the TPM would create.
  CHECK_LE(pcr_index, 16);
  CHECK_LE(quote.quoted_pcr_value().size(), 256U);
  const uint8_t header[] = {
    // TPM_PCR_SELECTION.sizeOfSelect: 16-bit length of PCR index bitmap.
    uint8_t(0), uint8_t(2),
    // TPM_PCR_SELECTION.pcrSelect: PCR index bitmap.
    uint8_t(pcr_index < 8 ? (1 << pcr_index) : 0),
    uint8_t(pcr_index < 8 ? 0 : (1 << (pcr_index - 8))),
    // TPM_PCR_COMPOSITE.valueSize: 32-bit length of PCR value.
    uint8_t(0), uint8_t(0), uint8_t(0),
    uint8_t(quote.quoted_pcr_value().size())};
  SecureBlob pcr_composite = SecureBlob::Combine(
      SecureBlob(std::begin(header), std::end(header)),
      SecureBlob(quote.quoted_pcr_value()));
  SecureBlob pcr_digest = CryptoLib::Sha1(pcr_composite);
  SecureBlob quoted_data(quote.quoted_data());
  // The PCR digest should appear 8 bytes into the quoted data. See the
  // TPM_QUOTE_INFO structure.
  if (search(quoted_data.begin(), quoted_data.end(),
             pcr_digest.begin(), pcr_digest.end()) != quoted_data.begin() + 8) {
    LOG(ERROR) << "PCR value mismatch.";
    return false;
  }

  if (quote.has_pcr_source_hint()) {
    // Check if the PCR value matches the hint.
    SecureBlob hint_digest = CryptoLib::Sha256(
        SecureBlob(quote.pcr_source_hint()));
    brillo::Blob extend_pcr_value(kDigestSize, 0);
    extend_pcr_value.insert(extend_pcr_value.end(),
                            hint_digest.begin(),
                            hint_digest.begin() + 20);
    SecureBlob final_pcr_value = CryptoLib::Sha1(extend_pcr_value);
    if (quote.quoted_pcr_value().size() != final_pcr_value.size() ||
        0 != memcmp(quote.quoted_pcr_value().data(), final_pcr_value.data(),
                    final_pcr_value.size())) {
      LOG(ERROR) << "PCR source hint is invalid.";
      return false;
    }
  }
  return true;
}

bool Attestation::VerifyCertifiedKey(
    const SecureBlob& aik_public_key,
    const SecureBlob& certified_public_key,
    const SecureBlob& certified_key_info,
    const SecureBlob& proof) {
  std::string key_info = certified_key_info.to_string();
  if (!VerifySignature(aik_public_key, certified_key_info, proof)) {
    LOG(ERROR) << "Failed to verify certified key proof signature.";
    return false;
  }
  const unsigned char* asn1_ptr = certified_public_key.data();
  std::unique_ptr<RSA, RSADeleter> rsa(
      d2i_RSAPublicKey(NULL, &asn1_ptr, certified_public_key.size()));
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode certified public key.";
    return false;
  }
  SecureBlob modulus(BN_num_bytes(rsa.get()->n));
  BN_bn2bin(rsa.get()->n, modulus.data());
  SecureBlob key_digest = CryptoLib::Sha1(modulus);
  if (std::search(certified_key_info.begin(),
                  certified_key_info.end(),
                  key_digest.begin(),
                  key_digest.end()) == certified_key_info.end()) {
    LOG(ERROR) << "Certified public key mismatch.";
    return false;
  }
  return true;
}

std::unique_ptr<EVP_PKEY, Attestation::EVP_PKEYDeleter>
    Attestation::GetAuthorityPublicKey(const char* issuer_name,
                                       bool is_cros_core) {
  const CertificateAuthority* const kKnownCA =
      is_cros_core ? kKnownCrosCoreEndorsementCA : kKnownEndorsementCA;
  const int kNumIssuers =
      is_cros_core ? arraysize(kKnownCrosCoreEndorsementCA) :
                     arraysize(kKnownEndorsementCA);
  for (int i = 0; i < kNumIssuers; ++i) {
    if (0 == strcmp(issuer_name, kKnownCA[i].issuer)) {
      std::unique_ptr<RSA, RSADeleter> rsa = CreateRSAFromHexModulus(
          kKnownCA[i].modulus);
      std::unique_ptr<EVP_PKEY, EVP_PKEYDeleter> pkey(EVP_PKEY_new());
      if (!pkey.get()) {
        return std::unique_ptr<EVP_PKEY, EVP_PKEYDeleter>();
      }
      EVP_PKEY_assign_RSA(pkey.get(), rsa.release());
      return pkey;
    }
  }
  return std::unique_ptr<EVP_PKEY, EVP_PKEYDeleter>();
}

bool Attestation::VerifySignature(const SecureBlob& public_key,
                                  const SecureBlob& signed_data,
                                  const SecureBlob& signature) {
  const unsigned char* asn1_ptr = public_key.data();
  std::unique_ptr<RSA, RSADeleter> rsa(
      d2i_RSAPublicKey(NULL, &asn1_ptr, public_key.size()));
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode public key.";
    return false;
  }
  SecureBlob digest = CryptoLib::Sha1(signed_data);
  if (!RSA_verify(NID_sha1, digest.data(), digest.size(),
                  signature.data(), signature.size(), rsa.get())) {
    LOG(ERROR) << "Failed to verify signature.";
    return false;
  }
  return true;
}

void Attestation::ClearDatabase() {
  TPMCredentials* credentials = database_pb_.mutable_credentials();
  ClearString(credentials->mutable_endorsement_public_key());
  ClearString(credentials->mutable_endorsement_credential());
  ClearString(credentials->mutable_platform_credential());
  ClearString(credentials->mutable_conformance_credential());
  ClearIdentity(database_pb_.mutable_identity_binding(),
                database_pb_.mutable_identity_key());
  ClearQuote(database_pb_.mutable_pcr0_quote());
  ClearQuote(database_pb_.mutable_pcr1_quote());
  Delegation* delegate = database_pb_.mutable_delegate();
  ClearString(delegate->mutable_blob());
  ClearString(delegate->mutable_secret());
  ClearIdentity(database_pb_.mutable_alternate_identity_binding(),
                database_pb_.mutable_alternate_identity_key());
  ClearQuote(database_pb_.mutable_alternate_pcr0_quote());
  ClearQuote(database_pb_.mutable_alternate_pcr1_quote());
  database_pb_.Clear();
}

void Attestation::ClearQuote(Quote* quote) {
  ClearString(quote->mutable_quote());
  ClearString(quote->mutable_quoted_data());
  ClearString(quote->mutable_quoted_pcr_value());
  ClearString(quote->mutable_pcr_source_hint());
}

void Attestation::ClearIdentity(IdentityBinding* binding, IdentityKey* key) {
  ClearString(binding->mutable_identity_binding());
  ClearString(binding->mutable_identity_public_key_der());
  ClearString(binding->mutable_identity_public_key());
  ClearString(binding->mutable_identity_label());
  ClearString(binding->mutable_pca_public_key());
  ClearString(key->mutable_identity_public_key());
  ClearString(key->mutable_identity_key_blob());
  ClearString(key->mutable_identity_credential());
}

void Attestation::ClearString(std::string* s) {
  brillo::SecureMemset(string_as_array(s), 0, s->length());
  s->clear();
}

bool Attestation::VerifyActivateIdentity(const SecureBlob& delegate_blob,
                                         const SecureBlob& delegate_secret,
                                         const SecureBlob& identity_key_blob,
                                         const SecureBlob& identity_public_key,
                                         const SecureBlob& ek_public_key) {
  const char* kTestCredential = "test";
  const uint8_t kAlgAES256 = 9;  // This comes from TPM_ALG_AES256.
  const uint8_t kEncModeCBC = 2;  // This comes from TPM_SYM_MODE_CBC.
  const uint8_t kAsymContentHeader[] =
      {0, 0, 0, kAlgAES256, 0, kEncModeCBC, 0, kCipherKeySize};
  const uint8_t kSymContentHeader[12] = {0};

  // Generate an AES key and encrypt the credential.
  SecureBlob aes_key(kCipherKeySize);
  CryptoLib::GetSecureRandom(aes_key.data(), aes_key.size());
  SecureBlob credential(kTestCredential,
                        kTestCredential + strlen(kTestCredential));
  SecureBlob encrypted_credential;
  if (!TssCompatibleEncrypt(aes_key, credential, &encrypted_credential)) {
    LOG(ERROR) << "Failed to encrypt credential.";
    return false;
  }

  // Construct a TPM_ASYM_CA_CONTENTS structure.
  SecureBlob public_key_digest = CryptoLib::Sha1(identity_public_key);
  SecureBlob asym_content = SecureBlob::Combine(SecureBlob::Combine(
      SecureBlob(std::begin(kAsymContentHeader), std::end(kAsymContentHeader)),
      aes_key),
      public_key_digest);

  // Encrypt the TPM_ASYM_CA_CONTENTS with the EK public key.
  const unsigned char* asn1_ptr = ek_public_key.data();
  std::unique_ptr<RSA, RSADeleter> rsa(
      d2i_RSAPublicKey(NULL, &asn1_ptr, ek_public_key.size()));
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode EK public key.";
    return false;
  }
  SecureBlob encrypted_asym_content;
  if (!TpmCompatibleOAEPEncrypt(rsa.get(), asym_content,
                                &encrypted_asym_content)) {
    LOG(ERROR) << "Failed to encrypt with EK public key.";
    return false;
  }

  // Construct a TPM_SYM_CA_ATTESTATION structure.
  uint32_t length = htonl(encrypted_credential.size());
  SecureBlob length_blob(sizeof(uint32_t));
  memcpy(length_blob.data(), &length, sizeof(uint32_t));
  SecureBlob sym_content = SecureBlob::Combine(SecureBlob::Combine(
      length_blob,
      SecureBlob(std::begin(kSymContentHeader), std::end(kSymContentHeader))),
      encrypted_credential);

  // Attempt to activate the identity.
  SecureBlob credential_out;
  if (!tpm_->ActivateIdentity(delegate_blob, delegate_secret, identity_key_blob,
                              encrypted_asym_content, sym_content,
                              &credential_out)) {
    LOG(ERROR) << "Failed to activate identity.";
    return false;
  }
  if (credential.size() != credential_out.size() ||
      brillo::SecureMemcmp(credential.data(), credential_out.data(),
                             credential.size()) != 0) {
    LOG(ERROR) << "Invalid identity credential.";
    return false;
  }
  return true;
}

bool Attestation::EncryptEndorsementCredential(
    PCAType pca_type,
    const SecureBlob& credential,
    EncryptedData* encrypted_credential) {
  std::unique_ptr<RSA, RSADeleter> rsa;
  std::string key_id;
  switch (pca_type) {
    case kDefaultPCA:
      rsa = CreateRSAFromHexModulus(kDefaultPCAPublicKey);
      key_id = std::string(kDefaultPCAPublicKeyID,
                           arraysize(kDefaultPCAPublicKeyID) - 1);
      break;
    case kTestPCA:
      rsa = CreateRSAFromHexModulus(kTestPCAPublicKey);
      key_id = std::string(kTestPCAPublicKeyID,
                           arraysize(kTestPCAPublicKeyID) - 1);
      break;
    case kAlternatePCA:
      {
        brillo::Blob pca_key;
        if (!install_attributes_->Get(kAlternatePCAKeyAttributeName,
                                      &pca_key)) {
          LOG(ERROR) << __func__ << "Alternate PCA key does not exist.";
          return false;
        }
        const unsigned char* asn1_ptr = pca_key.data();
        rsa.reset(d2i_RSA_PUBKEY(NULL, &asn1_ptr, pca_key.size()));
        brillo::SecureBlob key_id_blob;
        // Ignore result, an empty ID is ok.
        install_attributes_->Get(kAlternatePCAKeyIDAttributeName, &key_id_blob);
        key_id = key_id_blob.to_string();
      }
      break;
    default:
      NOTREACHED();
  }
  if (!rsa.get()) {
    LOG(ERROR) << __func__ << ": Failed to decode public key.";
    return false;
  }
  return EncryptData(credential, rsa.get(), key_id, encrypted_credential);
}

const EncryptedData& Attestation::GetEncryptedEndorsementCredential(
    PCAType pca_type) const {
  switch (pca_type) {
    case kDefaultPCA:
    default:
      return database_pb_.credentials()
          .default_encrypted_endorsement_credential();
      break;

    case kTestPCA:
      return database_pb_.credentials()
          .test_encrypted_endorsement_credential();
      break;

    case kAlternatePCA:
      return database_pb_.credentials()
          .alternate_encrypted_endorsement_credential();
  }
}

bool Attestation::AddDeviceKey(const std::string& key_name,
                               const CertifiedKey& key) {
  // If a key by this name already exists, reuse the field.
  bool found = false;
  for (int i = 0; i < database_pb_.device_keys_size(); ++i) {
    if (database_pb_.device_keys(i).key_name() == key_name) {
      found = true;
      *database_pb_.mutable_device_keys(i) = key;
      break;
    }
  }
  if (!found)
    *database_pb_.add_device_keys() = key;
  return PersistDatabaseChanges();
}

void Attestation::RemoveDeviceKey(const std::string& key_name) {
  bool found = false;
  for (int i = 0; i < database_pb_.device_keys_size(); ++i) {
    if (database_pb_.device_keys(i).key_name() == key_name) {
      found = true;
      int last = database_pb_.device_keys_size() - 1;
      if (i < last) {
        database_pb_.mutable_device_keys()->SwapElements(i, last);
      }
      database_pb_.mutable_device_keys()->RemoveLast();
      break;
    }
  }
  if (found) {
    if (!PersistDatabaseChanges()) {
      LOG(WARNING) << __func__ << ": Failed to persist key deletion.";
    }
  }
}

bool Attestation::FindKeyByName(bool is_user_specific,
                                const std::string& username,
                                const std::string& key_name,
                                CertifiedKey* key) {
  if (is_user_specific) {
    SecureBlob key_data;
    if (!key_store_->Read(is_user_specific, username, key_name, &key_data)) {
      LOG(INFO) << "Key not found: " << key_name;
      return false;
    }
    if (!key->ParseFromArray(key_data.data(), key_data.size())) {
      LOG(ERROR) << "Failed to parse key: " << key_name;
      return false;
    }
    return true;
  }
  for (int i = 0; i < database_pb_.device_keys_size(); ++i) {
    if (database_pb_.device_keys(i).key_name() == key_name) {
      *key = database_pb_.device_keys(i);
      return true;
    }
  }
  LOG(INFO) << "Key not found: " << key_name;
  return false;
}

bool Attestation::SaveKey(bool is_user_specific,
                          const std::string& username,
                          const std::string& key_name,
                          const CertifiedKey& key) {
  if (is_user_specific) {
    std::string tmp;
    if (!key.SerializeToString(&tmp)) {
      LOG(ERROR) << __func__ << ": Failed to serialize protobuf.";
      return false;
    }
    SecureBlob blob(tmp);
    ClearString(&tmp);
    if (!key_store_->Write(is_user_specific, username, key_name, blob)) {
      LOG(ERROR) << __func__ << ": Failed to store certified key for user.";
      return false;
    }
  } else {
    if (!AddDeviceKey(key_name, key)) {
      LOG(ERROR) << __func__ << ": Failed to store certified key for device.";
      return false;
    }
  }
  return true;
}

void Attestation::DeleteKey(bool is_user_specific,
                            const std::string& username,
                            const std::string& key_name) {
  if (is_user_specific) {
    key_store_->Delete(is_user_specific, username, key_name);
  } else {
    RemoveDeviceKey(key_name);
  }
}

bool Attestation::CreatePEMCertificateChain(const CertifiedKey& key,
                                            SecureBlob* certificate_chain) {
  if (key.certified_key_credential().empty()) {
    LOG(ERROR) << "Certificate is empty.";
    return false;
  }
  std::string pem = CreatePEMCertificate(key.certified_key_credential());
  if (!key.intermediate_ca_cert().empty()) {
    pem += "\n";
    pem += CreatePEMCertificate(key.intermediate_ca_cert());
  }
  for (int i = 0; i < key.additional_intermediate_ca_cert_size(); ++i) {
    pem += "\n";
    pem += CreatePEMCertificate(key.additional_intermediate_ca_cert(i));
  }
  *certificate_chain = SecureBlob(pem);
  ClearString(&pem);
  return true;
}

std::string Attestation::CreatePEMCertificate(const std::string& certificate) {
  const char kBeginCertificate[] = "-----BEGIN CERTIFICATE-----\n";
  const char kEndCertificate[] = "-----END CERTIFICATE-----";

  std::string pem = kBeginCertificate;
  pem += brillo::data_encoding::Base64EncodeWrapLines(certificate);
  pem += kEndCertificate;
  return pem;
}

bool Attestation::SignChallengeData(const CertifiedKey& key,
                                    const SecureBlob& data_to_sign,
                                    SecureBlob* response) {
  SecureBlob signature;
  if (!tpm_->Sign(SecureBlob(key.key_blob()),
                  data_to_sign,
                  kNotBoundToPCR,
                  &signature)) {
    LOG(ERROR) << "Failed to generate signature.";
    return false;
  }
  SignedData signed_data;
  signed_data.set_data(data_to_sign.to_string());
  signed_data.set_signature(signature.to_string());
  std::string serialized;
  if (!signed_data.SerializeToString(&serialized)) {
    LOG(ERROR) << "Failed to serialize signed data.";
    return false;
  }
  SecureBlob tmp(serialized);
  ClearString(&serialized);
  response->swap(tmp);
  return true;
}

bool Attestation::ValidateEnterpriseChallenge(
    const SignedData& signed_challenge) {
  const char kExpectedChallengePrefix[] = "EnterpriseKeyChallenge";
  std::unique_ptr<RSA, RSADeleter> rsa =
      CreateRSAFromHexModulus(kEnterpriseSigningPublicKey);
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode public key.";
    return false;
  }
  SecureBlob digest = CryptoLib::Sha256(SecureBlob(signed_challenge.data()));
  SecureBlob signature(signed_challenge.signature());
  RSA* enterprise_key = enterprise_test_key_ ? enterprise_test_key_ : rsa.get();
  if (!RSA_verify(NID_sha256, digest.data(), digest.size(),
                  signature.data(), signature.size(), enterprise_key)) {
    LOG(ERROR) << "Failed to verify challenge signature.";
    return false;
  }
  Challenge challenge;
  if (!challenge.ParseFromString(signed_challenge.data())) {
    LOG(ERROR) << "Failed to parse challenge protobuf.";
    return false;
  }
  if (challenge.prefix() != kExpectedChallengePrefix) {
    LOG(ERROR) << "Unexpected challenge prefix.";
    return false;
  }
  return true;
}

bool Attestation::EncryptEnterpriseKeyInfo(const KeyInfo& key_info,
                                           EncryptedData* encrypted_data) {
  std::unique_ptr<RSA, RSADeleter> rsa =
      CreateRSAFromHexModulus(kEnterpriseEncryptionPublicKey);
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode public key.";
    return false;
  }
  std::string serialized;
  if (!key_info.SerializeToString(&serialized)) {
    LOG(ERROR) << "Failed to serialize key info.";
    return false;
  }
  RSA* enterprise_key = enterprise_test_key_ ? enterprise_test_key_ : rsa.get();
  std::string enterprise_key_id(kEnterpriseEncryptionPublicKeyID,
                           arraysize(kEnterpriseEncryptionPublicKeyID) - 1);
  bool result = EncryptData(SecureBlob(serialized),
                            enterprise_key,
                            enterprise_key_id,
                            encrypted_data);
  ClearString(&serialized);
  return result;
}

bool Attestation::EncryptData(const SecureBlob& input,
                              RSA* wrapping_key,
                              const std::string& wrapping_key_id,
                              EncryptedData* output) {
  // Encrypt with a randomly generated AES key.
  SecureBlob aes_key;
  if (!tpm_->GetRandomData(kCipherKeySize, &aes_key)) {
    LOG(ERROR) << "GetRandomData failed.";
    return false;
  }
  SecureBlob aes_iv;
  if (!tpm_->GetRandomData(kAesBlockSize, &aes_iv)) {
    LOG(ERROR) << "GetRandomData failed.";
    return false;
  }
  SecureBlob encrypted;
  if (!AesEncrypt(input, aes_key, aes_iv, &encrypted)) {
    LOG(ERROR) << "AesEncrypt failed.";
    return false;
  }
  output->set_encrypted_data(encrypted.data(), encrypted.size());
  output->set_iv(aes_iv.data(), aes_iv.size());
  output->set_wrapping_key_id(wrapping_key_id);
  output->set_mac(CryptoLib::ComputeEncryptedDataHMAC(*output, aes_key));

  // Wrap the AES key with the given public key.
  SecureBlob encrypted_key(RSA_size(wrapping_key));
  int length = RSA_public_encrypt(aes_key.size(),
                                  aes_key.data(),
                                  encrypted_key.data(),
                                  wrapping_key, RSA_PKCS1_OAEP_PADDING);
  if (length == -1) {
    LOG(ERROR) << "RSA_public_encrypt failed.";
    return false;
  }
  encrypted_key.resize(length);
  output->set_wrapped_key(encrypted_key.to_string());
  return true;
}

std::unique_ptr<RSA, Attestation::RSADeleter>
Attestation::CreateRSAFromHexModulus(
    const std::string& hex_modulus) {
  std::unique_ptr<RSA, RSADeleter> rsa(RSA_new());
  if (!rsa.get())
    return std::unique_ptr<RSA, RSADeleter>();
  rsa->e = BN_new();
  if (!rsa->e)
    return std::unique_ptr<RSA, RSADeleter>();
  BN_set_word(rsa->e, kWellKnownExponent);
  rsa->n = BN_new();
  if (!rsa->n)
    return std::unique_ptr<RSA, RSADeleter>();
  if (0 == BN_hex2bn(&rsa->n, hex_modulus.c_str()))
    return std::unique_ptr<RSA, RSADeleter>();
  return rsa;
}

bool Attestation::CreateSignedPublicKey(
    const CertifiedKey& key,
    brillo::SecureBlob* signed_public_key) {
  // Get the certified public key as an EVP_PKEY.
  const unsigned char* asn1_ptr =
    reinterpret_cast<const unsigned char*>(key.public_key().data());
  std::unique_ptr<RSA, RSADeleter> rsa(
      d2i_RSAPublicKey(NULL, &asn1_ptr, key.public_key().size()));
  if (!rsa.get())
    return false;
  std::unique_ptr<EVP_PKEY, EVP_PKEYDeleter> public_key(EVP_PKEY_new());
  if (!public_key.get())
    return false;
  EVP_PKEY_assign_RSA(public_key.get(), rsa.release());

  // Fill in the public key.
  std::unique_ptr<NETSCAPE_SPKI, NETSCAPE_SPKIDeleter>
      spki(NETSCAPE_SPKI_new());
  if (!spki.get())
    return false;
  if (!NETSCAPE_SPKI_set_pubkey(spki.get(), public_key.get()))
    return false;

  // Fill in a random challenge.
  SecureBlob challenge;
  if (!tpm_->GetRandomData(kNonceSize, &challenge))
    return false;
  std::string challenge_hex = base::HexEncode(challenge.data(),
                                              challenge.size());
  if (!ASN1_STRING_set(spki.get()->spkac->challenge,
                       challenge_hex.data(),
                       challenge_hex.size()))
    return false;

  // Generate the signature.
  unsigned char* buffer = NULL;
  int length = i2d_NETSCAPE_SPKAC(spki.get()->spkac, &buffer);
  if (length <= 0)
    return false;
  SecureBlob data_to_sign(buffer, buffer + length);
  OPENSSL_free(buffer);
  SecureBlob signature;
  if (!tpm_->Sign(SecureBlob(key.key_blob()),
                  data_to_sign,
                  kNotBoundToPCR,
                  &signature)) {
    return false;
  }

  // Fill in the signature and algorithm.
  if (!ASN1_BIT_STRING_set(spki.get()->signature,
                           reinterpret_cast<unsigned char*>(signature.data()),
                           signature.size())) {
    return false;
  }
  // Be explicit that there are zero unused bits; otherwise i2d below will
  // automatically detect unused bits but signatures require zero unused bits.
  spki.get()->signature->flags = ASN1_STRING_FLAG_BITS_LEFT;
  X509_ALGOR_set0(spki.get()->sig_algor,
                  OBJ_nid2obj(NID_sha256WithRSAEncryption),
                  V_ASN1_NULL,
                  NULL);

  // DER encode.
  buffer = NULL;
  length = i2d_NETSCAPE_SPKI(spki.get(), &buffer);
  if (length <= 0)
    return false;
  SecureBlob tmp(buffer, buffer + length);
  OPENSSL_free(buffer);
  signed_public_key->swap(tmp);

  return true;
}

bool Attestation::AesEncrypt(const brillo::SecureBlob& plaintext,
                const brillo::SecureBlob& key,
                const brillo::SecureBlob& iv,
                brillo::SecureBlob* ciphertext) {
  return CryptoLib::AesEncryptSpecifyBlockMode(plaintext, 0, plaintext.size(),
                                               key, iv,
                                               CryptoLib::kPaddingStandard,
                                               CryptoLib::kCbc,
                                               ciphertext);
}

bool Attestation::AesDecrypt(const brillo::SecureBlob& ciphertext,
                const brillo::SecureBlob& key,
                const brillo::SecureBlob& iv,
                brillo::SecureBlob* plaintext) {
  return CryptoLib::AesDecryptSpecifyBlockMode(ciphertext, 0, ciphertext.size(),
                                               key, iv,
                                               CryptoLib::kPaddingStandard,
                                               CryptoLib::kCbc,
                                               plaintext);
}

bool Attestation::TssCompatibleEncrypt(const SecureBlob& key,
                                       const SecureBlob& input,
                                       SecureBlob* output) {
  CHECK(output);
  if (key.size() != kCipherKeySize) {
    LOG(ERROR) << "Wrong key size!";
    return false;
  }
  SecureBlob iv(AES_BLOCK_SIZE);
  CryptoLib::GetSecureRandom(reinterpret_cast<unsigned char*>(iv.data()),
                             AES_BLOCK_SIZE);
  SecureBlob encrypted_input;
  if (!AesEncrypt(input, key, iv, &encrypted_input)) {
    LOG(ERROR) << "Error encrypting input.";
    return false;
  }
  *output = SecureBlob::Combine(iv, encrypted_input);
  return true;
}

bool Attestation::TpmCompatibleOAEPEncrypt(RSA* key,
                                           const brillo::SecureBlob& input,
                                           brillo::SecureBlob* output) {
  CHECK(output);
  // The custom OAEP parameter as specified in TPM Main Part 1, Section 31.1.1.
  const unsigned char oaep_param[4] = {'T', 'C', 'P', 'A'};
  brillo::SecureBlob padded_input(RSA_size(key));
  unsigned char* padded_buffer = padded_input.data();
  const unsigned char* input_buffer = input.data();
  int result = RSA_padding_add_PKCS1_OAEP(padded_buffer, padded_input.size(),
                                          input_buffer, input.size(),
                                          oaep_param, arraysize(oaep_param));
  if (!result) {
    LOG(ERROR) << "Failed to add OAEP padding.";
    return false;
  }
  output->resize(padded_input.size());
  unsigned char* output_buffer = output->data();
  result = RSA_public_encrypt(padded_input.size(), padded_buffer,
                              output_buffer, key, RSA_NO_PADDING);
  if (result == -1) {
    LOG(ERROR) << "Failed to encrypt OAEP padded input.";
    return false;
  }
  return true;
}

int Attestation::ChooseTemporalIndex(const std::string& user,
                                     const std::string& origin) {
  std::string user_hash = CryptoLib::Sha256(SecureBlob(user)).to_string();
  std::string origin_hash = CryptoLib::Sha256(SecureBlob(origin)).to_string();
  int histogram[kNumTemporalValues] = {0};
  for (int i = 0; i < database_pb_.temporal_index_record_size(); ++i) {
    const AttestationDatabase::TemporalIndexRecord& record =
        database_pb_.temporal_index_record(i);
    // Ignore out-of-range index values.
    if (record.temporal_index() < 0 ||
        record.temporal_index() >= kNumTemporalValues)
      continue;
    if (record.origin_hash() == origin_hash) {
      if (record.user_hash() == user_hash) {
        // We've previously chosen this index for this user, reuse it.
        return record.temporal_index();
      } else {
        // We've previously chosen this index for another user.
        ++histogram[record.temporal_index()];
      }
    }
  }
  int least_used_index = 0;
  for (int i = 1; i < kNumTemporalValues; ++i) {
    if (histogram[i] < histogram[least_used_index])
      least_used_index = i;
  }
  if (histogram[least_used_index] > 0) {
    LOG(WARNING) << "Unique origin-specific identifiers have been exhausted.";
    ReportCrosEvent(kAttestationOriginSpecificIdentifiersExhausted);
  }
  // Record our choice for later reference.
  AttestationDatabase::TemporalIndexRecord* new_record =
      database_pb_.add_temporal_index_record();
  new_record->set_origin_hash(origin_hash);
  new_record->set_user_hash(user_hash);
  new_record->set_temporal_index(least_used_index);
  PersistDatabaseChanges();
  return least_used_index;
}

void Attestation::FinalizeEndorsementData() {
  if (retain_endorsement_data_) {
    return;
  }
  // Only finalize endorsement data after install attributes are finalized.
  if (install_attributes_->is_first_install()) {
    return;
  }
  if (!database_pb_.has_credentials()) {
    return;
  }
  TPMCredentials* credentials = database_pb_.mutable_credentials();
  if (!credentials->has_endorsement_credential()) {
    return;
  }
  if (!credentials->has_default_encrypted_endorsement_credential()) {
    LOG(INFO) << "Attestation: Migrating default endorsement data.";
    if (!EncryptEndorsementCredential(
        kDefaultPCA,
        SecureBlob(credentials->endorsement_credential()),
        credentials->mutable_default_encrypted_endorsement_credential())) {
      LOG(ERROR) << "Attestation: Failed to encrypt EK cert.";
      return;
    }
  }
  if (!credentials->has_test_encrypted_endorsement_credential()) {
    LOG(INFO) << "Attestation: Migrating endorsement data (test).";
    if (!EncryptEndorsementCredential(
        kTestPCA,
        SecureBlob(credentials->endorsement_credential()),
        credentials->mutable_test_encrypted_endorsement_credential())) {
      LOG(ERROR) << "Attestation: Failed to encrypt EK cert (test).";
      return;
    }
  }
  if (!credentials->has_alternate_encrypted_endorsement_credential() &&
      install_attributes_->Get(kAlternatePCAKeyAttributeName, NULL)) {
    LOG(INFO) << "Attestation: Migrating endorsement data (alternate).";
    if (!EncryptEndorsementCredential(
        kAlternatePCA,
        SecureBlob(credentials->endorsement_credential()),
        credentials->mutable_alternate_encrypted_endorsement_credential())) {
      LOG(ERROR) << "Attestation: Failed to encrypt EK cert (alternate).";
      return;
    }
  }
  LOG(INFO) << "Attestation: Clearing endorsement data.";
  ClearString(credentials->mutable_endorsement_public_key());
  credentials->clear_endorsement_public_key();
  ClearString(credentials->mutable_endorsement_credential());
  credentials->clear_endorsement_credential();
  if (!PersistDatabaseChanges()) {
    LOG(ERROR) << "Attestation: Failed to persist database changes.";
  }
}

bool Attestation::GetDelegateCredentials(brillo::SecureBlob* blob,
                                         brillo::SecureBlob* secret,
                                         bool* has_reset_lock_permissions) {
  if (!IsPreparedForEnrollment()) {
    return false;
  }
  SecureBlob tmp_blob(database_pb_.delegate().blob());
  blob->swap(tmp_blob);
  SecureBlob tmp_secret(database_pb_.delegate().secret());
  secret->swap(tmp_secret);
  *has_reset_lock_permissions =
      database_pb_.delegate().has_reset_lock_permissions();
  return true;
}

bool Attestation::GetCachedEndorsementData(
    brillo::SecureBlob* ek_public_key,
    brillo::SecureBlob* ek_certificate) {
  if (!database_pb_.has_credentials()) {
    return false;
  }
  const TPMCredentials& credentials = database_pb_.credentials();
  // If the TPM is not owned it's possible we have access to the public key but
  // not to the certificate.
  if (!credentials.has_endorsement_public_key()) {
    return false;
  }
  SecureBlob tmp_public_key(credentials.endorsement_public_key());
  ek_public_key->swap(tmp_public_key);
  SecureBlob tmp_credential(credentials.endorsement_credential());
  ek_certificate->swap(tmp_credential);
  return true;
}

void Attestation::CacheEndorsementData() {
  // Before taking ownership we can only cache the public key. After taking
  // ownership this is taken care of by the prepare-for-enrollment process.
  if (tpm_->IsOwned() ||
      (database_pb_.has_credentials() &&
       database_pb_.credentials().has_endorsement_public_key())) {
    return;
  }
  SecureBlob public_key_blob;
  if (!tpm_->GetEndorsementPublicKey(&public_key_blob)) {
    LOG(WARNING) << "TPM is not owned but failed to cache EK public key.";
    return;
  }
  database_pb_.mutable_credentials()->set_endorsement_public_key(
      public_key_blob.data(),
      public_key_blob.size());
}

bool Attestation::IsTPMReady() {
  if (!is_tpm_ready_ && tpm_)
    is_tpm_ready_ = tpm_->IsEnabled() &&
                    tpm_->IsOwned() &&
                    !tpm_->IsBeingOwned();
  return is_tpm_ready_;
}

void Attestation::ExtendPCR1IfClear() {
  SecureBlob current_pcr_value;
  if (!tpm_->ReadPCR(1, &current_pcr_value) ||
      current_pcr_value.size() != kDigestSize) {
    LOG(WARNING) << "Failed to read PCR1.";
    return;
  }
  brillo::Blob default_pcr_value(kDigestSize, 0);
  if (!std::equal(default_pcr_value.begin(), default_pcr_value.end(),
                  current_pcr_value.begin())) {
    // The PCR has already been extended.
    return;
  }
  std::string hwid = platform_->GetHardwareID();
  LOG(WARNING) << "Extending PCR1.";
  // Take the first 20 bytes of a SHA-256 hash because this is what firmware
  // would do. (Using SHA-256 allows a single precomputed hash to be stored
  // along with the HWID for both TPM 1.2 and 2.0 platforms).
  SecureBlob hwid_hash = CryptoLib::Sha256(SecureBlob(hwid));
  SecureBlob extension(hwid_hash.begin(), hwid_hash.begin() + kDigestSize);
  if (hwid.length() == 0 || !tpm_->ExtendPCR(1, extension)) {
    LOG(WARNING) << "Failed to extend PCR1.";
  }
}

bool Attestation::SendPCARequestAndBlock(PCAType pca_type,
                                         PCARequestType request_type,
                                         const brillo::SecureBlob& request,
                                         brillo::SecureBlob* reply) {
  std::shared_ptr<brillo::http::Transport> transport = http_transport_;
  if (!transport) {
    transport = brillo::http::Transport::CreateDefault();
  }
  std::unique_ptr<brillo::http::Response> response = PostBinaryAndBlock(
      GetPCAURL(pca_type, request_type),
      request.data(),
      request.size(),
      brillo::mime::application::kOctet_stream,
      {},  // headers
      transport,
      NULL);  // error
  if (!response->IsSuccessful()) {
    LOG(ERROR) << "HTTP request to PCA failed.";
    return false;
  }
  std::vector<uint8_t> response_data = response->ExtractData();
  SecureBlob tmp(response_data.begin(), response_data.end());
  reply->swap(tmp);
  return true;
}

std::string Attestation::GetPCAURL(PCAType pca_type,
                                   PCARequestType request_type) const {
  std::string url;
  switch (pca_type) {
    case kDefaultPCA:
      url = kDefaultPCAWebOrigin;
      break;
    case kAlternatePCA:
      {
        brillo::SecureBlob url_blob;
        if (!install_attributes_->Get(kAlternatePCAUrlAttributeName,
                                      &url_blob)) {
          LOG(ERROR) << "Cannot find alternate PCA URL.";
          return std::string();
        }
        url = url_blob.to_string();
      }
      break;
    default:
      NOTREACHED();
  }

  switch (request_type) {
    case kEnroll:
      url += "/enroll";
      break;
    case kGetCertificate:
      url += "/sign";
      break;
    default:
      NOTREACHED();
  }
  return url;
}

bool Attestation::ComputeEnterpriseEnrollmentNonce(
    brillo::SecureBlob* enterprise_enrollment_nonce) {
  if (abe_data_.empty()) {
    // If there is no device secret we cannot compute the DEN. We do not
    // want to fail attestation for those devices.
    enterprise_enrollment_nonce->clear();
    return true;
  }
  const uint8_t* context_name = reinterpret_cast<const uint8_t*>(
      kAttestationBasedEnterpriseEnrollmentContextName);
  SecureBlob context_key(context_name, context_name
      + sizeof(kAttestationBasedEnterpriseEnrollmentContextName) - 1);
  SecureBlob nonce = CryptoLib::HmacSha256(context_key, abe_data_);
  enterprise_enrollment_nonce->swap(nonce);
  return true;
}

void Attestation::RSADeleter::operator()(void* ptr) const {
  if (ptr)
    RSA_free(reinterpret_cast<RSA*>(ptr));
}

void Attestation::X509Deleter::operator()(void* ptr) const {
  if (ptr)
    X509_free(reinterpret_cast<X509*>(ptr));
}

void Attestation::EVP_PKEYDeleter::operator()(void* ptr) const {
  if (ptr)
    EVP_PKEY_free(reinterpret_cast<EVP_PKEY*>(ptr));
}

void Attestation::NETSCAPE_SPKIDeleter::operator()(void* ptr) const {
  if (ptr)
    NETSCAPE_SPKI_free(reinterpret_cast<NETSCAPE_SPKI*>(ptr));
}

}  // namespace cryptohome
