blob: c8246e6f911caae5212f5c630c8d8f250eaa566c [file] [log] [blame]
// Copyright 2016 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 CRYPTOHOME_SERVICE_DISTRIBUTED_H_
#define CRYPTOHOME_SERVICE_DISTRIBUTED_H_
#include <memory>
#include <string>
#include "attestation/common/attestation_interface.h"
#include "cryptohome/service.h"
namespace cryptohome {
// ServiceDistributed
// Represents a Service where attestation functionality is implemented
// in a separated attestationd daemon.
class ServiceDistributed : public Service {
public:
ServiceDistributed();
ServiceDistributed(const ServiceDistributed&) = delete;
ServiceDistributed& operator=(const ServiceDistributed&) = delete;
virtual ~ServiceDistributed();
void AttestationInitialize() override;
void AttestationInitializeTpm() override;
void AttestationInitializeTpmComplete() override;
bool AttestationGetEnrollmentPreparations(
const AttestationGetEnrollmentPreparationsRequest& request,
AttestationGetEnrollmentPreparationsReply* reply) override;
void AttestationGetTpmStatus(GetTpmStatusReply* reply) override;
bool AttestationGetDelegateCredentials(
brillo::Blob* blob,
brillo::Blob* secret,
bool* has_reset_lock_permissions) override;
gboolean TpmIsAttestationPrepared(gboolean* OUT_prepared,
GError** error) override;
gboolean TpmVerifyAttestationData(gboolean is_cros_core,
gboolean* OUT_verified,
GError** error) override;
gboolean TpmVerifyEK(gboolean is_cros_core,
gboolean* OUT_verified,
GError** error) override;
gboolean TpmAttestationCreateEnrollRequest(gint pca_type,
GArray** OUT_pca_request,
GError** error) override;
gboolean AsyncTpmAttestationCreateEnrollRequest(gint pca_type,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationEnroll(gint pca_type,
GArray* pca_response,
gboolean* OUT_success,
GError** error) override;
gboolean AsyncTpmAttestationEnroll(gint pca_type,
GArray* pca_response,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationEnrollEx(gint pca_type,
gboolean forced,
gboolean* OUT_success,
GError** error) override;
gboolean AsyncTpmAttestationEnrollEx(gint pca_type,
gboolean forced,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationCreateCertRequest(gint pca_type,
gint certificate_profile,
gchar* username,
gchar* request_origin,
GArray** OUT_pca_request,
GError** error) override;
gboolean AsyncTpmAttestationCreateCertRequest(gint pca_type,
gint certificate_profile,
gchar* username,
gchar* request_origin,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationFinishCertRequest(GArray* pca_response,
gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray** OUT_cert,
gboolean* OUT_success,
GError** error) override;
gboolean AsyncTpmAttestationFinishCertRequest(GArray* pca_response,
gboolean is_user_specific,
gchar* username,
gchar* key_name,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationGetCertificateEx(gint certificate_profile,
gchar* username,
gchar* request_origin,
gint pca_type,
gint key_type,
gchar* key_name,
gboolean forced,
gboolean shall_trigger_enrollment,
GArray** OUT_certificate,
gboolean* OUT_success,
GError** error) override;
gboolean AsyncTpmAttestationGetCertificateEx(
gint certificate_profile,
gchar* username,
gchar* request_origin,
gint pca_type,
gint key_type,
gchar* key_name,
gboolean forced,
gboolean shall_trigger_enrollment,
gint* OUT_async_id,
GError** error) override;
gboolean TpmIsAttestationEnrolled(gboolean* OUT_is_enrolled,
GError** error) override;
gboolean TpmAttestationDoesKeyExist(gboolean is_user_specific,
gchar* username,
gchar* key_name,
gboolean* OUT_exists,
GError** error) override;
gboolean TpmAttestationGetCertificate(gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray** OUT_certificate,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationGetPublicKey(gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray** OUT_public_key,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationRegisterKey(gboolean is_user_specific,
gchar* username,
gchar* key_name,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationSignEnterpriseChallenge(
gboolean is_user_specific,
gchar* username,
gchar* key_name,
gchar* domain,
GArray* device_id,
gboolean include_signed_public_key,
GArray* challenge,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationSignEnterpriseVaChallenge(
gint va_type,
gboolean is_user_specific,
gchar* username,
gchar* key_name,
gchar* domain,
GArray* device_id,
gboolean include_signed_public_key,
GArray* challenge,
gchar* key_name_for_spkac,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationSignSimpleChallenge(gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray* challenge,
gint* OUT_async_id,
GError** error) override;
gboolean TpmAttestationGetKeyPayload(gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray** OUT_payload,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationSetKeyPayload(gboolean is_user_specific,
gchar* username,
gchar* key_name,
GArray* payload,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationDeleteKeys(gboolean is_user_specific,
gchar* username,
gchar* key_prefix,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationDeleteKey(gboolean is_user_specific,
gchar* username,
gchar* key_name,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationGetEK(gchar** ek_info,
gboolean* OUT_success,
GError** error) override;
gboolean TpmAttestationResetIdentity(gchar* reset_token,
GArray** OUT_reset_request,
gboolean* OUT_success,
GError** error) override;
gboolean GetEndorsementInfo(const GArray* request,
DBusGMethodInvocation* context) override;
gboolean InitializeCastKey(const GArray* request,
DBusGMethodInvocation* context) override;
gboolean TpmAttestationGetEnrollmentId(gboolean ignore_cache,
GArray** OUT_enrollment_id,
gboolean* OUT_success,
GError** error) override;
private:
// A helper function which maps an integer to a valid CertificateProfile.
static attestation::CertificateProfile GetProfile(int profile_value);
// Send GetKeyInfoRequest to attestationd and wait for reply.
bool GetKeyInfo(gboolean is_user_specific,
gchar* username,
gchar* key_name,
attestation::GetKeyInfoReply* key_info);
// Prepare interface to attestationd, if not prepared yet.
// Can be called multiple times.
// Starts attestation_thread_ and initializes interface.
bool PrepareInterface();
// Internal method to obtain enrollment preparations.
bool ObtainTpmAttestationEnrollmentPreparations(
const attestation::GetEnrollmentPreparationsRequest& request,
attestation::GetEnrollmentPreparationsReply* reply,
GError** error);
// Internal method to obtain the TPM status.
bool ObtainTpmStatus(attestation::GetStatusReply* reply, GError** error);
// Post a method on the attestation_thread_.
template <typename MethodType>
bool Post(const MethodType& method);
// Post a method on the attestation_thread and wait for its completion.
template <typename MethodType>
bool PostAndWait(const MethodType& method);
// Send request to attestationd and wait for reply.
// Request is sent from attestation_thread_.
template <typename ReplyProtoType, typename MethodType>
bool SendRequestAndWait(const MethodType& method,
ReplyProtoType* reply_proto);
// A helper function which maps an integer to a valid ACAType.
static gboolean ConvertIntegerToACAType(gint type,
attestation::ACAType* aca_type,
GError** error);
// A helper function which maps an integer to a valid VAType.
static gboolean ConvertIntegerToVAType(gint type,
attestation::VAType* va_type,
GError** error);
// A helper function which maps an integer to a valid KeyType.
static gboolean ConvertIntegerToKeyType(gint type,
attestation::KeyType* va_type,
GError** error);
// Helper methods that fill GError where an error
// is returned directly from the original handler.
static void ReportErrorFromStatus(GError** error,
attestation::AttestationStatus status);
static void ReportSendFailure(GError** error);
static void ReportUnsupportedACAType(GError** error, int type);
static void ReportUnsupportedVAType(GError** error, int type);
static void ReportUnsupportedKeyType(GError** error, int type);
// Callback called after receiving the ownership taken signal from tpm_manager
void OwnershipTakenSignalCallback();
std::unique_ptr<attestation::AttestationInterface>
default_attestation_interface_;
attestation::AttestationInterface* attestation_interface_;
// Callbacks processing different replies.
// Called from attestation_thread_.
// Process replies that contain only status.
// Sends event with proper async_id.
template <typename ReplyProtoType>
void ProcessStatusReply(int async_id, const ReplyProtoType& reply);
// Process replies that contain status and some binary data.
// The binary data is retrieved from the reply using func().
// Sends event with proper async_id.
template <typename ReplyProtoType>
void ProcessDataReply(const std::string& (ReplyProtoType::*func)() const,
int async_id,
const ReplyProtoType& reply);
// Process GetEndorsementInfoReply.
void ProcessGetEndorsementInfoReply(
DBusGMethodInvocation* context,
const attestation::GetEndorsementInfoReply& reply);
// Tasks executed by attestation_thread_ to process
// async requests.
void DoGetEndorsementInfo(const brillo::SecureBlob& request_array,
DBusGMethodInvocation* context);
void DoInitializeCastKey(const brillo::SecureBlob& request_array,
DBusGMethodInvocation* context);
// Does PCR0 contain the value that indicates the verified mode.
bool IsVerifiedModeMeasured();
void ConnectOwnershipTakenSignal() override;
base::WeakPtr<ServiceDistributed> GetWeakPtr();
// Message loop thread servicing dbus communications with attestationd.
class AttestationThread : public base::Thread {
public:
explicit AttestationThread(ServiceDistributed* service)
: base::Thread{"attestation_thread"}, service_{service} {}
void CleanUp() override {
service_->attestation_interface_ = nullptr;
service_->default_attestation_interface_.reset();
}
ServiceDistributed* service_;
};
AttestationThread attestation_thread_{this};
// Declared last, so that weak pointers are destroyed first.
base::WeakPtrFactory<ServiceDistributed> weak_factory_;
// dbus proxy that handles the ownership taken signal registration.
std::unique_ptr<brillo::dbus::Proxy> tpm_manager_proxy_;
};
} // namespace cryptohome
#endif // CRYPTOHOME_SERVICE_DISTRIBUTED_H_