// 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 "components/cryptauth/fake_secure_message_delegate.h"

#include <stddef.h>

#include <algorithm>

#include "base/callback.h"
#include "base/md5.h"
#include "base/strings/string_util.h"

namespace cryptauth {

namespace {

const char kKeyPrefix[] = "fake_key_";
const char kPrivateKeyPrefix[] = "private_";

// Encrypts the |plaintext| with the |key| using the |encryption_scheme| and
// returns the ciphertext.
std::string Encrypt(const std::string& plaintext,
                    const std::string& key,
                    const securemessage::EncScheme& encryption_scheme) {
  if (encryption_scheme == securemessage::NONE)
    return plaintext;

  // Encrypt with a Vigenere cipher.
  std::string ciphertext;
  ciphertext.resize(plaintext.size());
  for (size_t i = 0; i < plaintext.size(); ++i) {
    unsigned char plaintext_char = plaintext[i];
    unsigned char key_char = key[i % key.size()];
    ciphertext[i] = plaintext_char + key_char;
  }
  return ciphertext;
}

// Decrypts the |ciphertext| with the |key| using the |encryption_scheme| and
// returns the plaintext.
std::string Decrypt(const std::string& ciphertext,
                    const std::string& key,
                    const securemessage::EncScheme& encryption_scheme) {
  if (encryption_scheme == securemessage::NONE)
    return ciphertext;

  // Decrypt with a Vigenere cipher.
  std::string plaintext;
  plaintext.resize(ciphertext.size());
  for (size_t i = 0; i < ciphertext.size(); ++i) {
    unsigned char ciphertext_char = ciphertext[i];
    unsigned char key_char = key[i % key.size()];
    plaintext[i] = ciphertext_char - key_char;
  }
  return plaintext;
}

// Signs the |payload| and |associated_data| with the |key| using the
// |signature_scheme| and returns the signature.
std::string Sign(const std::string& payload,
                 const std::string& associated_data,
                 const std::string& key) {
  return base::MD5String(payload + "|" + associated_data + "|" + key);
}

// Verifies that the |signature| for the the |payload| and |associated_data| is
// valid for the given the |key| and |signature_scheme|.
bool Verify(const std::string& signature,
            const std::string& payload,
            const std::string& associated_data,
            const std::string& key,
            const securemessage::SigScheme& signature_scheme) {
  std::string signing_key;

  if (signature_scheme == securemessage::HMAC_SHA256) {
    signing_key = key;
  } else {
    std::string prefix = kPrivateKeyPrefix;
    bool is_private_key =
        base::StartsWith(key, prefix, base::CompareCase::SENSITIVE);
    signing_key = is_private_key ? key.substr(prefix.size()) : prefix + key;
  }

  std::string expected_signature = Sign(payload, associated_data, signing_key);
  return signature == expected_signature;
}

}  // namespace

FakeSecureMessageDelegate::FakeSecureMessageDelegate()
    : next_public_key_(std::string(kKeyPrefix) + "0") {
}

FakeSecureMessageDelegate::~FakeSecureMessageDelegate() {
}

void FakeSecureMessageDelegate::GenerateKeyPair(
    const GenerateKeyPairCallback& callback) {
  std::string public_key = next_public_key_;

  // The private key is simply the public key prepended with "private_".
  std::string private_key(kPrivateKeyPrefix + public_key);

  next_public_key_ = std::string(kKeyPrefix) + base::MD5String(public_key);

  callback.Run(public_key, private_key);
}

void FakeSecureMessageDelegate::DeriveKey(const std::string& private_key,
                                          const std::string& public_key,
                                          const DeriveKeyCallback& callback) {
  // To ensure that the same symmetric key is derived for DeriveKey(private1,
  // public2) and DeriveKey(private2, public1), we remove the prefix from the
  // private key so it is equal to its corresponding public key.
  std::string prefix(kPrivateKeyPrefix);
  std::string normalized_private_key =
      base::StartsWith(private_key, prefix, base::CompareCase::SENSITIVE)
          ? private_key.substr(prefix.size())
          : private_key;

  std::vector<std::string> keys;
  keys.push_back(normalized_private_key);
  keys.push_back(public_key);
  std::sort(keys.begin(), keys.end());
  callback.Run(base::MD5String(keys[0] + "|" + keys[1]));
}

void FakeSecureMessageDelegate::CreateSecureMessage(
    const std::string& payload,
    const std::string& key,
    const CreateOptions& create_options,
    const CreateSecureMessageCallback& callback) {
  securemessage::Header header;
  header.set_signature_scheme(create_options.signature_scheme);
  header.set_encryption_scheme(create_options.encryption_scheme);
  if (!create_options.public_metadata.empty())
    header.set_public_metadata(create_options.public_metadata);
  if (!create_options.verification_key_id.empty())
    header.set_verification_key_id(create_options.verification_key_id);
  if (!create_options.decryption_key_id.empty())
    header.set_decryption_key_id(create_options.decryption_key_id);

  securemessage::HeaderAndBody header_and_body;
  header_and_body.mutable_header()->CopyFrom(header);
  header_and_body.set_body(
      Encrypt(payload, key, create_options.encryption_scheme));
  std::string serialized_header_and_body;
  header_and_body.SerializeToString(&serialized_header_and_body);

  securemessage::SecureMessage secure_message;
  secure_message.set_header_and_body(serialized_header_and_body);
  secure_message.set_signature(
      Sign(payload, create_options.associated_data, key));

  std::string serialized_secure_message;
  secure_message.SerializeToString(&serialized_secure_message);
  callback.Run(serialized_secure_message);
}

void FakeSecureMessageDelegate::UnwrapSecureMessage(
    const std::string& serialized_message,
    const std::string& key,
    const UnwrapOptions& unwrap_options,
    const UnwrapSecureMessageCallback& callback) {
  securemessage::SecureMessage secure_message;
  if (!secure_message.ParseFromString(serialized_message)) {
    LOG(ERROR) << "Failed to parse SecureMessage.";
    callback.Run(false, std::string(), securemessage::Header());
    return;
  }

  securemessage::HeaderAndBody header_and_body;
  if (!header_and_body.ParseFromString(secure_message.header_and_body())) {
    LOG(ERROR) << "Failed to parse secure message HeaderAndBody.";
    callback.Run(false, std::string(), securemessage::Header());
    return;
  }

  const securemessage::Header& header = header_and_body.header();
  std::string payload =
      Decrypt(header_and_body.body(), key, unwrap_options.encryption_scheme);

  bool verified = Verify(secure_message.signature(), payload,
                         unwrap_options.associated_data, key,
                         unwrap_options.signature_scheme);
  if (verified) {
    callback.Run(true, payload, header);
  } else {
    callback.Run(false, std::string(), securemessage::Header());
  }
}

std::string FakeSecureMessageDelegate::GetPrivateKeyForPublicKey(
    const std::string& public_key) {
  return kPrivateKeyPrefix + public_key;
}

}  // namespace cryptauth
