// Copyright 2016 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 <stdio.h>

#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/sys_byteorder.h>
#include <brillo/syslog_logging.h>
#include <crypto/sha2.h>
#include <openssl/sha.h>

#include "trunks/trunks_dbus_proxy.h"

namespace {

using trunks::TrunksDBusProxy;

// Commands we support
constexpr char kForce[] = "force";
constexpr char kGetLock[] = "get_lock";
constexpr char kPopLogEntry[] = "pop_logentry";
constexpr char kRaw[] = "raw";
constexpr char kSetLock[] = "set_lock";
constexpr char kSysInfo[] = "sysinfo";
constexpr char kUpdate[] = "update";
constexpr char kU2fCert[] = "u2f_cert";
constexpr char kVerbose[] = "verbose";

// Maximum image update block size expected by Cr50.
// Equals to SIGNED_TRANSFER_SIZE in src/platform/ec/chip/g/update_fw.h
static const uint32_t kTransferSize = 1024;

static int verbose;

void PrintUsage() {
  printf("Usage:\n");
  printf("  trunks_send --%s\n", kGetLock);
  printf("  trunks_send --%s\n", kSetLock);
  printf("  trunks_send --%s\n", kSysInfo);
  printf("  trunks_send --%s\n", kPopLogEntry);
  printf("  trunks_send --%s XX [XX ..]\n", kRaw);
  printf("  trunks_send [--%s] --%s <bin file>\n", kForce, kUpdate);
  printf("  trunks_send --%s [--crt=<file>] [--nonce=<txt>] [--appid=<txt>]\n",
         kU2fCert);
  printf("Options:\n");
  printf("   --%s\n", kVerbose);
}

std::string HexEncode(const std::string& bytes) {
  return base::HexEncode(bytes.data(), bytes.size());
}

// All TPM extension commands use this struct for input and output. Any other
// data follows immediately after. All values are big-endian over the wire.
struct TpmCmdHeader {
  uint16_t tag;              // TPM_ST_NO_SESSIONS
  uint32_t size;             // including this header
  uint32_t code;             // Command out, Response back.
  uint16_t subcommand_code;  // Additional command/response codes
} __attribute__((packed));

// TPMv2 Spec mandates that vendor-specific command codes have bit 29 set,
// while bits 15-0 indicate the command. All other bits should be zero. We
// define one of those 16-bit command values for Cr50 purposes, and use the
// subcommand_code in struct TpmCmdHeader to further distinguish the desired
// operation.
#define TPM_CC_VENDOR_BIT 0x20000000

// Vendor-specific command codes
#define TPM_CC_VENDOR_CR50 0x0000

// This needs to be used to be backwards compatible with older Cr50 versions.
#define CR50_EXTENSION_COMMAND 0xbaccd00a
#define CR50_EXTENSION_FW_UPGRADE 4

// Cr50 vendor-specific subcommand codes. 16 bits available.
enum vendor_cmd_cc {
  VENDOR_CC_POST_RESET = 7,
  VENDOR_CC_GET_LOCK = 16,
  VENDOR_CC_SET_LOCK = 17,
  VENDOR_CC_SYSINFO = 18,
  VENDOR_CC_U2F_APDU = 27,
  VENDOR_CC_POP_LOG_ENTRY = 28,
};

// The TPM response code is all zero for success.
// Errors are a little complicated:
//
//   Bits 31:12 must be zero.
//
//   Bit 11     S=0   Error
//   Bit 10     T=1   Vendor defined response code
//   Bit  9     r=0   reserved
//   Bit  8     V=1   Conforms to TPMv2 spec
//   Bit  7     F=0   Conforms to Table 14, Format-Zero Response Codes
//   Bits 6:0   num   128 possible failure reasons
#define VENDOR_RC_ERR 0x00000500
#define VENDOR_RC_MASK 0x0000007f
#define VENDOR_RC_NO_SUCH_COMMAND 0x0000007f

}  // namespace

