// 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 "base/memory/ptr_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "u2f_apdu_command.h"
#include "u2f_apdu_response.h"

namespace device {

class U2fApduTest : public testing::Test {};

TEST_F(U2fApduTest, TestDeserializeBasic) {
  uint8_t cla = 0xAA;
  uint8_t ins = 0xAB;
  uint8_t p1 = 0xAC;
  uint8_t p2 = 0xAD;
  std::vector<uint8_t> message = {cla, ins, p1, p2};
  std::unique_ptr<U2fApduCommand> cmd =
      U2fApduCommand::CreateFromMessage(message);

  EXPECT_EQ(static_cast<size_t>(0), cmd->response_length_);
  EXPECT_THAT(cmd->data_, testing::ContainerEq(std::vector<uint8_t>()));
  EXPECT_EQ(cmd->cla_, cla);
  EXPECT_EQ(cmd->ins_, ins);
  EXPECT_EQ(cmd->p1_, p1);
  EXPECT_EQ(cmd->p2_, p2);

  // Invalid length
  message = {cla, ins, p1};
  EXPECT_EQ(nullptr, U2fApduCommand::CreateFromMessage(message));
  message.push_back(p2);
  message.push_back(0);
  message.push_back(0xFF);
  message.push_back(0xFF);
  std::vector<uint8_t> oversized(U2fApduCommand::kApduMaxDataLength);
  message.insert(message.end(), oversized.begin(), oversized.end());
  message.push_back(0);
  message.push_back(0);
  EXPECT_NE(nullptr, U2fApduCommand::CreateFromMessage(message));
  message.push_back(0);
  EXPECT_EQ(nullptr, U2fApduCommand::CreateFromMessage(message));
}

TEST_F(U2fApduTest, TestDeserializeComplex) {
  uint8_t cla = 0xAA;
  uint8_t ins = 0xAB;
  uint8_t p1 = 0xAC;
  uint8_t p2 = 0xAD;
  std::vector<uint8_t> data(
      U2fApduCommand::kApduMaxDataLength - U2fApduCommand::kApduMaxHeader - 2,
      0x7F);
  std::vector<uint8_t> message = {cla, ins, p1, p2, 0};
  message.push_back((data.size() >> 8) & 0xff);
  message.push_back(data.size() & 0xff);
  message.insert(message.end(), data.begin(), data.end());

  // Create a message with no response expected
  std::unique_ptr<U2fApduCommand> cmd_no_response =
      U2fApduCommand::CreateFromMessage(message);
  EXPECT_EQ(static_cast<size_t>(0), cmd_no_response->response_length_);
  EXPECT_THAT(data, testing::ContainerEq(cmd_no_response->data_));
  EXPECT_EQ(cmd_no_response->cla_, cla);
  EXPECT_EQ(cmd_no_response->ins_, ins);
  EXPECT_EQ(cmd_no_response->p1_, p1);
  EXPECT_EQ(cmd_no_response->p2_, p2);

  // Add response length to message
  message.push_back(0xF1);
  message.push_back(0xD0);
  std::unique_ptr<U2fApduCommand> cmd =
      U2fApduCommand::CreateFromMessage(message);
  EXPECT_THAT(data, testing::ContainerEq(cmd->data_));
  EXPECT_EQ(cmd->cla_, cla);
  EXPECT_EQ(cmd->ins_, ins);
  EXPECT_EQ(cmd->p1_, p1);
  EXPECT_EQ(cmd->p2_, p2);
  EXPECT_EQ(static_cast<size_t>(0xF1D0), cmd->response_length_);
}

TEST_F(U2fApduTest, TestDeserializeResponse) {
  U2fApduResponse::Status status;
  std::unique_ptr<U2fApduResponse> response;
  std::vector<uint8_t> test_vector;

  // Invalid length
  std::vector<uint8_t> message = {0xAA};
  EXPECT_EQ(nullptr, U2fApduResponse::CreateFromMessage(message));

  // Valid length and status
  status = U2fApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED;
  message = {static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8),
             static_cast<uint8_t>(status)};
  response = U2fApduResponse::CreateFromMessage(message);
  ASSERT_NE(nullptr, response);
  EXPECT_EQ(U2fApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED,
            response->response_status_);
  EXPECT_THAT(response->data_, testing::ContainerEq(std::vector<uint8_t>()));

  // Valid length and status
  status = U2fApduResponse::Status::SW_NO_ERROR;
  message = {static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8),
             static_cast<uint8_t>(status)};
  test_vector = {0x01, 0x02, 0xEF, 0xFF};
  message.insert(message.begin(), test_vector.begin(), test_vector.end());
  response = U2fApduResponse::CreateFromMessage(message);
  ASSERT_NE(nullptr, response);
  EXPECT_EQ(U2fApduResponse::Status::SW_NO_ERROR, response->response_status_);
  EXPECT_THAT(response->data_, testing::ContainerEq(test_vector));
}

