blob: d2d7e79f311c0a8821595f88a2957efc0cc1dbb1 [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATTESTATION_SERVER_ATTESTATION_SERVICE_H_
#define ATTESTATION_SERVER_ATTESTATION_SERVICE_H_
#include "attestation/common/attestation_interface.h"
#include <stdint.h>
#include <atomic>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <attestation/proto_bindings/attestation_ca.pb.h>
#include <attestation/proto_bindings/pca_agent.pb.h>
#include <base/callback.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/optional.h>
#include <base/threading/thread.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest_prod.h>
#include <policy/libpolicy.h>
#include "attestation/common/crypto_utility.h"
#include "attestation/common/crypto_utility_impl.h"
#include "attestation/common/tpm_utility_factory.h"
#include "attestation/pca_agent/dbus-proxies.h"
#include "attestation/server/attestation_flow.h"
#include "attestation/server/attestation_service_metrics.h"
#include "attestation/server/certificate_queue.h"
#include "attestation/server/database.h"
#include "attestation/server/database_impl.h"
#include "attestation/server/enrollment_queue.h"
#include "attestation/server/google_keys.h"
#include "attestation/server/key_store.h"
#include "attestation/server/pkcs11_key_store.h"
#include "tpm_manager/client/tpm_nvram_dbus_proxy.h"
#include "tpm_manager/client/tpm_ownership_dbus_proxy.h"
#include "tpm_manager/common/tpm_nvram_interface.h"
#include "tpm_manager/common/tpm_ownership_interface.h"
namespace attestation {
// An implementation of AttestationInterface for the core attestation service.
// Access to TPM, network and local file-system resources occurs asynchronously
// with the exception of Initialize(). All methods must be called on the same
// thread that originally called Initialize().
// Usage:
// std::unique_ptr<AttestationInterface> attestation =
// new AttestationService();
// CHECK(attestation->Initialize(nullptr));
// attestation->GetEndorsementInfo(...);
//
// THREADING NOTES:
// This class runs a worker thread and delegates all calls to it. This keeps the
// public methods non-blocking while allowing complex implementation details
// with dependencies on the TPM, network, and filesystem to be coded in a more
// readable way. It also serves to serialize method execution which reduces
// complexity with TPM state.
//
// Tasks that run on the worker thread are bound with base::Unretained which is
// safe because the thread is owned by this class (so it is guaranteed not to
// process a task after destruction). Weak pointers are used to post replies
// back to the main thread.
class AttestationService : public AttestationInterface {
public:
using IdentityCertificateMap = google::protobuf::
Map<int, attestation::AttestationDatabase_IdentityCertificate>;
using InitializeCompleteCallback = base::OnceCallback<void(bool)>;
// The index of the first identity.
static constexpr int kFirstIdentity = 0;
// The request limit for enrollment queue.
constexpr static size_t kEnrollmentRequestLimit = 50;
// The alias limit for certification queue.
const size_t kCertificateRequestAliasLimit = 5;
// If abe_data is not an empty blob, its contents will be
// used to enable attestation-based enterprise enrollment.
explicit AttestationService(brillo::SecureBlob* abe_data);
AttestationService(const AttestationService&) = delete;
AttestationService& operator=(const AttestationService&) = delete;
~AttestationService() override = default;
// AttestationInterface methods.
bool Initialize() override;
void GetEnrollmentPreparations(
const GetEnrollmentPreparationsRequest& request,
const GetEnrollmentPreparationsCallback& callback) override;
void GetKeyInfo(const GetKeyInfoRequest& request,
const GetKeyInfoCallback& callback) override;
void GetEndorsementInfo(const GetEndorsementInfoRequest& request,
const GetEndorsementInfoCallback& callback) override;
void GetAttestationKeyInfo(
const GetAttestationKeyInfoRequest& request,
const GetAttestationKeyInfoCallback& callback) override;
void ActivateAttestationKey(
const ActivateAttestationKeyRequest& request,
const ActivateAttestationKeyCallback& callback) override;
void CreateCertifiableKey(
const CreateCertifiableKeyRequest& request,
const CreateCertifiableKeyCallback& callback) override;
void Decrypt(const DecryptRequest& request,
const DecryptCallback& callback) override;
void Sign(const SignRequest& request, const SignCallback& callback) override;
void RegisterKeyWithChapsToken(
const RegisterKeyWithChapsTokenRequest& request,
const RegisterKeyWithChapsTokenCallback& callback) override;
void GetStatus(const GetStatusRequest& request,
const GetStatusCallback& callback) override;
void Verify(const VerifyRequest& request,
const VerifyCallback& callback) override;
void CreateEnrollRequest(
const CreateEnrollRequestRequest& request,
const CreateEnrollRequestCallback& callback) override;
void FinishEnroll(const FinishEnrollRequest& request,
const FinishEnrollCallback& callback) override;
void Enroll(const EnrollRequest& request,
const EnrollCallback& callback) override;
void CreateCertificateRequest(
const CreateCertificateRequestRequest& request,
const CreateCertificateRequestCallback& callback) override;
void FinishCertificateRequest(
const FinishCertificateRequestRequest& request,
const FinishCertificateRequestCallback& callback) override;
void GetCertificate(const GetCertificateRequest& request,
const GetCertificateCallback& callback) override;
void SignEnterpriseChallenge(
const SignEnterpriseChallengeRequest& request,
const SignEnterpriseChallengeCallback& callback) override;
void SignSimpleChallenge(
const SignSimpleChallengeRequest& request,
const SignSimpleChallengeCallback& callback) override;
void SetKeyPayload(const SetKeyPayloadRequest& request,
const SetKeyPayloadCallback& callback) override;
void DeleteKeys(const DeleteKeysRequest& request,
const DeleteKeysCallback& callback) override;
void ResetIdentity(const ResetIdentityRequest& request,
const ResetIdentityCallback& callback) override;
void GetEnrollmentId(const GetEnrollmentIdRequest& request,
const GetEnrollmentIdCallback& callback) override;
void GetCertifiedNvIndex(
const GetCertifiedNvIndexRequest& request,
const GetCertifiedNvIndexCallback& callback) override;
// Same as initialize but calls callback when tasks finish.
bool InitializeWithCallback(InitializeCompleteCallback callback);
// Return the type of the endorsement key (EK).
KeyType GetEndorsementKeyType() const;
// Return the type of the attestation identity key (AIK).
KeyType GetAttestationIdentityKeyType() const;
// Mutators useful for testing.
void set_crypto_utility(CryptoUtility* crypto_utility) {
crypto_utility_ = crypto_utility;
}
void set_database(Database* database) { database_ = database; }
void set_key_store(KeyStore* key_store) { key_store_ = key_store; }
void set_tpm_utility(TpmUtility* tpm_utility) { tpm_utility_ = tpm_utility; }
void set_hwid(const std::string& hwid) { hwid_ = hwid; }
void set_abe_data(brillo::SecureBlob* abe_data) { abe_data_ = abe_data; }
void set_pca_agent_proxy(org::chromium::PcaAgentProxyInterface* proxy) {
pca_agent_proxy_ = proxy;
}
void set_google_keys(GoogleKeys google_keys) {
google_keys_ = std::move(google_keys);
}
void set_policy_provider(policy::PolicyProvider* policy_provider) {
policy_provider_.reset(policy_provider);
}
private:
enum class EnrollmentStatus {
kUnknown,
kNotEnrolled,
kInProgress,
kEnrolled,
};
enum ACATypeInternal { kDefaultACA = 0, kTestACA = 1, kMaxACATypeInternal };
static ACAType GetACAType(ACATypeInternal aca_type_internal);
friend class AttestationServiceBaseTest;
friend class AttestationServiceTest;
typedef std::map<std::string, std::string> CertRequestMap;
// Attestation service worker thread class that cleans up after stopping.
class ServiceWorkerThread : public base::Thread {
public:
explicit ServiceWorkerThread(AttestationService* service)
: base::Thread("Attestation Service Worker"), service_(service) {
DCHECK(service_);
}
ServiceWorkerThread(const ServiceWorkerThread&) = delete;
ServiceWorkerThread& operator=(const ServiceWorkerThread&) = delete;
~ServiceWorkerThread() override { Stop(); }
private:
void CleanUp() override { service_->ShutdownTask(); }
AttestationService* const service_;
};
// A relay callback which allows the use of weak pointer semantics for a reply
// to TaskRunner::PostTaskAndReply.
template <typename ReplyProtobufType>
void TaskRelayCallback(
const base::Callback<void(const ReplyProtobufType&)> callback,
const std::shared_ptr<ReplyProtobufType>& reply) {
callback.Run(*reply);
}
// Initialization to be run on the worker thread.
void InitializeTask(InitializeCompleteCallback callback);
// Checks if |database_| needs to be migrated to the latest data model and
// do so if needed. Returns true if migration was needed and successful.
bool MigrateAttestationDatabase();
// Migrates identity date in |database_| if needed. Returns true if the
// migration was needed and successful.
// Note that this function is not multithread safe.
bool MigrateIdentityData();
// Shutdown to be run on the worker thread.
void ShutdownTask();
// A blocking implementation of GetEnrollmentPreparations.
void GetEnrollmentPreparationsTask(
const GetEnrollmentPreparationsRequest& request,
const std::shared_ptr<GetEnrollmentPreparationsReply>& result);
// A blocking implementation of GetKeyInfo.
void GetKeyInfoTask(const GetKeyInfoRequest& request,
const std::shared_ptr<GetKeyInfoReply>& result);
// A blocking implementation of GetEndorsementInfo.
void GetEndorsementInfoTask(
const GetEndorsementInfoRequest& request,
const std::shared_ptr<GetEndorsementInfoReply>& result);
// A blocking implementation of GetAttestationKeyInfo.
void GetAttestationKeyInfoTask(
const GetAttestationKeyInfoRequest& request,
const std::shared_ptr<GetAttestationKeyInfoReply>& result);
// A blocking implementation of ActivateAttestationKey.
void ActivateAttestationKeyTask(
const ActivateAttestationKeyRequest& request,
const std::shared_ptr<ActivateAttestationKeyReply>& result);
// A blocking implementation of CreateCertifiableKey.
void CreateCertifiableKeyTask(
const CreateCertifiableKeyRequest& request,
const std::shared_ptr<CreateCertifiableKeyReply>& result);
// A blocking implementation of Decrypt.
void DecryptTask(const DecryptRequest& request,
const std::shared_ptr<DecryptReply>& result);
// A blocking implementation of Sign.
void SignTask(const SignRequest& request,
const std::shared_ptr<SignReply>& result);
// A synchronous implementation of RegisterKeyWithChapsToken.
void RegisterKeyWithChapsTokenTask(
const RegisterKeyWithChapsTokenRequest& request,
const std::shared_ptr<RegisterKeyWithChapsTokenReply>& result);
// A synchronous implementation of GetStatus.
void GetStatusTask(const GetStatusRequest& request,
const std::shared_ptr<GetStatusReply>& result);
// A synchronous implementation of Verify.
void VerifyTask(const VerifyRequest& request,
const std::shared_ptr<VerifyReply>& result);
// A synchronous implementation of CreateEnrollRequest.
template <typename RequestType>
void CreateEnrollRequestTask(
const RequestType& request,
const std::shared_ptr<CreateEnrollRequestReply>& result);
// A synchronous implementation of FinishEnroll.
template <typename ReplyType>
void FinishEnrollTask(const FinishEnrollRequest& request,
const std::shared_ptr<ReplyType>& result);
// A synchronous implementation of CreateCertificateRequest.
template <typename RequestType>
void CreateCertificateRequestTask(
const RequestType& request,
const std::shared_ptr<CreateCertificateRequestReply>& result);
// A synchronous implementation of FinishCertificateRequest.
template <typename ReplyType>
void FinishCertificateRequestTask(
const FinishCertificateRequestRequest& request,
const std::shared_ptr<ReplyType>& result);
// A synchronous implementation of SignEnterpriseChallenge.
void SignEnterpriseChallengeTask(
const SignEnterpriseChallengeRequest& request,
const std::shared_ptr<SignEnterpriseChallengeReply>& result);
// A synchronous implementation of SignSimpleChallenge.
void SignSimpleChallengeTask(
const SignSimpleChallengeRequest& request,
const std::shared_ptr<SignSimpleChallengeReply>& result);
// A synchronous implementation of SetKeyPayload.
void SetKeyPayloadTask(const SetKeyPayloadRequest& request,
const std::shared_ptr<SetKeyPayloadReply>& result);
// A synchronous implementation of DeleteKeys.
void DeleteKeysTask(const DeleteKeysRequest& request,
const std::shared_ptr<DeleteKeysReply>& result);
// A synchronous implementation of ResetIdentity.
void ResetIdentityTask(const ResetIdentityRequest& request,
const std::shared_ptr<ResetIdentityReply>& result);
// A synchronous implementation for GetEnrollmentId.
void GetEnrollmentIdTask(const GetEnrollmentIdRequest& request,
const std::shared_ptr<GetEnrollmentIdReply>& result);
// A synchronous implementation for GetCertifiedNvIndex.
void GetCertifiedNvIndexTask(
const GetCertifiedNvIndexRequest& request,
const std::shared_ptr<GetCertifiedNvIndexReply>& result);
// Returns true if PrepareForEnrollment() initialization step has been
// successfully done for any Google Attestation CA.
// Note that while in normal circumstance, this returning true means that all
// info required for enrollment is available, but that's not always the case,
// see the implementation for detail.
bool IsPreparedForEnrollment();
// Returns true if PrepareForEnrollment() initialization step has been
// successfully done for the given Google Attestation CA.
bool IsPreparedForEnrollmentWithACA(ACAType aca_type);
// Returns true iff enrollment with the default or test Google Attestation CA
// has been completed.
bool IsEnrolled();
// Returns true iff enrollment with the given Google Attestation CA has been
// completed.
bool IsEnrolledWithACA(ACAType aca_type);
// Creates an enrollment request compatible with the Google Attestation CA.
// Returns true on success.
bool CreateEnrollRequestInternal(ACAType aca_type,
std::string* enroll_request);
// Finishes enrollment given an |enroll_response| from the Google Attestation
// CA. Returns true on success. On failure, returns false and sets
// |server_error| to the error string from the CA.
bool FinishEnrollInternal(ACAType aca_type,
const std::string& enroll_response,
std::string* server_error);
// Creates a |certificate_request| compatible with the Google Attestation CA
// for the given |key|, according to the given |profile|, |username| and
// |origin|.
bool CreateCertificateRequestInternal(ACAType aca_type,
const std::string& username,
const CertifiedKey& key,
CertificateProfile profile,
const std::string& origin,
std::string* certificate_request,
std::string* message_id);
// Finishes a certificate request by decoding the |certificate_response| to
// recover the |certificate_chain| and storing it in association with the
// |key| identified by |username| and |key_label|. Returns true on success. On
// failure, returns false and sets |server_error| to the error string from the
// CA. Calls PopulateAndStoreCertifiedKey internally.
bool FinishCertificateRequestInternal(const std::string& certificate_response,
const std::string& username,
const std::string& key_label,
const std::string& message_id,
CertifiedKey* key,
std::string* certificate_chain,
std::string* server_error);
// Recover the |certificate_chain| from |response_pb| and store it in
// association with the |key| identified by |username| and |key_label|.
// Returns true on success.
bool PopulateAndStoreCertifiedKey(
const AttestationCertificateResponse& response_pb,
const std::string& username,
const std::string& key_label,
CertifiedKey* key,
std::string* certificate_chain);
// Creates, certifies, and saves a new |key| for |username| with the given
// |key_label|, |key_type|, and |key_usage|. Returns true on success.
bool CreateKey(const std::string& username,
const std::string& key_label,
KeyType key_type,
KeyUsage key_usage,
CertifiedKey* key);
// Finds the |key| associated with |username| and |key_label|. Returns false
// if such a key does not exist.
bool FindKeyByLabel(const std::string& username,
const std::string& key_label,
CertifiedKey* key);
// Saves the |key| associated with |username| and |key_label|. Returns true on
// success.
bool SaveKey(const std::string& username,
const std::string& key_label,
const CertifiedKey& key);
// Deletes the key associated with |username| and |key_label|.
bool DeleteKey(const std::string& username, const std::string& key_label);
// Deletes the key associated with |username| and having prefix |key_prefix|.
bool DeleteKeysByPrefix(const std::string& username,
const std::string& key_prefix);
// Adds named device-wide key to the attestation database.
bool AddDeviceKey(const std::string& key_label, const CertifiedKey& key);
// Removes a device-wide key from the attestation database.
bool RemoveDeviceKey(const std::string& key_label);
// Removes device-wide keys with a given prefix from the attestation
// database.
bool RemoveDeviceKeysByPrefix(const std::string& key_prefix);
// Creates a PEM certificate chain from the credential fields of a |key|.
std::string CreatePEMCertificateChain(const CertifiedKey& key);
// Creates a certificate in PEM format from a DER encoded X.509 certificate.
std::string CreatePEMCertificate(const std::string& certificate);
// Chooses a temporal index which will be used by the ACA to create a
// certificate. This decision factors in the currently signed-in |user| and
// the |origin| of the certificate request. The strategy is to find an index
// which has not already been used by another user for the same origin.
int ChooseTemporalIndex(const std::string& user, const std::string& origin);
// Creates a X.509/DER SubjectPublicKeyInfo for the given |key_type| and
// |public_key|. On success returns true and provides |public_key_info|.
// TODO(crbug/942487): After this migration, we won't need this utility
// anymore. For now, we store ECC public key as SubjectPublicKeyInfo format,
// which will be passed as |public_key|.
bool GetSubjectPublicKeyInfo(KeyType key_type,
const std::string& public_key,
std::string* public_key_info) const;
// Get endorsement public key. Get it from proto database if exists, otherwise
// get it from tpm_utility.
base::Optional<std::string> GetEndorsementPublicKey() const;
// Get endorsement certificate. Get it from proto database if exists,
// otherwise get it from tpm_utility.
base::Optional<std::string> GetEndorsementCertificate() const;
// Prepares the attestation system for enrollment with an ACA.
void PrepareForEnrollment(InitializeCompleteCallback callback);
// Gets the customerId from the policy data and populates in |key_info|.
bool PopulateCustomerId(KeyInfo* key_info);
// Returns an iterator pointing to the identity certificate for the given
// |identity| and given Privacy CA.
virtual IdentityCertificateMap::iterator FindIdentityCertificate(
int identity, ACAType pca_type);
// Returns whether there is an identity certificate for the given |identity|
// and given Privacy CA.
virtual bool HasIdentityCertificate(int identity, ACAType pca_type);
// Finds an existing identity certificate for the given |identity| and Privacy
// CA, and if none is found, creates one. Returns a pointer to the certificate
// or nullptr if one could not be created. If |cert_index| is non null, set it
// to the index of the certificate, or -1 if none could be found or created.
AttestationDatabase_IdentityCertificate* FindOrCreateIdentityCertificate(
int identity, ACAType aca_type, int* cert_index);
// Creates a new identity and returns its index, or -1 if it could not be
// created.
int CreateIdentity(int identity_features);
// Quote NVRAM data. Returns the quoted data in |quote| and |true| if
// success, |false| otherwise.
bool QuoteNvramData(NVRAMQuoteType quote_type,
const IdentityKey& identity_key,
Quote* quote);
// Certify NVRAM data and insert it into the given |identity|. Returns false
// if data cannot be inserted, or if |must_be_present| is true and the data
// cannot be certified.
bool InsertCertifiedNvramData(NVRAMQuoteType quote_type,
bool must_be_present,
AttestationDatabase::Identity* identity);
// Returns the count of identities in the attestation database.
virtual int GetIdentitiesCount() const;
// Returns the identity features of |identity|.
virtual int GetIdentityFeatures(int identity) const;
// Returns a copy of the identity certificate map.
virtual IdentityCertificateMap GetIdentityCertificateMap() const;
// ENcrypts all the endorsement credentials that we don't have yet.
bool EncryptAllEndorsementCredentials();
// Encrypts data for the given |aca_type|.
bool EncryptDataForAttestationCA(ACAType aca_type,
const std::string& data,
EncryptedData* encrypted_data);
// Activates an attestation key given an |encrypted_certificate|. The EK with
// |ek_key_type| will be used for activation. On success returns true and
// provides the decrypted |certificate| if not null. If |save_certificate| is
// set, also writes the |certificate| to the database and returns the
// certificate number in |certificate_index|. The value of |certificate_index|
// is undefined if the certificate is not saved. |ek_key_type| is only used in
// TPM 2.0.
bool ActivateAttestationKeyInternal(
int identity,
ACAType aca_type,
KeyType ek_key_type,
const EncryptedIdentityCredential& encrypted_certificate,
bool save_certificate,
std::string* certificate,
int* certificate_index);
// Checks if PCR0 indicates that the system booted in verified mode.
// Always reads PCR0 contents from TPM, so works even when not prepared
// for enrollment.
bool IsVerifiedMode() const;
// Validates incoming enterprise challenge data.
bool ValidateEnterpriseChallenge(VAType va_type,
const SignedData& signed_challenge);
// Encrypts a KeyInfo protobuf as required for an enterprise challenge
// response.
bool EncryptEnterpriseKeyInfo(VAType va_type,
const KeyInfo& key_info,
EncryptedData* encrypted_data);
// Signs data using the provided key. On success, returns true and fills
// |response| with serialized SignedData.
bool SignChallengeData(const CertifiedKey& key,
const std::string& data_to_sign,
std::string* response);
// Verifies identity key binding data.
bool VerifyIdentityBinding(const IdentityBinding& binding);
// Computes and returns the PCR value for a known 3-byte |mode|:
// - byte 0: 1 if in developer mode, 0 otherwise,
// - byte 1: 1 if in recovery mode, 0 otherwise,
// - byte 2: 1 if verified firmware, 0 if developer firmware.
std::string GetPCRValueForMode(const char* mode) const;
// Verifies that PCR quote signature is correct.
// aik_public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
bool VerifyQuoteSignature(const std::string& aik_public_key_info,
const Quote& quote,
uint32_t pcr_index);
// Verifies PCR0 quote.
// aik_public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
bool VerifyPCR0Quote(const std::string& aik_public_key_info,
const Quote& pcr0_quote);
// Verifies PCR1 quote.
// aik_public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
bool VerifyPCR1Quote(const std::string& aik_public_key_info,
const Quote& pcr1_quote);
// Calculates the digest for a certified key. The digest is TPM version (1.2
// vs 2.0) specific.
// public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
// public_key_tpm_format must be provided in TPM format.
bool GetCertifiedKeyDigest(const std::string& public_key_info,
const std::string& public_key_tpm_format,
std::string* key_digest);
// Verifies a certified key.
// aik_public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
// public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
// key_info is a TPM_CERTIFY_INFO structure.
bool VerifyCertifiedKey(const std::string& aik_public_key_info,
const std::string& public_key_info,
const std::string& public_key_tpm_format,
const std::string& key_info,
const std::string& proof);
// Creates a certified key and verifies it.
// aik_public_key_info must be provided in X.509 SubjectPublicKeyInfo format.
bool VerifyCertifiedKeyGeneration(const std::string& aik_key_blob,
const std::string& aik_public_key_info);
// Performs AIK activation with a fake credential. It use RSA EK for the fake
// credential sharing.
bool VerifyActivateIdentity(const std::string& aik_public_key_tpm_format);
// Calls the routine corresponding to the |AttestationFlowAction| stored in
// |data| to proceed the next step of the enrollment flow. Most of the actions
// taken are quite self-explanatory except a caveat -- Since enrollment might
// be followed by certificate flow, upon Receiving
// |AttestationFlowAction::kNoop|, the flow might continue by posting
// |StartCertificateTask|.
void OnEnrollAction(const std::shared_ptr<AttestationFlowData>& data);
// Sends the enroll request with the content stored in |data| via
// |pca_agentd|. See |HandlePcaAgentEnrollRequestError| and
// |HandlePcaAgentEnrollReply| for more details.
void SendEnrollRequest(const std::shared_ptr<AttestationFlowData>& data);
// Calls the D-bus method callback stored in |data| with a bad
// |AttestationStatus|. Passed as the error callback of
// |pca_agent::EnrollAsync|.
void HandlePcaAgentEnrollRequestError(
const std::shared_ptr<AttestationFlowData>& data, brillo::Error* err);
// Calls the D-bus method callback stored in |data| with a proper
// |AttestationStatus| depending on the response received from PCA server.
// Passed as the success callback of |pca_agent::EnrollAsync|.
void HandlePcaAgentEnrollReply(
const std::shared_ptr<AttestationFlowData>& data,
const pca_agent::EnrollReply& pca_reply);
// Calls the routine corresponding to the |AttestationFlowAction| stored in
// |data| to proceed the next step of the certificate flow.
void OnGetCertificateAction(const std::shared_ptr<AttestationFlowData>& data);
// Sends the certificate request with the content stored in |data| via
// |pca_agentd|.See |HandlePcaAgentGetCertificateRequestError| and
// |HandlePcaAgentGetCertificateReply| for more details.
void SendGetCertificateRequest(
const std::shared_ptr<AttestationFlowData>& data);
// Calls the D-bus method callback stored in |data| with a bad
// |AttestationStatus|. Passed as the error callback of
// |pca_agent::GetCertificateAsync|.
void HandlePcaAgentGetCertificateRequestError(
const std::shared_ptr<AttestationFlowData>& data, brillo::Error* err);
// Calls the D-bus method callback stored in |data| with a proper
// |AttestationStatus| depending on the response received from PCA server via
// |pca_agentd|. Passed as the success callback of
// |pca_agent::GetCertificateAsync|.
void HandlePcaAgentGetCertificateReply(
const std::shared_ptr<AttestationFlowData>& data,
const pca_agent::GetCertificateReply& pca_reply);
// Creates the enroll request and stores the return status code and the result
// request (if any) into |data|; also, specifies the next
// |AttestationFlowAction| into |data| accordingly.
void StartEnrollTask(const std::shared_ptr<AttestationFlowData>& data);
// Posts |StartEnrollTask|, along with its reply task |OnEnrollAction|.
void PostStartEnrollTask(const std::shared_ptr<AttestationFlowData>& data);
// Finishes the enroll request with the response stored in |data|; also,
// specifies the next |AttestationFlowAction| into |data| accordingly. Named
// with suffix "V2" because the legacy |FinishEnrollTask| exists; function
// overloading causes some unnecessary code change because we have to
// specify the function signature when we posts |FinishEnrollTask|; thus,
// chooses just rename rather than overloading.
void FinishEnrollTaskV2(const std::shared_ptr<AttestationFlowData>& data);
// Creates the certificate request and stores the return status code and the
// result request (if any) into |data|; also, specifies the next
// |AttestationFlowAction| into |data| accordingly.
void StartCertificateTask(const std::shared_ptr<AttestationFlowData>& data);
// Posts |StartCertificateTask| if necessary, i.e., |data| indicates it is
// certification flow instead of just enrollment.
void PostStartCertificateTaskOrReturn(
const std::shared_ptr<AttestationFlowData>& data);
// Finishes the certificate request with the response stored in |data|; also,
// specifies the next |AttestationFlowAction| into |data| accordingly.
void FinishCertificateTask(const std::shared_ptr<AttestationFlowData>& data);
// If the status of |data| is success, it will call |data|s
// |ReturnCertificate|, otherwise it will call |ReturnStatus|. Removes all
// aliases of |data| from |certificate_queue_| and invokes the same method on
// them (|ReturnCertificate| or |ReturnStatus|).
void ReturnForAllCertificateRequestAliases(
const std::shared_ptr<AttestationFlowData>& data);
// Compute the enterprise DEN for attestation-based enrollment.
std::string ComputeEnterpriseEnrollmentNonce();
// Compute the enterprise EID for attestation-based enrollment.
std::string ComputeEnterpriseEnrollmentId();
base::WeakPtr<AttestationService> GetWeakPtr();
FRIEND_TEST(AttestationServiceBaseTest, MigrateAttestationDatabase);
FRIEND_TEST(AttestationServiceBaseTest,
MigrateAttestationDatabaseWithCorruptedFields);
FRIEND_TEST(AttestationServiceBaseTest,
MigrateAttestationDatabaseAllEndorsementCredentials);
FRIEND_TEST_ALL_PREFIXES(AttestationServiceEnterpriseTest,
SignEnterpriseChallengeSuccess);
FRIEND_TEST_ALL_PREFIXES(AttestationServiceEnterpriseTest,
SignEnterpriseChallengeUseKeyForSPKAC);
AttestationServiceMetrics metrics_;
// Other than initialization and destruction, these are used only by the
// worker thread.
CryptoUtility* crypto_utility_{nullptr};
Database* database_{nullptr};
KeyStore* key_store_{nullptr};
// |tpm_utility_| typically points to |default_tpm_utility_| created/destroyed
// on the |worker_thread_|. As such, should not be accessed after that thread
// is stopped/destroyed.
TpmUtility* tpm_utility_{nullptr};
std::string hwid_;
CertRequestMap pending_cert_requests_;
std::string system_salt_;
brillo::SecureBlob* abe_data_;
GoogleKeys google_keys_;
// Default identity features for newly created identities.
int default_identity_features_ =
attestation::IDENTITY_FEATURE_ENTERPRISE_ENROLLMENT_ID;
// Maps NVRAMQuoteType indices to indices into the static NVRAM data we
// use for NVRAM quotes.
std::map<NVRAMQuoteType, int> nvram_quote_type_to_index_data_;
// Default implementations for the above interfaces. These will be setup
// during Initialize() if the corresponding interface has not been set with a
// mutator.
// As |default_database_| has a reference of |default_crypto_utility_| and
// |default_crypto_utility_| has a reference of |default_tpm_utility|,
// the availabilities of these 2 variable follow the rule applied to
// |default_tpm_utility_|. See the comment for |default_tpm_utility_| below.
std::unique_ptr<CryptoUtilityImpl> default_crypto_utility_;
std::unique_ptr<DatabaseImpl> default_database_;
std::unique_ptr<Pkcs11KeyStore> default_key_store_;
std::unique_ptr<chaps::TokenManagerClient> pkcs11_token_manager_;
// |default_tpm_utility_| is created and destroyed on the |worker_thread_|,
// and is not available after the thread is stopped/destroyed.
std::unique_ptr<TpmUtility> default_tpm_utility_;
std::unique_ptr<org::chromium::PcaAgentProxyInterface>
default_pca_agent_proxy_;
org::chromium::PcaAgentProxyInterface* pca_agent_proxy_{nullptr};
// Enrollment statuses for respective ACA type is maintained in this array. By
// default it is zero-initialized, i.e., EnrollmentStatus::kUnknown. Since
// both dbus calling thread and worker thread both mutate the values, we use
// atomic variables to prevent data race and make sure the side effect is
// propagated to other threads immediately.
std::atomic<EnrollmentStatus> enrollment_statuses_[ACAType_ARRAYSIZE]{};
// Used to store the requests during enrollment.
EnrollmentQueue enrollment_queue_{kEnrollmentRequestLimit};
// The certificate queue that is used to store the |AttestationFlowData|
// aliases during certification.
SynchronizedCertificateQueue certificate_queue_{
kCertificateRequestAliasLimit};
// All work is done in the background. This serves to serialize requests and
// allow synchronous implementation of complex methods. This is intentionally
// declared after the thread-owned members.
std::unique_ptr<ServiceWorkerThread> worker_thread_;
// The device policy provider, used to get device policy data.
std::unique_ptr<policy::PolicyProvider> policy_provider_;
// Declared last so any weak pointers are destroyed first.
base::WeakPtrFactory<AttestationService> weak_factory_;
};
} // namespace attestation
#endif // ATTESTATION_SERVER_ATTESTATION_SERVICE_H_