// Send raw, unformatted bytes
static int HandleRaw(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  std::string commandline;
  for (std::string arg : cl->GetArgs()) {
    commandline.append(arg);
  }
  base::RemoveChars(commandline, " \t\r\n:.", &commandline);

  std::vector<uint8_t> bytes;
  if (!base::HexStringToBytes(commandline, &bytes)) {
    LOG(ERROR) << "Can't convert input to bytes.";
    return 1;
  }

  std::string command(bytes.data(), bytes.data() + bytes.size());
  if (verbose) {
    printf("Out(%zd): ", command.size());
    puts(HexEncode(command).c_str());
  }
  std::string response = proxy->SendCommandAndWait(command);
  if (verbose) {
    printf("In(%zd):  ", response.size());
  }

  // Just print the result
  puts(HexEncode(response).c_str());

  return 0;
}

// Send the TPM command, get the reply, return response code and results.
static uint32_t VendorCommand(TrunksDBusProxy* proxy,
                              uint16_t cc,
                              const std::string& input,
                              std::string* output,
                              bool extendedCommandMode = false) {
  // Pack up the header and the input
  struct TpmCmdHeader header;
  header.tag = base::HostToNet16(trunks::TPM_ST_NO_SESSIONS);
  header.size = base::HostToNet32(sizeof(header) + input.size());
  if (extendedCommandMode)
    header.code = base::HostToNet32(CR50_EXTENSION_COMMAND);
  else
    header.code = base::HostToNet32(TPM_CC_VENDOR_BIT | TPM_CC_VENDOR_CR50);
  header.subcommand_code = base::HostToNet16(cc);

  std::string command(reinterpret_cast<char*>(&header), sizeof(header));
  command += input;

  // Send the command, get the response
  if (verbose) {
    printf("Out(%zd): ", command.size());
    puts(HexEncode(command).c_str());
  }
  std::string response = proxy->SendCommandAndWait(command);
  if (verbose) {
    printf("In(%zd):  ", response.size());
    puts(HexEncode(response).c_str());
  }

  if (response.size() < sizeof(header)) {
    LOG(ERROR) << "TPM response was too short!";
    return -1;
  }

  // Unpack the response header and any output
  memcpy(&header, response.data(), sizeof(header));
  header.size = base::NetToHost32(header.size);
  header.code = base::NetToHost32(header.code);

  // Error of some sort?
  if (header.code) {
    if ((header.code & VENDOR_RC_ERR) == VENDOR_RC_ERR) {
      fprintf(stderr, "TPM error code 0x%08x\n", header.code);
    }
  }

  // Pass back any reply beyond the header
  *output = response.substr(sizeof(header));

  return header.code;
}

//
// A convenience structure which allows to group together various revision
// fields of the header created by the signer.
//
// These fields are compared when deciding if versions of two images are the
// same or when deciding which one of the available images to run.
//
// Originally defined in src/platform/ec/chip/g/upgrade_fw.h
//
struct SignedHeaderVersion {
  uint32_t minor;
  uint32_t major;
  uint32_t epoch;
};

//
// Response to the connection establishment request.
//
// All protocol versions starting with version 2 respond to the very first
// packet with an 8 byte or larger response, where the first 4 bytes are a
// version specific data, and the second 4 bytes - the protocol version
// number.
//
// Originally defined in src/platform/ec/chip/g/upgrade_fw.h
//
struct FirstResponsePdu {
  uint32_t return_value;

  // The below fields are present in versions 2 and up.
  uint32_t protocol_version;

  // The below fields are present in versions 3 and up.
  uint32_t backup_ro_offset;
  uint32_t backup_rw_offset;

  // The below fields are present in versions 4 and up.
  // Versions of the currently active RO and RW sections.
  SignedHeaderVersion shv[2];

  // The below fields are present in versions 5 and up
  // keyids of the currently active RO and RW sections.
  uint32_t keyid[2];
};

