// Copyright 2015 The Chromium 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 "chromeos/components/multidevice/secure_message_delegate_impl.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/easy_unlock_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace multidevice {

namespace {

// Converts encryption type to a string representation used by EasyUnlock dbus
// client.
std::string EncSchemeToString(securemessage::EncScheme scheme) {
  switch (scheme) {
    case securemessage::AES_256_CBC:
      return easy_unlock::kEncryptionTypeAES256CBC;
    case securemessage::NONE:
      return easy_unlock::kEncryptionTypeNone;
  }

  NOTREACHED();
  return std::string();
}

// Converts signature type to a string representation used by EasyUnlock dbus
// client.
std::string SigSchemeToString(securemessage::SigScheme scheme) {
  switch (scheme) {
    case securemessage::ECDSA_P256_SHA256:
      return easy_unlock::kSignatureTypeECDSAP256SHA256;
    case securemessage::HMAC_SHA256:
      return easy_unlock::kSignatureTypeHMACSHA256;
    case securemessage::RSA2048_SHA256:
      // RSA2048_SHA256 is not supported by the daemon.
      NOTREACHED();
      return std::string();
  }

  NOTREACHED();
  return std::string();
}

// Parses the serialized HeaderAndBody string returned by the DBus client, and
// calls the corresponding SecureMessageDelegate unwrap callback.
void HandleUnwrapResult(
    const SecureMessageDelegate::UnwrapSecureMessageCallback& callback,
    const std::string& unwrap_result) {
  securemessage::HeaderAndBody header_and_body;
  if (!header_and_body.ParseFromString(unwrap_result)) {
    callback.Run(false, std::string(), securemessage::Header());
  } else {
    callback.Run(true, header_and_body.body(), header_and_body.header());
  }
}

// The SecureMessageDelegate expects the keys in the reverse order returned by
// the DBus client.
void HandleKeyPairResult(
    const SecureMessageDelegate::GenerateKeyPairCallback& callback,
    const std::string& private_key,
    const std::string& public_key) {
  callback.Run(public_key, private_key);
}

}  // namespace

// static
SecureMessageDelegateImpl::Factory*
    SecureMessageDelegateImpl::Factory::test_factory_instance_ = nullptr;

// static
std::unique_ptr<SecureMessageDelegate>
SecureMessageDelegateImpl::Factory::NewInstance() {
  if (test_factory_instance_)
    return test_factory_instance_->BuildInstance();

  static base::NoDestructor<SecureMessageDelegateImpl::Factory> factory;
  return factory->BuildInstance();
}

// static
void SecureMessageDelegateImpl::Factory::SetInstanceForTesting(
    Factory* test_factory) {
  test_factory_instance_ = test_factory;
}

SecureMessageDelegateImpl::Factory::~Factory() = default;

std::unique_ptr<SecureMessageDelegate>
SecureMessageDelegateImpl::Factory::BuildInstance() {
  return base::WrapUnique(new SecureMessageDelegateImpl());
}

SecureMessageDelegateImpl::SecureMessageDelegateImpl()
    : dbus_client_(chromeos::DBusThreadManager::Get()->GetEasyUnlockClient()) {}

SecureMessageDelegateImpl::~SecureMessageDelegateImpl() {}

void SecureMessageDelegateImpl::GenerateKeyPair(
    const GenerateKeyPairCallback& callback) {
  dbus_client_->GenerateEcP256KeyPair(
      base::BindOnce(HandleKeyPairResult, callback));
}

void SecureMessageDelegateImpl::DeriveKey(const std::string& private_key,
                                          const std::string& public_key,
                                          const DeriveKeyCallback& callback) {
  dbus_client_->PerformECDHKeyAgreement(private_key, public_key, callback);
}

void SecureMessageDelegateImpl::CreateSecureMessage(
    const std::string& payload,
    const std::string& key,
    const CreateOptions& create_options,
    const CreateSecureMessageCallback& callback) {
  if (create_options.signature_scheme == securemessage::RSA2048_SHA256) {
    PA_LOG(ERROR) << "Unable to create message: RSA2048_SHA256 not supported "
                  << "by the ChromeOS daemon.";
    callback.Run(std::string());
    return;
  }

  chromeos::EasyUnlockClient::CreateSecureMessageOptions options;
  options.key.assign(key);

  if (!create_options.associated_data.empty())
    options.associated_data.assign(create_options.associated_data);

  if (!create_options.public_metadata.empty())
    options.public_metadata.assign(create_options.public_metadata);

  if (!create_options.verification_key_id.empty())
    options.verification_key_id.assign(create_options.verification_key_id);

  if (!create_options.decryption_key_id.empty())
    options.decryption_key_id.assign(create_options.decryption_key_id);

  options.encryption_type = EncSchemeToString(create_options.encryption_scheme);
  options.signature_type = SigSchemeToString(create_options.signature_scheme);

  dbus_client_->CreateSecureMessage(payload, options, callback);
}

void SecureMessageDelegateImpl::UnwrapSecureMessage(
    const std::string& serialized_message,
    const std::string& key,
    const UnwrapOptions& unwrap_options,
    const UnwrapSecureMessageCallback& callback) {
  if (unwrap_options.signature_scheme == securemessage::RSA2048_SHA256) {
    PA_LOG(ERROR) << "Unable to unwrap message: RSA2048_SHA256 not supported "
                  << "by the ChromeOS daemon.";
    callback.Run(false, std::string(), securemessage::Header());
    return;
  }

  chromeos::EasyUnlockClient::UnwrapSecureMessageOptions options;
  options.key.assign(key);

  if (!unwrap_options.associated_data.empty())
    options.associated_data.assign(unwrap_options.associated_data);

  options.encryption_type = EncSchemeToString(unwrap_options.encryption_scheme);
  options.signature_type = SigSchemeToString(unwrap_options.signature_scheme);

  dbus_client_->UnwrapSecureMessage(
      serialized_message, options,
      base::BindOnce(&HandleUnwrapResult, callback));
}

}  // namespace multidevice

}  // namespace chromeos
