// Copyright 2014 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 "easy-unlock/dbus_adaptor.h"

#include <chromeos/dbus/service_constants.h>
#include <dbus/message.h>

#include "easy-unlock/easy_unlock_service.h"

namespace easy_unlock {

namespace {

// Converts encryption type string to ServiceImpl::EncryptionType enum.
bool ConvertEncryptionType(
    const std::string& encryption_type_str,
    easy_unlock_crypto::ServiceImpl::EncryptionType* type) {
  if (encryption_type_str == kEncryptionTypeNone) {
    *type = easy_unlock_crypto::ServiceImpl::ENCRYPTION_TYPE_NONE;
    return true;
  }

  if (encryption_type_str == kEncryptionTypeAES256CBC) {
    *type = easy_unlock_crypto::ServiceImpl::ENCRYPTION_TYPE_AES_256_CBC;
    return true;
  }

  return false;
}

// Converts signature type string to ServiceImpl::SignatureType enum.
bool ConvertSignatureType(
    const std::string& signature_type_str,
    easy_unlock_crypto::ServiceImpl::SignatureType* type) {
  if (signature_type_str == kSignatureTypeECDSAP256SHA256) {
    *type = easy_unlock_crypto::ServiceImpl::SIGNATURE_TYPE_ECDSA_P256_SHA256;
    return true;
  }

  if (signature_type_str == kSignatureTypeHMACSHA256) {
    *type = easy_unlock_crypto::ServiceImpl::SIGNATURE_TYPE_HMAC_SHA256;
    return true;
  }

  return false;
}

// Reads public key algorithm string passed to DBus method call and converts
// it to ServiceImpl::KeyAlgorithm enum. Returns whether the parameter
// was successfully read and converted.
bool ConvertKeyAlgorithm(
    const std::string& algorithm_str,
    easy_unlock_crypto::ServiceImpl::KeyAlgorithm* algorithm) {
  if (algorithm_str == kKeyAlgorithmRSA) {
    *algorithm = easy_unlock_crypto::ServiceImpl::KEY_ALGORITHM_RSA;
    return true;
  }

  if (algorithm_str == kKeyAlgorithmECDSA) {
    *algorithm = easy_unlock_crypto::ServiceImpl::KEY_ALGORITHM_ECDSA;
    return true;
  }

  return false;
}

}  // namespace

DBusAdaptor::DBusAdaptor(const scoped_refptr<dbus::Bus>& bus,
                         easy_unlock::Service* service)
    : service_impl_(service),
      dbus_object_(
          nullptr, bus, dbus::ObjectPath(easy_unlock::kEasyUnlockServicePath)) {
  CHECK(service_impl_) << "Service implementation not passed to DBus adaptor";
}

DBusAdaptor::~DBusAdaptor() {}

void DBusAdaptor::Register(const CompletionAction& callback) {
  brillo::dbus_utils::DBusInterface* interface =
      dbus_object_.AddOrGetInterface(kEasyUnlockServiceInterface);

  interface->AddSimpleMethodHandler(kGenerateEcP256KeyPairMethod,
                                    base::Unretained(this),
                                    &DBusAdaptor::GenerateEcP256KeyPair);
  interface->AddSimpleMethodHandler(kWrapPublicKeyMethod,
                                    base::Unretained(this),
                                    &DBusAdaptor::WrapPublicKey);
  interface->AddSimpleMethodHandler(kPerformECDHKeyAgreementMethod,
                                    base::Unretained(this),
                                    &DBusAdaptor::PerformECDHKeyAgreement);
  interface->AddSimpleMethodHandler(kCreateSecureMessageMethod,
                                    base::Unretained(this),
                                    &DBusAdaptor::CreateSecureMessage);
  interface->AddSimpleMethodHandler(kUnwrapSecureMessageMethod,
                                    base::Unretained(this),
                                    &DBusAdaptor::UnwrapSecureMessage);
  dbus_object_.RegisterAsync(callback);
}

void DBusAdaptor::GenerateEcP256KeyPair(std::vector<uint8_t>* private_key,
                                        std::vector<uint8_t>* public_key) {
  service_impl_->GenerateEcP256KeyPair(private_key, public_key);
}

std::vector<uint8_t> DBusAdaptor::WrapPublicKey(
    const std::string& algorithm_str, const std::vector<uint8_t>& public_key) {
  easy_unlock_crypto::ServiceImpl::KeyAlgorithm algorithm;
  if (!ConvertKeyAlgorithm(algorithm_str, &algorithm)) {
    LOG(ERROR) << "Invalid key algorithm";
    // TODO(tbarzic): Return error instead.
    return std::vector<uint8_t>();
  }

  return service_impl_->WrapPublicKey(algorithm, public_key);
}

std::vector<uint8_t> DBusAdaptor::PerformECDHKeyAgreement(
    const std::vector<uint8_t>& private_key,
    const std::vector<uint8_t>& public_key) {
  return service_impl_->PerformECDHKeyAgreement(private_key, public_key);
}

std::vector<uint8_t> DBusAdaptor::CreateSecureMessage(
    const std::vector<uint8_t>& payload,
    const std::vector<uint8_t>& key,
    const std::vector<uint8_t>& associated_data,
    const std::vector<uint8_t>& public_metadata,
    const std::vector<uint8_t>& verification_key_id,
    const std::vector<uint8_t>& decryption_key_id,
    const std::string& encryption_type_str,
    const std::string& signature_type_str) {
  easy_unlock_crypto::ServiceImpl::EncryptionType encryption_type;
  easy_unlock_crypto::ServiceImpl::SignatureType signature_type;

  if (!ConvertEncryptionType(encryption_type_str, &encryption_type) ||
      !ConvertSignatureType(signature_type_str, &signature_type)) {
    LOG(ERROR) << "Invalid encryption or signature type";
    // TODO(tbarzic): Return error here.
    return std::vector<uint8_t>();
  }

  return service_impl_->CreateSecureMessage(
      payload, key, associated_data, public_metadata, verification_key_id,
      decryption_key_id, encryption_type, signature_type);
}

std::vector<uint8_t> DBusAdaptor::UnwrapSecureMessage(
    const std::vector<uint8_t>& message,
    const std::vector<uint8_t>& key,
    const std::vector<uint8_t>& associated_data,
    const std::string& encryption_type_str,
    const std::string& signature_type_str) {
  easy_unlock_crypto::ServiceImpl::EncryptionType encryption_type;
  easy_unlock_crypto::ServiceImpl::SignatureType signature_type;

  if (!ConvertEncryptionType(encryption_type_str, &encryption_type) ||
      !ConvertSignatureType(signature_type_str, &signature_type)) {
    LOG(ERROR) << "Invalid encryption or signature type";
    // TODO(tbarzic): Return error here.
    return std::vector<uint8_t>();
  }

  return service_impl_->UnwrapSecureMessage(message, key, associated_data,
                                            encryption_type, signature_type);
}

}  // namespace easy_unlock