struct UpdatePduHeader {
  uint32_t pdu_digest;
  uint32_t pdu_base_offset;
};

//
// Cr50 image header.
//
// Based on SignedHeader defined in src/platform/ec/chip/g/signed_header.h
//
struct EssentialHeader {
  uint32_t magic;
  uint32_t padding0[201];
  uint32_t image_size;
  uint32_t padding1[12];
  uint32_t epoch;
  uint32_t major;
  uint32_t minor;
};

//
// Wraps a block of image into a Vendor Command PDU and sends it to the device.
//
// Wrapping includes creating a header containing the digest of the entire PDU
// and the offset to program the PDU contents int the device's flash.
//
// |data| points to the entire firmware image containing RO and RW sections.
// |data_offset| is the offset into the image and into the flash memory, and
// |block_size| is the number of bytes to be tranferred with this block.
//
// Returns true on success, false on error.
//
static bool TransferBlock(TrunksDBusProxy* proxy,
                          const char* data,
                          size_t data_offset,
                          size_t block_size) {
  uint8_t digest[SHA_DIGEST_LENGTH];
  UpdatePduHeader updu;
  SHA_CTX shaCtx;
  std::string response;

  printf("sending 0x%zx bytes to offset %#zx\n", block_size, data_offset);

  updu.pdu_base_offset = base::NetToHost32(data_offset);
  SHA1_Init(&shaCtx);
  SHA1_Update(&shaCtx, &updu.pdu_base_offset, sizeof(updu.pdu_base_offset));
  SHA1_Update(&shaCtx, data + data_offset, block_size);
  SHA1_Final(digest, &shaCtx);

  memcpy(&updu.pdu_digest, digest, sizeof(updu.pdu_digest));

  std::string request =
      std::string(reinterpret_cast<char*>(&updu), sizeof(updu)) +
      std::string(data + data_offset, block_size);

  uint32_t rv =
      VendorCommand(proxy, CR50_EXTENSION_FW_UPGRADE, request, &response, true);
  if (rv) {
    LOG(ERROR) << "Failed to transfer image block, got 0x" << std::hex << rv;
    return false;
  }

  if (response.size() != 1) {
    LOG(ERROR) << "Unexpected return size " << response.size();
    return false;
  }

  if (response.data()[0]) {
    rv = response.data()[0];
    LOG(ERROR) << "Error " << rv;
    return false;
  }

  return true;
}

//
// Sends to the TPM the first transfer PDU, it is just 8 bytes of zeros. Verify
// the expected response (which is of FirstResponsePdu structure).
//
// Returns true on success, false on error.
//
static bool SetupConnection(TrunksDBusProxy* proxy, FirstResponsePdu* rpdu) {
  // Connection setup is triggered by 8 bytes of zeros.
  std::string request(8, 0);
  std::string response;

  uint32_t rv =
      VendorCommand(proxy, CR50_EXTENSION_FW_UPGRADE, request, &response, true);
  if (rv) {
    LOG(ERROR) << "Failed to set up connection, got 0x" << std::hex << rv;
    return false;
  }

  // We got something. Check for errors.
  if (response.size() < sizeof(FirstResponsePdu)) {
    LOG(ERROR) << "Unexpected response size " << response.size();
    return false;
  }

  // Let's unmarshal the response
  memcpy(rpdu, response.data(), std::min(sizeof(*rpdu), response.size()));

  rpdu->return_value = base::NetToHost32(rpdu->return_value);
  if (rpdu->return_value) {
    LOG(ERROR) << "Target reporting error 0x" << std::hex << rpdu->return_value;
    return false;
  }

  rpdu->protocol_version = base::NetToHost32(rpdu->protocol_version);
  if (rpdu->protocol_version < 5) {
    LOG(ERROR) << "Unsupported protocol version " << rpdu->protocol_version;
    return false;
  }
  printf("protocol version: %d\n", rpdu->protocol_version);
  rpdu->backup_ro_offset = base::NetToHost32(rpdu->backup_ro_offset);
  rpdu->backup_rw_offset = base::NetToHost32(rpdu->backup_rw_offset);

  for (int i = 0; i < base::size(rpdu->shv); i++) {
    rpdu->shv[i].minor = base::NetToHost32(rpdu->shv[i].minor);
    rpdu->shv[i].major = base::NetToHost32(rpdu->shv[i].major);
    rpdu->shv[i].epoch = base::NetToHost32(rpdu->shv[i].epoch);
  }

  printf("offsets: backup RO at %#x, backup RW at %#x\n",
         rpdu->backup_ro_offset, rpdu->backup_rw_offset);
  return true;
}

