// Copyright 2018 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 <sysexits.h>

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>

#include <base/command_line.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>

#include "u2fd/g2f_tools/g2f_client.h"

int main(int argc, char* argv[]) {
  DEFINE_bool(syslog, false, "also log to syslog");
  DEFINE_string(dev, "", "path to G2F device");
  DEFINE_bool(ping, false, "{action} ping device");
  DEFINE_bool(raw, false, "{action} send raw HID command");
  DEFINE_bool(msg, false, "{action} send U2F message");
  DEFINE_bool(wink, false, "{action} wink");
  DEFINE_bool(reg, false, "{action} send U2F_REGISTER message");
  DEFINE_bool(auth, false, "{action} send U2F_AUTHENTICATE message");
  DEFINE_bool(lock, false, "lock channel before action");
  DEFINE_int32(ping_size, 10, "size of ping data");
  DEFINE_int32(lock_timeout, 10, "lock_timeout in seconds [0..10]");
  DEFINE_string(payload, "", "request payload bytes (hex) for --raw or --msg");
  DEFINE_int32(cc, -1, "command code to send for --raw");
  DEFINE_int32(p1, -1, "P1 value to send for --reg or --auth, -1 for default");
  DEFINE_string(challenge, "", "challenge parameter for --reg or --auth");
  DEFINE_string(application, "", "application parameter for --reg or --auth");
  DEFINE_string(key_handle, "", "key handle parameter for --auth");
  DEFINE_bool(g2f, false, "use fixed G2F attestation key for --reg");
  DEFINE_int32(v, 0, "verbosity level (up to 3)");

  brillo::FlagHelper::Init(argc, argv, "g2ftool - G2F testing tool");

  int log_flags = brillo::kLogToStderrIfTty;
  if (FLAGS_syslog) {
    log_flags |= brillo::kLogToSyslog;
  }
  brillo::InitLog(log_flags);

  if (FLAGS_dev.empty()) {
    LOG(ERROR) << "Must provide a non-empty device";
    return EX_USAGE;
  }

  g2f_client::HidDevice hid_device(FLAGS_dev);
  g2f_client::U2FHid u2f_hid(&hid_device);
  g2f_client::U2F u2f(&u2f_hid);

  const std::vector<bool> actions = {FLAGS_ping, FLAGS_wink, FLAGS_raw,
                                     FLAGS_msg,  FLAGS_reg,  FLAGS_auth};
  if (std::count(actions.cbegin(), actions.cend(), true) != 1) {
    LOG(ERROR) << "Must specify exactly one action";
    return EX_USAGE;
  }

  if (FLAGS_lock) {
    if (FLAGS_lock_timeout < 0 || FLAGS_lock_timeout > 10) {
      LOG(ERROR) << "Lock timeout must be in [0..10]";
      return EX_USAGE;
    }
    if (!u2f_hid.Lock(static_cast<uint8_t>(FLAGS_lock_timeout))) {
      return EX_SOFTWARE;
    }
    std::cout << "Locked for " << FLAGS_lock_timeout << " seconds."
              << std::endl;
  }

  if (FLAGS_ping) {
    if (!u2f_hid.Ping(FLAGS_ping_size)) {
      return EX_SOFTWARE;
    }
    std::cout << "Ping success." << std::endl;
  } else if (FLAGS_wink) {
    if (!u2f_hid.Wink()) {
      return EX_SOFTWARE;
    }
    std::cout << "Wink success." << std::endl;
  } else if (FLAGS_raw) {
    if (!u2f_hid.Init(false /* force_realloc */)) {
      return EX_SOFTWARE;
    }
    g2f_client::U2FHid::Command request;
    if (!FLAGS_payload.empty() &&
        !base::HexStringToBytes(FLAGS_payload, &request.payload)) {
      LOG(ERROR) << "Failed to convert --payload to bytes";
      return EX_USAGE;
    }
    if (FLAGS_cc < 0 || FLAGS_cc > 0xFF) {
      LOG(ERROR) << "Must provide --cc in [0..255]";
      return EX_USAGE;
    }
    request.cmd = static_cast<uint8_t>(FLAGS_cc);
    g2f_client::U2FHid::Command response;
    if (!u2f_hid.RawCommand(request, &response)) {
      return EX_SOFTWARE;
    }
    std::cout << response.FullDump() << std::endl;
  } else if (FLAGS_msg) {
    brillo::Blob request;
    if (!FLAGS_payload.empty() &&
        !base::HexStringToBytes(FLAGS_payload, &request)) {
      LOG(ERROR) << "Failed to convert --payload to bytes";
      return EX_USAGE;
    }
    brillo::Blob response;
    if (!u2f_hid.Msg(request, &response)) {
      return EX_SOFTWARE;
    }
    std::cout << base::HexEncode(response.data(), response.size()) << std::endl;
  } else if (FLAGS_reg) {
    if (FLAGS_p1 < -1 || FLAGS_p1 > 255) {
      LOG(ERROR) << "P1 value should be 0-255, or -1 for default" << std::endl;
      return EX_USAGE;
    }
    base::Optional<uint8_t> p1;
    if (FLAGS_p1 > -1) {
      p1 = FLAGS_p1;
    }
    brillo::Blob challenge;
    if (!FLAGS_challenge.empty() &&
        !base::HexStringToBytes(FLAGS_challenge, &challenge)) {
      LOG(ERROR) << "Failed to convert --reg_challenge to bytes" << std::endl;
      return EX_USAGE;
    }
    brillo::Blob application;
    if (!FLAGS_application.empty() &&
        !base::HexStringToBytes(FLAGS_application, &application)) {
      std::cout << "Failed to convert --reg_application to bytes" << std::endl;
      return EX_USAGE;
    }
    brillo::Blob public_key;
    brillo::Blob key_handle;
    brillo::Blob certificate_and_signature;
    if (!u2f.Register(p1, challenge, application, FLAGS_g2f, &public_key,
                      &key_handle, &certificate_and_signature)) {
      return EX_SOFTWARE;
    }
    std::cout << "public_key="
              << base::HexEncode(public_key.data(), public_key.size())
              << std::endl
              << "key_handle="
              << base::HexEncode(key_handle.data(), key_handle.size())
              << std::endl
              << "certificate_and_signature="
              << base::HexEncode(certificate_and_signature.data(),
                                 certificate_and_signature.size())
              << std::endl;
  } else if (FLAGS_auth) {
    if (FLAGS_p1 < -1 || FLAGS_p1 > 255) {
      LOG(ERROR) << "P1 value should be 0-255, or -1 for default" << std::endl;
      return EX_USAGE;
    }
    base::Optional<uint8_t> p1;
    if (FLAGS_p1 > -1) {
      p1 = FLAGS_p1;
    }
    brillo::Blob challenge;
    if (!FLAGS_challenge.empty() &&
        !base::HexStringToBytes(FLAGS_challenge, &challenge)) {
      std::cout << "Failed to convert --challenge to bytes" << std::endl;
      return EX_USAGE;
    }
    brillo::Blob application;
    if (!FLAGS_application.empty() &&
        !base::HexStringToBytes(FLAGS_application, &application)) {
      std::cout << "Failed to convert --application to bytes" << std::endl;
      return EX_USAGE;
    }
    brillo::Blob key_handle;
    if (!FLAGS_key_handle.empty() &&
        !base::HexStringToBytes(FLAGS_key_handle, &key_handle)) {
      std::cout << "Failed to convert --key_handle to bytes" << std::endl;
      return EX_USAGE;
    }
    bool presence_verified;
    brillo::Blob counter;
    brillo::Blob signature;
    if (!u2f.Authenticate(p1, challenge, application, key_handle,
                          &presence_verified, &counter, &signature)) {
      return EX_SOFTWARE;
    }
    std::cout << "presence_verified=" << presence_verified << std::endl
              << "counter=" << base::HexEncode(counter.data(), counter.size())
              << std::endl
              << "signature="
              << base::HexEncode(signature.data(), signature.size())
              << std::endl;
  }

  return EX_OK;
}