TEST_F(U2fApduTest, TestSerializeCommand) {
  auto cmd = base::MakeUnique<U2fApduCommand>();

  cmd->set_cla(0xA);
  cmd->set_ins(0xB);
  cmd->set_p1(0xC);
  cmd->set_p2(0xD);

  // No data, no response expected
  std::vector<uint8_t> expected({0xA, 0xB, 0xC, 0xD});
  ASSERT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(
      expected,
      testing::ContainerEq(
          U2fApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));

  // No data, response expected
  cmd->set_response_length(0xCAFE);
  expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0xCA, 0xFE};
  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(
      expected,
      testing::ContainerEq(
          U2fApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));

  // Data exists, response expected
  std::vector<uint8_t> data({0x1, 0x2, 0x3, 0x4});
  cmd->set_data(data);
  expected = {0xA, 0xB, 0xC, 0xD, 0x0,  0x0, 0x4,
              0x1, 0x2, 0x3, 0x4, 0xCA, 0xFE};
  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(
      expected,
      testing::ContainerEq(
          U2fApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));

  // Data exists, no response expected
  cmd->set_response_length(0);
  expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4};
  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(
      expected,
      testing::ContainerEq(
          U2fApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));
}

TEST_F(U2fApduTest, TestSerializeEdgeCases) {
  auto cmd = base::MakeUnique<U2fApduCommand>();

  cmd->set_cla(0xA);
  cmd->set_ins(0xB);
  cmd->set_p1(0xC);
  cmd->set_p2(0xD);

  // Set response length to maximum, which should serialize to 0x0000
  cmd->set_response_length(U2fApduCommand::kApduMaxResponseLength);
  std::vector<uint8_t> expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x0};
  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(
      expected,
      testing::ContainerEq(
          U2fApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));

  // Maximum data size
  std::vector<uint8_t> oversized(U2fApduCommand::kApduMaxDataLength);
  cmd->set_data(oversized);
  EXPECT_THAT(cmd->GetEncodedCommand(),
              testing::ContainerEq(
                  U2fApduCommand::CreateFromMessage(cmd->GetEncodedCommand())
                      ->GetEncodedCommand()));
}

TEST_F(U2fApduTest, TestCreateSign) {
  std::vector<uint8_t> appid(U2fApduCommand::kAppIdDigestLen, 0x01);
  std::vector<uint8_t> challenge(U2fApduCommand::kChallengeDigestLen, 0xff);
  std::vector<uint8_t> key_handle(U2fApduCommand::kMaxKeyHandleLength);

  std::unique_ptr<U2fApduCommand> cmd =
      U2fApduCommand::CreateSign(appid, challenge, key_handle);
  ASSERT_NE(nullptr, cmd);
  EXPECT_THAT(U2fApduCommand::CreateFromMessage(cmd->GetEncodedCommand())
                  ->GetEncodedCommand(),
              testing::ContainerEq(cmd->GetEncodedCommand()));
  // Expect null result with incorrectly sized key handle
  key_handle.push_back(0x0f);
  cmd = U2fApduCommand::CreateSign(appid, challenge, key_handle);
  EXPECT_EQ(nullptr, cmd);
  key_handle.pop_back();
  // Expect null result with incorrectly sized appid
  appid.pop_back();
  cmd = U2fApduCommand::CreateSign(appid, challenge, key_handle);
  EXPECT_EQ(nullptr, cmd);
  appid.push_back(0xff);
  // Expect null result with incorrectly sized challenge
  challenge.push_back(0x0);
  cmd = U2fApduCommand::CreateSign(appid, challenge, key_handle);
  EXPECT_EQ(nullptr, cmd);
}

TEST_F(U2fApduTest, TestCreateRegister) {
  std::vector<uint8_t> appid(U2fApduCommand::kAppIdDigestLen, 0x01);
  std::vector<uint8_t> challenge(U2fApduCommand::kChallengeDigestLen, 0xff);
  std::unique_ptr<U2fApduCommand> cmd =
      U2fApduCommand::CreateRegister(appid, challenge);
  ASSERT_NE(nullptr, cmd);
  EXPECT_THAT(U2fApduCommand::CreateFromMessage(cmd->GetEncodedCommand())
                  ->GetEncodedCommand(),
              testing::ContainerEq(cmd->GetEncodedCommand()));
  // Expect null result with incorrectly sized appid
  appid.push_back(0xff);
  cmd = U2fApduCommand::CreateRegister(appid, challenge);
  EXPECT_EQ(nullptr, cmd);
  appid.pop_back();
  // Expect null result with incorrectly sized challenge
  challenge.push_back(0xff);
  cmd = U2fApduCommand::CreateRegister(appid, challenge);
  EXPECT_EQ(nullptr, cmd);
}

TEST_F(U2fApduTest, TestCreateVersion) {
  std::unique_ptr<U2fApduCommand> cmd = U2fApduCommand::CreateVersion();
  std::vector<uint8_t> expected = {
      0x0, U2fApduCommand::kInsU2fVersion, 0x0, 0x0, 0x0, 0x0, 0x0};

  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(U2fApduCommand::CreateFromMessage(cmd->GetEncodedCommand())
                  ->GetEncodedCommand(),
              testing::ContainerEq(cmd->GetEncodedCommand()));
}

TEST_F(U2fApduTest, TestCreateLegacyVersion) {
  std::unique_ptr<U2fApduCommand> cmd = U2fApduCommand::CreateLegacyVersion();
  // Legacy version command contains 2 extra null bytes compared to ISO 7816-4
  // format
  std::vector<uint8_t> expected = {
      0x0, U2fApduCommand::kInsU2fVersion, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

  EXPECT_THAT(expected, testing::ContainerEq(cmd->GetEncodedCommand()));
  EXPECT_THAT(U2fApduCommand::CreateFromMessage(cmd->GetEncodedCommand())
                  ->GetEncodedCommand(),
              testing::ContainerEq(cmd->GetEncodedCommand()));
}
}  // namespace device