//
// Compares version fields in the header of the new image to the versions
// running on the target. Returns true if the new image is newer.
//
static bool ImageIsNewer(const EssentialHeader& header,
                         const SignedHeaderVersion& shv) {
  if (header.epoch != shv.epoch)
    return header.epoch > shv.epoch;
  if (header.major != shv.major)
    return header.major > shv.major;
  return header.minor > shv.minor;
}

//
// Updates RO or RW section of the Cr50 image on the device.
// A section is updated only if it's newer than the one currently on the
// device, or if |force| is set to true.
//
// |update_image| is the entire 512K file produced by the builder,
// |section_offset| is the offset of either inactive RO or inactive RW on
// the device, |shv| communicates this section's version retrieved from the
// device.
//
// Returns true on success, false on error. Skipping an update if the current
// version is not older than the one in |update_image| is considered a success.
//
static bool TransferSection(TrunksDBusProxy* proxy,
                            const std::string& update_image,
                            uint32_t section_offset,
                            const SignedHeaderVersion& shv,
                            bool force) {
  EssentialHeader header;

  // Try reading the header into the structure.
  if ((section_offset + sizeof(EssentialHeader)) > update_image.size()) {
    LOG(ERROR) << "Header at offset 0x" << std::hex << section_offset
               << " does not fit into the image of " << std::dec
               << update_image.size() << " bytes";
    return false;
  }
  memcpy(&header, update_image.data() + section_offset, sizeof(header));

  if (header.magic != 0xffffffff) {
    LOG(ERROR) << "Wrong magic value 0x" << std::hex << header.magic
               << " at offset 0x" << std::hex << section_offset;
    return false;
  }

  if (header.image_size > (update_image.size() - section_offset)) {
    LOG(ERROR) << "Wrong section size 0x" << std::hex << header.image_size
               << " at offset 0x" << std::hex << section_offset;
    return false;
  }

  printf("Offset %#x file at %d.%d.%d device at %d.%d.%d, section size %d\n",
         section_offset, header.epoch, header.major, header.minor, shv.epoch,
         shv.major, shv.minor, header.image_size);
  if (!force && !ImageIsNewer(header, shv)) {
    printf("Skipping update\n");
    return true;
  }

  // Transfer section, one block at a time.
  size_t block_size;
  for (uint32_t transferred = 0; transferred < header.image_size;
       transferred += block_size) {
    block_size = std::min(header.image_size - transferred, kTransferSize);
    if (!TransferBlock(proxy, update_image.data(), section_offset + transferred,
                       block_size)) {
      return false;
    }
  }

  return true;
}

