// 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/services/secure_channel/device_to_device_responder_operations.h"

#include "base/bind.h"
#include "base/callback.h"
#include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/components/multidevice/secure_message_delegate.h"
#include "chromeos/services/device_sync/proto/cryptauth_api.pb.h"
#include "chromeos/services/device_sync/proto/securemessage.pb.h"

namespace chromeos {

namespace secure_channel {

namespace {

// TODO(tengs): Due to a bug with the ChromeOS secure message daemon, we cannot
// create SecureMessages with empty payloads. To workaround this bug, this value
// is put into the payload if it would otherwise be empty.
// See crbug.com/512894.
const char kPayloadFiller[] = "\xae";

// The version to put in the cryptauth::GcmMetadata field.
const int kGcmMetadataVersion = 1;

// The D2D protocol version.
const int kD2DProtocolVersion = 1;

// Callback for DeviceToDeviceResponderOperations::ValidateHelloMessage(),
// after the [Hello] message is unwrapped.
void OnHelloMessageUnwrapped(
    const DeviceToDeviceResponderOperations::ValidateHelloCallback& callback,
    bool verified,
    const std::string& payload,
    const securemessage::Header& header) {
  securemessage::InitiatorHello initiator_hello;
  if (!verified || !initiator_hello.ParseFromString(header.public_metadata()) ||
      initiator_hello.protocol_version() != kD2DProtocolVersion) {
    callback.Run(false, std::string());
    return;
  }

  callback.Run(true, initiator_hello.public_dh_key().SerializeAsString());
}

// Helper struct containing all the context needed to create the [Responder
// Auth] message.
struct CreateResponderAuthMessageContext {
  std::string hello_message;
  std::string session_public_key;
  std::string session_private_key;
  std::string persistent_private_key;
  std::string persistent_symmetric_key;
  multidevice::SecureMessageDelegate* secure_message_delegate;
  DeviceToDeviceResponderOperations::MessageCallback callback;
  std::string hello_public_key;
  std::string middle_message;
};

// Forward declarations of functions used to create the [Responder Auth]
// message, declared in order in which they are called during the creation flow.
void OnHelloMessageValidatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    bool hello_message_validated,
    const std::string& hello_public_key);
void OnInnerMessageCreatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& inner_message);
void OnMiddleMessageCreatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& middle_message);
void OnSessionSymmetricKeyDerivedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& session_symmetric_key);

// Called after the initiator's [Hello] message is unwrapped.
void OnHelloMessageValidatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    bool hello_message_validated,
    const std::string& hello_public_key) {
  if (!hello_message_validated) {
    PA_LOG(VERBOSE) << "Invalid [Hello] while creating [Responder Auth]";
    context.callback.Run(std::string());
    return;
  }

  context.hello_public_key = hello_public_key;

  // Create the inner most wrapped message of [Responder Auth].
  cryptauth::GcmMetadata gcm_metadata;
  gcm_metadata.set_type(cryptauth::UNLOCK_KEY_SIGNED_CHALLENGE);
  gcm_metadata.set_version(kGcmMetadataVersion);

  multidevice::SecureMessageDelegate::CreateOptions create_options;
  create_options.encryption_scheme = securemessage::NONE;
  create_options.signature_scheme = securemessage::ECDSA_P256_SHA256;
  gcm_metadata.SerializeToString(&create_options.public_metadata);
  create_options.associated_data = context.hello_message;

  context.secure_message_delegate->CreateSecureMessage(
      kPayloadFiller, context.persistent_private_key, create_options,
      base::Bind(&OnInnerMessageCreatedForResponderAuth, context));
}

// Called after the inner-most layer of [Responder Auth] is created.
void OnInnerMessageCreatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& inner_message) {
  if (inner_message.empty()) {
    PA_LOG(VERBOSE) << "Failed to create middle message for [Responder Auth]";
    context.callback.Run(std::string());
    return;
  }

  // Create the middle message.
  multidevice::SecureMessageDelegate::CreateOptions create_options;
  create_options.encryption_scheme = securemessage::AES_256_CBC;
  create_options.signature_scheme = securemessage::HMAC_SHA256;
  create_options.associated_data = context.hello_message;
  context.secure_message_delegate->CreateSecureMessage(
      inner_message, context.persistent_symmetric_key, create_options,
      base::Bind(&OnMiddleMessageCreatedForResponderAuth, context));
}

