// 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_