//
// Updates the Cr50 image on the device. |update_image| contains the entire
// new Cr50 image.
// Each of the Cr50 sections is updated only if it's newer than the one
// currently on the device, or if |force| is set to true. Otherwise the
// session is skipped. The information about the section offsets and current
// versions is taken from the response to the connection request |rpdu| received
// from the device earlier.
//
// Returns the number of successfully updated sections (including skipped), or
// a negative value in case of error.
//
static int TransferImage(TrunksDBusProxy* proxy,
                         const std::string& update_image,
                         const FirstResponsePdu& rpdu,
                         bool force) {
  int num_txed_sections = 0;
  uint32_t section_offsets[] = {rpdu.backup_ro_offset, rpdu.backup_rw_offset};
  int index;

  //
  // The cr50 will not accept lower addresses after higher addresses for 60
  // seconds. Decide what section needs to be transferred first.
  //

  index = section_offsets[0] > section_offsets[1] ? 1 : 0;
  for (int i = 0; i < base::size(section_offsets); i++) {
    if (!TransferSection(proxy, update_image, section_offsets[index],
                         rpdu.shv[index], force)) {
      if (!force) {
        return -1;
      }
    } else {
      num_txed_sections++;
    }
    index = (index + 1) % base::size(section_offsets);
  }

  return num_txed_sections;
}

enum UpdateStatus { UpdateSuccess = 0, UpdateError = 1, UpdateCancelled = 2 };

// Updathe the Cr50 image on the device.
static UpdateStatus HandleUpdate(TrunksDBusProxy* proxy,
                                 base::CommandLine* cl) {
  if (cl->GetArgs().size() != 1) {
    LOG(ERROR) << "A single image file name must be provided.";
    return UpdateError;
  }

  base::FilePath filename(cl->GetArgs()[0]);

  std::string update_image;
  if (!base::ReadFileToString(filename, &update_image)) {
    LOG(ERROR) << "Failed to read " << filename.value();
    return UpdateError;
  }

  FirstResponsePdu rpdu;
  if (!SetupConnection(proxy, &rpdu)) {
    return UpdateError;
  }

  // Cr50 images with RW versoin below 0.0.19 process updates differently,
  // and as such require special treatment.
  bool running_pre_19 = rpdu.shv[1].minor < 19 && rpdu.shv[1].major == 0 &&
                        rpdu.shv[1].epoch == 0;

  if (running_pre_19 && !cl->HasSwitch(kForce)) {
    printf("Not updating from RW 0.0.%d, use --force if necessary\n",
           rpdu.shv[1].minor);
    return UpdateCancelled;
  }

  int rv = TransferImage(proxy, update_image, rpdu, cl->HasSwitch(kForce));

  if (rv < 0) {
    return UpdateError;
  }

  // Positive rv indicates that some sections were transferred and a Cr50
  // reboot is required. RW Cr50 versions below 0.0.19 require a posted reset
  // to switch to the new image.
  if (rv > 0 && running_pre_19) {
    std::string dummy;

    LOG(INFO) << "Will post a reset request.";

    if (VendorCommand(proxy, VENDOR_CC_POST_RESET, dummy, &dummy, true)) {
      LOG(ERROR) << "Failed to post a reset request.";
      return UpdateError;
    }
  }

  return UpdateSuccess;
}

// Vendor command to get the console lock state
static int VcGetLock(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  std::string out;
  uint32_t rc = VendorCommand(proxy, VENDOR_CC_GET_LOCK, out, &out);

  if (!rc)
    printf("lock is %s\n", out[0] ? "enabled" : "disabled");

  return rc != 0;
}

// Vendor command to set the console lock
static int VcSetLock(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  std::string out;
  uint32_t rc = VendorCommand(proxy, VENDOR_CC_SET_LOCK, out, &out);

  if (!rc)
    printf("lock is enabled\n");

  return rc != 0;
}

static const char* key_type(uint32_t key_id) {
  // It is a mere convention, but all prod keys are required to have key
  // IDs such that bit D2 is set, and all dev keys are required to have
  // key IDs such that bit D2 is not set.
  if (key_id & (1 << 2))
    return "prod";
  else
    return "dev";
}

// SysInfo command:
// There are no input args.
// Output is this struct, all fields in network order.
struct sysinfo_s {
  uint32_t ro_keyid;
  uint32_t rw_keyid;
  uint32_t dev_id0;
  uint32_t dev_id1;
} __attribute__((packed));