// Called after the middle layer of [Responder Auth] is created.
void OnMiddleMessageCreatedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& middle_message) {
  if (middle_message.empty()) {
    PA_LOG(ERROR) << "Error inner message while creating [Responder Auth]";
    context.callback.Run(std::string());
    return;
  }

  // Before we can create the outer-most message layer, we need to perform a key
  // agreement for the session symmetric key.
  context.middle_message = middle_message;
  context.secure_message_delegate->DeriveKey(
      context.session_private_key, context.hello_public_key,
      base::Bind(&OnSessionSymmetricKeyDerivedForResponderAuth, context));
}

// Called after the session symmetric key is derived, so we can create the outer
// most layer of [Responder Auth].
void OnSessionSymmetricKeyDerivedForResponderAuth(
    CreateResponderAuthMessageContext context,
    const std::string& session_symmetric_key) {
  if (session_symmetric_key.empty()) {
    PA_LOG(ERROR) << "Error inner message while creating [Responder Auth]";
    context.callback.Run(std::string());
    return;
  }

  cryptauth::GcmMetadata gcm_metadata;
  gcm_metadata.set_type(cryptauth::DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD);
  gcm_metadata.set_version(kGcmMetadataVersion);

  // Store the responder's session public key in plaintext in the header.
  securemessage::ResponderHello responder_hello;
  if (!responder_hello.mutable_public_dh_key()->ParseFromString(
          context.session_public_key)) {
    PA_LOG(ERROR) << "Error parsing public key while creating [Responder Auth]";
    PA_LOG(ERROR) << context.session_public_key;
    context.callback.Run(std::string());
    return;
  }
  responder_hello.set_protocol_version(kD2DProtocolVersion);

  // Create the outer most message, wrapping the other messages created
  // previously.
  securemessage::DeviceToDeviceMessage device_to_device_message;
  device_to_device_message.set_message(context.middle_message);
  device_to_device_message.set_sequence_number(1);

  multidevice::SecureMessageDelegate::CreateOptions create_options;
  create_options.encryption_scheme = securemessage::AES_256_CBC;
  create_options.signature_scheme = securemessage::HMAC_SHA256;
  create_options.public_metadata = gcm_metadata.SerializeAsString();
  responder_hello.SerializeToString(&create_options.decryption_key_id);

  context.secure_message_delegate->CreateSecureMessage(
      device_to_device_message.SerializeAsString(),
      SessionKeys(session_symmetric_key).responder_encode_key(), create_options,
      context.callback);
}

// Helper struct containing all the context needed to validate the [Initiator
// Auth] message.
struct ValidateInitiatorAuthMessageContext {
  std::string persistent_symmetric_key;
  std::string responder_auth_message;
  multidevice::SecureMessageDelegate* secure_message_delegate;
  DeviceToDeviceResponderOperations::ValidationCallback callback;
};

// Called after the inner-most layer of [Initiator Auth] is unwrapped.
void OnInnerMessageUnwrappedForInitiatorAuth(
    const ValidateInitiatorAuthMessageContext& context,
    bool verified,
    const std::string& payload,
    const securemessage::Header& header) {
  if (!verified)
    PA_LOG(VERBOSE) << "Failed to inner [Initiator Auth] message.";
  context.callback.Run(verified);
}

// Called after the outer-most layer of [Initiator Auth] is unwrapped.
void OnOuterMessageUnwrappedForInitiatorAuth(
    const ValidateInitiatorAuthMessageContext& context,
    bool verified,
    const std::string& payload,
    const securemessage::Header& header) {
  if (!verified) {
    PA_LOG(VERBOSE) << "Failed to verify outer [Initiator Auth] message";
    context.callback.Run(false);
    return;
  }

  // Parse the decrypted payload.
  securemessage::DeviceToDeviceMessage device_to_device_message;
  if (!device_to_device_message.ParseFromString(payload) ||
      device_to_device_message.sequence_number() != 1) {
    PA_LOG(VERBOSE) << "Failed to validate DeviceToDeviceMessage payload.";
    context.callback.Run(false);
    return;
  }

  // Unwrap the inner message of [Initiator Auth].
  multidevice::SecureMessageDelegate::UnwrapOptions unwrap_options;
  unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
  unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
  unwrap_options.associated_data = context.responder_auth_message;
  context.secure_message_delegate->UnwrapSecureMessage(
      device_to_device_message.message(), context.persistent_symmetric_key,
      unwrap_options,
      base::Bind(&OnInnerMessageUnwrappedForInitiatorAuth, context));
}

}  // namespace

