// Copyright 2019 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.

#ifndef U2FD_U2F_APDU_H_
#define U2FD_U2F_APDU_H_

#include <stdint.h>

#include <optional>
#include <string>
#include <vector>

#include "u2fd/util.h"

// Classes for dealing with command and response APDUs, as described in the "U2F
// Raw Message Formats" specification.

namespace u2f {

// INS codes used in U2F Command APDUs.
enum class U2fIns : uint8_t {
  kU2fRegister = 1,      // U2F_REGISTER
  kU2fAuthenticate = 2,  // U2F_AUTHENTICATE
  kU2fVersion = 3,       // U2F_VERSION

  // TODO(crbug.com/1218246) Change UMA enum name kU2fCommand if new enums are
  // added to avoid data discontinuity.
  kInsInvalid = 0xff,
};

// Represents a command APDU.
class U2fCommandApdu {
 public:
  // Fixed-size header of a command APDU.
  struct Header {
    U2fIns ins_;
    uint8_t p1_;
    uint8_t p2_;
  };

  // Attempts to parse the specified string as an APDU, and returns a valid
  // U2fCommandApdu if successful, or std::nullopt otherwise. If unsuccessful,
  // and u2f_status is not null, populates it with a U2F status code indicating
  // the type of failure, if an appropriate code is available, or 0 otherwise.
  static std::optional<U2fCommandApdu> ParseFromString(
      const std::string& apdu_raw, uint16_t* u2f_status);

  // Creates an 'empty' APDU for the command with the specified INS command
  // code.
  static U2fCommandApdu CreateForU2fIns(U2fIns ins);

  // Returns the INS command code for this APDU.
  U2fIns Ins() const { return header_.ins_; }
  // Returns the P1 parameter for this APDU.
  uint8_t P1() const { return header_.p1_; }
  // Returns the request body for this APDU.
  const std::string& Body() const { return data_; }
  // Returns the max response length for this APDU.
  uint32_t MaxResponseLength() const { return max_response_length_; }
  // Serializes this APDU to a string.
  std::string ToString() const;

 protected:
  Header header_;
  std::string data_;
  uint32_t max_response_length_;

 private:
  // Private constructor, use factory methods above.
  U2fCommandApdu() = default;
  // Internal parser class called by ParseFromString().
  class Parser;
  friend class Parser;
};

// Represents an APDU for a U2F_REGISTER request.
class U2fRegisterRequestApdu {
 public:
  // Attempt to parse the body of the specified APDU as a U2F_REGISTER request.
  // Returns a valid U2fRegisterRequestApdu if successful, or std::nullopt
  // otherwise. If unsuccessful, and u2f_status is not null, populates it with
  // a U2F status code indicating the type of failure, if an appropriate code
  // is available, or 0 otherwise.
  static std::optional<U2fRegisterRequestApdu> FromCommandApdu(
      const U2fCommandApdu& apdu, uint16_t* u2f_status);

  // Whether the request response should use the G2F attestation certificate (if
  // available).
  bool UseG2fAttestation() const { return g2f_attestation_; }

  // Whether the request is a 'bogus' request sent by Chrome, solely to cause a
  // USB device to flash its LED.
  bool IsChromeDummyWinkRequest() const;

  // Accessors for the request fields.
  const std::vector<uint8_t>& GetAppId() const { return app_id_; }
  const std::vector<uint8_t>& GetChallenge() const { return challenge_; }

 private:
  bool g2f_attestation_;
  std::vector<uint8_t> app_id_;
  std::vector<uint8_t> challenge_;
};

class U2fAuthenticateRequestApdu {
 public:
  // Attempt to parse the body of the specified APDU as a U2F_AUTHENTICATE
  // request. Returns a valid U2fRegisterRequestApdu if successful, or
  // std::nullopt otherwise. If unsuccessful, and u2f_status is not null,
  // populates it with a U2F status code indicating the type of failure,
  // if an appropriate code is available, or 0 otherwise.
  static std::optional<U2fAuthenticateRequestApdu> FromCommandApdu(
      const U2fCommandApdu& apdu, uint16_t* u2f_status);

  // Returns true if the APDU is for a U2F_AUTHENTICATE check-only
  // request. Check-only requests should verify whether the specified key handle
  // is owned by this U2F device, but not perform any authentication.
  bool IsAuthenticateCheckOnly() const { return auth_check_only_; }

  // Accessors for the request fields.
  const std::vector<uint8_t>& GetAppId() const { return app_id_; }
  const std::vector<uint8_t>& GetChallenge() const { return challenge_; }
  const std::vector<uint8_t>& GetKeyHandle() const { return key_handle_; }

 private:
  bool auth_check_only_;
  std::vector<uint8_t> app_id_;
  std::vector<uint8_t> challenge_;
  std::vector<uint8_t> key_handle_;
};

// Represents a response APDU. Provides methods for building  nd serializing a
// response.
class U2fResponseApdu {
 public:
  // Constructs an empty response.
  U2fResponseApdu() = default;

  // Serialize the response to the specified string.
  bool ToString(std::string* out) const;

  // Methods to append data to the response.
  void AppendByte(uint8_t byte) { data_.push_back(byte); }
  void AppendBytes(const std::vector<uint8_t>& bytes) {
    util::AppendToVector(bytes, &data_);
  }
  void AppendString(const std::string& string) {
    util::AppendToVector(string, &data_);
  }
  template <typename T>
  void AppendObject(const T& obj) {
    util::AppendToVector(obj, &data_);
  }

  // Sets the return status for the response.
  void SetStatus(uint16_t sw) {
    sw1_ = sw >> 8;
    sw2_ = static_cast<uint8_t>(sw);
  }

 private:
  std::vector<uint8_t> data_;
  uint8_t sw1_;
  uint8_t sw2_;
};

}  // namespace u2f

#endif  // U2FD_U2F_APDU_H_