static int VcSysInfo(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  std::string out;
  uint32_t rc = VendorCommand(proxy, VENDOR_CC_SYSINFO, out, &out);

  if (rc)
    return 1;

  if (out.size() != sizeof(struct sysinfo_s)) {
    LOG(ERROR) << "Wrong TPM response size.";
    return 1;
  }

  struct sysinfo_s sysinfo;
  memcpy(&sysinfo, out.c_str(), out.size());
  sysinfo.ro_keyid = base::NetToHost32(sysinfo.ro_keyid);
  sysinfo.rw_keyid = base::NetToHost32(sysinfo.rw_keyid);
  sysinfo.dev_id0 = base::NetToHost32(sysinfo.dev_id0);
  sysinfo.dev_id1 = base::NetToHost32(sysinfo.dev_id1);

  printf("RO keyid:    0x%08x (%s)\n", sysinfo.ro_keyid,
         key_type(sysinfo.ro_keyid));
  printf("RW keyid:    0x%08x (%s)\n", sysinfo.rw_keyid,
         key_type(sysinfo.rw_keyid));
  printf("DEV_ID:      0x%08x 0x%08x\n", sysinfo.dev_id0, sysinfo.dev_id1);

  return 0;
}

// PopLogEntry command:
// There are no input args.
// Output is this struct, all fields in network order.
struct logentry_s {
  uint32_t timestamp; /* Relative timestamp of event, "msec ago" */
  uint8_t type;       /* Type of event logged */
  uint8_t size;       /* Byte size of extra payload data, only 0 supported */
  uint16_t data;      /* Type-defined additional log info */
} __attribute__((packed));

static int VcPopLogEntry(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  std::string out;
  uint32_t rc = VendorCommand(proxy, VENDOR_CC_POP_LOG_ENTRY, out, &out);
  base::Time ts;
  base::Time::Exploded ts_exploded;

  if (rc)
    return 1;

  if (out.size() == 0) {
    LOG(INFO) << "No log entry available.";
    return 0;
  }
  if (out.size() != sizeof(struct logentry_s)) { /* proper struct */
    LOG(ERROR) << "Wrong TPM response size.";
    return 1;
  }

  struct logentry_s logentry;
  memcpy(&logentry, out.c_str(), out.size());
  logentry.timestamp = base::NetToHost32(logentry.timestamp);
  logentry.data = base::NetToHost16(logentry.data);

  ts =
      base::Time::Now() - base::TimeDelta::FromMilliseconds(logentry.timestamp);
  ts.LocalExplode(&ts_exploded);

  printf("LogEntry %04i%02i%02i-%02i:%02i:%02i.%03i: Type: 0x%x Data: 0x%x\n",
         ts_exploded.year, ts_exploded.month, ts_exploded.day_of_month,
         ts_exploded.hour, ts_exploded.minute, ts_exploded.second,
         ts_exploded.millisecond, logentry.type, logentry.data);
  return 0;
}

// U2F APDU header (as defined by ISO7816-4:2005)
struct ApduHeader {
  uint8_t cla;
  uint8_t ins;
  uint8_t p1;
  uint8_t p2;
  uint8_t lc;
} __attribute__((packed));

static int SendU2fApdu(TrunksDBusProxy* proxy,
                       uint8_t ins,
                       uint8_t p1,
                       uint8_t p2,
                       const std::string& payload,
                       std::string* response) {
  std::string out;
  struct ApduHeader apdu;

  // The instruction class is always 0 for this transport.
  apdu.cla = 0;
  apdu.ins = ins;
  apdu.p1 = p1;
  apdu.p2 = p2;
  // Record the size of the payload, only supports small sizes < 256 bytes.
  if (payload.size() > 255)
    return -EINVAL;
  apdu.lc = payload.size();

  std::string request =
      std::string(reinterpret_cast<char*>(&apdu), sizeof(apdu)) + payload;
  uint32_t rc = VendorCommand(proxy, VENDOR_CC_U2F_APDU, request, &out);
  if (!rc) {
    if (out.length() < sizeof(uint16_t))
      return -EINVAL;
    // The status word is stored in the last 2 bytes.
    size_t sw_off = out.length() - sizeof(uint16_t);
    uint16_t sw;
    memcpy(&sw, out.c_str() + sw_off, sizeof(sw));
    *response = out.substr(0, sw_off);
    return base::NetToHost16(sw);
  }
  return -rc;
}