// static
void DeviceToDeviceResponderOperations::ValidateHelloMessage(
    const std::string& hello_message,
    const std::string& persistent_symmetric_key,
    multidevice::SecureMessageDelegate* secure_message_delegate,
    const ValidateHelloCallback& callback) {
  // The [Hello] message has the structure:
  // {
  //   header: <session_public_key>,
  //           Sig(<session_public_key>, persistent_symmetric_key)
  //   payload: ""
  // }
  multidevice::SecureMessageDelegate::UnwrapOptions unwrap_options;
  unwrap_options.encryption_scheme = securemessage::NONE;
  unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
  secure_message_delegate->UnwrapSecureMessage(
      hello_message, persistent_symmetric_key, unwrap_options,
      base::Bind(&OnHelloMessageUnwrapped, callback));
}

// static
void DeviceToDeviceResponderOperations::CreateResponderAuthMessage(
    const std::string& hello_message,
    const std::string& session_public_key,
    const std::string& session_private_key,
    const std::string& persistent_private_key,
    const std::string& persistent_symmetric_key,
    multidevice::SecureMessageDelegate* secure_message_delegate,
    const MessageCallback& callback) {
  // The [Responder Auth] message has the structure:
  // {
  //   header: <responder_public_key>,
  //           Sig(<responder_public_key> + payload1,
  //               session_symmetric_key),
  //   payload1: Enc({
  //     header: Sig(payload2 + <hello_message>, persistent_symmetric_key),
  //     payload2: {
  //       sequence_number: 1,
  //       body: Enc({
  //         header: Sig(payload3 + <hello_message>,
  //                     persistent_responder_public_key),
  //         payload3: ""
  //       }, persistent_symmetric_key)
  //     }
  //   }, session_symmetric_key),
  // }
  CreateResponderAuthMessageContext context = {hello_message,
                                               session_public_key,
                                               session_private_key,
                                               persistent_private_key,
                                               persistent_symmetric_key,
                                               secure_message_delegate,
                                               callback};

  // To create the [Responder Auth] message, we need to first parse the
  // initiator's [Hello] message and extract the initiator's session public key.
  DeviceToDeviceResponderOperations::ValidateHelloMessage(
      hello_message, persistent_symmetric_key, secure_message_delegate,
      base::Bind(&OnHelloMessageValidatedForResponderAuth, context));
}

// static
void DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
    const std::string& initiator_auth_message,
    const SessionKeys& session_keys,
    const std::string& persistent_symmetric_key,
    const std::string& responder_auth_message,
    multidevice::SecureMessageDelegate* secure_message_delegate,
    const ValidationCallback& callback) {
  // The [Initiator Auth] message has the structure:
  // {
  //   header: Sig(payload1, session_symmetric_key)
  //   payload1: Enc({
  //     sequence_number: 2,
  //     body: {
  //       header: Sig(payload2 + responder_auth_message,
  //       persistent_symmetric_key)
  //       payload2: ""
  //     }
  //   }, session_symmetric_key)
  // }
  ValidateInitiatorAuthMessageContext context = {
      persistent_symmetric_key, responder_auth_message, secure_message_delegate,
      callback};

  multidevice::SecureMessageDelegate::UnwrapOptions unwrap_options;
  unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
  unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
  secure_message_delegate->UnwrapSecureMessage(
      initiator_auth_message, session_keys.initiator_encode_key(),
      unwrap_options,
      base::Bind(&OnOuterMessageUnwrappedForInitiatorAuth, context));
}

}  // namespace secure_channel

}  // namespace chromeos
