// Copyright 2017 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 "device/u2f/u2f_sign.h"

#include <utility>

#include "services/service_manager/public/cpp/connector.h"

namespace device {

U2fSign::U2fSign(std::string relying_party_id,
                 service_manager::Connector* connector,
                 const base::flat_set<U2fTransportProtocol>& protocols,
                 const std::vector<std::vector<uint8_t>>& registered_keys,
                 const std::vector<uint8_t>& challenge_hash,
                 const std::vector<uint8_t>& app_param,
                 SignResponseCallback completion_callback)
    : U2fRequest(std::move(relying_party_id), connector, protocols),
      registered_keys_(registered_keys),
      challenge_hash_(challenge_hash),
      app_param_(app_param),
      completion_callback_(std::move(completion_callback)),
      weak_factory_(this) {}

U2fSign::~U2fSign() = default;

// static
std::unique_ptr<U2fRequest> U2fSign::TrySign(
    std::string relying_party_id,
    service_manager::Connector* connector,
    const base::flat_set<U2fTransportProtocol>& protocols,
    const std::vector<std::vector<uint8_t>>& registered_keys,
    const std::vector<uint8_t>& challenge_hash,
    const std::vector<uint8_t>& app_param,
    SignResponseCallback completion_callback) {
  std::unique_ptr<U2fRequest> request = std::make_unique<U2fSign>(
      std::move(relying_party_id), connector, protocols, registered_keys,
      challenge_hash, app_param, std::move(completion_callback));
  request->Start();

  return request;
}

void U2fSign::TryDevice() {
  DCHECK(current_device_);

  if (registered_keys_.size() == 0) {
    // Send registration (Fake enroll) if no keys were provided
    current_device_->Register(
        U2fRequest::GetBogusAppParam(), U2fRequest::GetBogusChallenge(),
        false /* no individual attestation */,
        base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
                   registered_keys_.cend()));
    return;
  }
  // Try signing current device with the first registered key
  auto it = registered_keys_.cbegin();
  current_device_->Sign(
      app_param_, challenge_hash_, *it,
      base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it));
}

void U2fSign::OnTryDevice(std::vector<std::vector<uint8_t>>::const_iterator it,
                          U2fReturnCode return_code,
                          const std::vector<uint8_t>& response_data) {
  switch (return_code) {
    case U2fReturnCode::SUCCESS: {
      state_ = State::COMPLETE;
      if (it == registered_keys_.cend()) {
        // This was a response to a fake enrollment. Return an empty key handle.
        std::move(completion_callback_)
            .Run(U2fReturnCode::CONDITIONS_NOT_SATISFIED, base::nullopt);
      } else {
        auto sign_response = SignResponseData::CreateFromU2fSignResponse(
            relying_party_id_, std::move(response_data), *it);
        if (!sign_response) {
          std::move(completion_callback_)
              .Run(U2fReturnCode::FAILURE, base::nullopt);
        } else {
          std::move(completion_callback_)
              .Run(U2fReturnCode::SUCCESS, std::move(sign_response));
        }
      }
      break;
    }
    case U2fReturnCode::CONDITIONS_NOT_SATISFIED: {
      // Key handle is accepted by this device, but waiting on user touch. Move
      // on and try this device again later.
      state_ = State::IDLE;
      Transition();
      break;
    }
    case U2fReturnCode::INVALID_PARAMS: {
      if (++it != registered_keys_.end()) {
        // Key is not for this device. Try signing with the next key.
        current_device_->Sign(
            app_param_, challenge_hash_, *it,
            base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it));
      } else {
        // No provided key was accepted by this device. Send registration
        // (Fake enroll) request to device.
        current_device_->Register(
            U2fRequest::GetBogusAppParam(), U2fRequest::GetBogusChallenge(),
            false /* no individual attestation */,
            base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
                       registered_keys_.cend()));
      }
      break;
    }
    default:
      // Some sort of failure occured. Abandon this device and move on.
      state_ = State::IDLE;
      current_device_ = nullptr;
      Transition();
      break;
  }
}

}  // namespace device