// ECDSA P256 uses 256-bit integers.
#define P256_NBYTES (256 / 8)

static int VcU2fCert(TrunksDBusProxy* proxy, base::CommandLine* cl) {
  const uint8_t kCmdU2fRegister = 0x01;
  const uint8_t kCmdU2fVendorMode = 0xbf;
  const uint8_t kG2fAttest = 0x80;
  const uint8_t kSetMode = 1;
  const uint8_t kU2fExtended = 3;
  const uint16_t kSwNoError = 0x9000;

  std::string resp;

  // Send the mode to U2f + extensions
  int sw = SendU2fApdu(proxy, kCmdU2fVendorMode, kSetMode, kU2fExtended,
                       std::string(), &resp);
  if (sw < 0) {
    if ((-sw & VENDOR_RC_MASK) == VENDOR_RC_NO_SUCH_COMMAND)
      LOG(ERROR) << "U2F Feature not available in firmware.";
    else
      LOG(ERROR) << "U2F vendor command failed with error " << std::hex << -sw;
    return 1;
  } else if (sw != kSwNoError) {
    LOG(ERROR) << "Set U2F Mode failed SW=" << std::hex << sw;
    return 1;
  }
  if (resp.length() < 1 || resp[0] != kU2fExtended) {
    LOG(ERROR) << "Cannot set extended U2F Mode " << std::hex
               << static_cast<int>(resp[0]);
    return 1;
  }

  // Use the SHA-256 of the empty string if no parameter is passed.
  std::string nonce(crypto::SHA256HashString(cl->GetSwitchValueASCII("nonce")));
  std::string appid(crypto::SHA256HashString(cl->GetSwitchValueASCII("appid")));

  std::string payload = nonce + appid;
  sw = SendU2fApdu(proxy, kCmdU2fRegister, kG2fAttest, 0, payload, &resp);
  if (sw != kSwNoError) {
    LOG(ERROR) << "U2F Register failed  SW=" << std::hex << sw;
    return 1;
  }

  // The response is:
  // A reserved byte [1 byte], which for legacy reasons has the value 0x05.
  // A user public key [65 bytes]. This is the (uncompressed) x,y-representation
  //                               of a curve point on the P-256 elliptic curve.
  // A key handle length byte [1 byte], which specifies the length of the key
  //                                    handle (see below).
  //                                    The value is unsigned (range 0-255).
  // A key handle [length, see previous field]. This a handle that
  //                                    allows the U2F token to identify the
  //                                    generated key pair. U2F tokens may wrap
  //                                    the generated private key and the
  //                                    application id it was generated for,
  //                                    and output that as the key handle.
  // An attestation certificate [variable length]. This is a certificate in
  //                                    X.509 DER format.
  // A signature. This is a ECDSA signature (on P-256).
  const int pkey_offset = 1;
  const size_t pkey_size = 1 + 2 * P256_NBYTES;
  const int handle_len_offset = pkey_offset + pkey_size;
  const int handle_offset = handle_len_offset + 1;

  if (resp.size() < handle_offset) {  // Invalid response length
    LOG(ERROR) << "Invalid response length " << resp.size() << " < "
               << handle_offset;
    return 1;
  }
  printf("PubKey: %s\n",
         HexEncode(resp.substr(pkey_offset, pkey_size)).c_str());

  uint8_t handle_len = resp[handle_len_offset];
  if (resp.size() < handle_offset + handle_len) {  // Invalid response length
    LOG(ERROR) << "Invalid response length " << resp.size() << " < "
               << handle_offset << " + " << handle_len;
    return 1;
  }
  printf("KeyHandle: %s\n",
         HexEncode(resp.substr(handle_offset, handle_len)).c_str());
  const int cert_offset = handle_offset + handle_len;
  if (resp.size() < cert_offset + 4) {  // Invalid response length
    LOG(ERROR) << "Invalid response length " << resp.size() << " < "
               << handle_offset << " + 4";
    return 1;
  }
  // parse the first tag of the certificate ASN.1 data to know its length.
  std::string cert_seq_tag = resp.substr(cert_offset, 4);
  // If we cannot find the size, do a safe bet and use the P256 signature
  // uncompressed size while it is ASN.1 DER encoded here, the certificate
  // might have few trailing bytes from the signature which is harmless.
  size_t cert_size = resp.size() - cert_offset - P256_NBYTES;

  // ASN.1 DER constants we are using.
  static const uint8_t kAsn1ClassStructured = 0x20;
  static const uint8_t kAsn1TagSequence = 0x10;
  static const uint8_t kAsn1LengthLong = 0x80;
  // Should be a Constructed Sequence ASN.1 tag else all bets are off,
  // with the size taking 2 bytes (the certificate size is somewhere between
  // 256B and 2KB).
  if ((static_cast<uint8_t>(cert_seq_tag[0]) ==
       (kAsn1ClassStructured | kAsn1TagSequence)) &&
      (static_cast<uint8_t>(cert_seq_tag[1]) ==
       (kAsn1LengthLong | sizeof(uint16_t)))) {
    uint16_t length_tag;
    memcpy(&length_tag, cert_seq_tag.c_str() + 2, sizeof(length_tag));
    cert_size = base::NetToHost16(length_tag) + cert_seq_tag.size();
  }
  if (resp.size() < cert_offset + cert_size) {  // Invalid response length
    LOG(ERROR) << "Invalid response length " << resp.size() << " < "
               << cert_offset << " + " << cert_size;
    return 1;
  }

  std::string cert = resp.substr(cert_offset, cert_size);
  printf("Cert: %s\n", HexEncode(cert).c_str());
  const int sig_offset = cert_offset + cert_size;
  const size_t sig_size = resp.size() - sig_offset;
  if (resp.size() < sig_offset + sig_size) {  // Invalid response length
    LOG(ERROR) << "Invalid response length " << resp.size() << " < "
               << sig_offset << " + " << sig_size;
    return 1;
  }
  printf("Signature(P256): %s\n",
         HexEncode(resp.substr(sig_offset, sig_size)).c_str());

  base::FilePath crt(cl->GetSwitchValuePath("crt"));
  if (!crt.empty()) {
    printf("Certificate file: %s\n", crt.value().c_str());
    base::WriteFile(crt, cert.data(), cert.size());
  }

  return 0;
}

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);
  brillo::InitLog(brillo::kLogToStderr);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

  if (cl->HasSwitch(kVerbose)) {
    verbose = 1;
  }

  TrunksDBusProxy proxy;
  if (!proxy.Init()) {
    LOG(ERROR) << "Failed to initialize dbus proxy.";
    return 1;
  }

  if (cl->HasSwitch(kRaw))
    return HandleRaw(&proxy, cl);

  if (cl->HasSwitch(kGetLock))
    return VcGetLock(&proxy, cl);

  if (cl->HasSwitch(kPopLogEntry))
    return VcPopLogEntry(&proxy, cl);

  if (cl->HasSwitch(kSetLock))
    return VcSetLock(&proxy, cl);

  if (cl->HasSwitch(kSysInfo))
    return VcSysInfo(&proxy, cl);

  if (cl->HasSwitch(kU2fCert))
    return VcU2fCert(&proxy, cl);

  if (cl->HasSwitch(kUpdate))
    return HandleUpdate(&proxy, cl);

  PrintUsage();
  return 1;
}
