// Copyright 2018 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/fido/u2f_register_operation.h"

#include <memory>
#include <utility>

#include "base/test/scoped_task_environment.h"
#include "device/fido/authenticator_make_credential_response.h"
#include "device/fido/ctap_make_credential_request.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_parsing_utils.h"
#include "device/fido/fido_test_data.h"
#include "device/fido/mock_fido_device.h"
#include "device/fido/test_callback_receiver.h"
#include "device/fido/virtual_u2f_device.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace device {

using ::testing::_;

namespace {

// Creates a CtapMakeCredentialRequest with given |registered_keys| as
// exclude list.
CtapMakeCredentialRequest CreateRegisterRequestWithRegisteredKeys(
    std::vector<PublicKeyCredentialDescriptor> registered_keys,
    bool is_individual_attestation = false) {
  PublicKeyCredentialRpEntity rp(test_data::kRelyingPartyId);
  PublicKeyCredentialUserEntity user(
      fido_parsing_utils::Materialize(test_data::kUserId));

  CtapMakeCredentialRequest request(
      test_data::kClientDataJson, std::move(rp), std::move(user),
      PublicKeyCredentialParams(
          std::vector<PublicKeyCredentialParams::CredentialInfo>(1)));
  request.exclude_list = std::move(registered_keys);
  if (is_individual_attestation)
    request.attestation_preference =
        AttestationConveyancePreference::ENTERPRISE;

  return request;
}

// Creates a CtapMakeCredentialRequest with an empty exclude list.
CtapMakeCredentialRequest CreateRegisterRequest(
    bool is_individual_attestation = false) {
  return CreateRegisterRequestWithRegisteredKeys(
      std::vector<PublicKeyCredentialDescriptor>(), is_individual_attestation);
}

using TestRegisterCallback = ::device::test::StatusAndValueCallbackReceiver<
    CtapDeviceResponseCode,
    base::Optional<AuthenticatorMakeCredentialResponse>>;

}  // namespace

class U2fRegisterOperationTest : public ::testing::Test {
 public:
  TestRegisterCallback& register_callback_receiver() {
    return register_callback_receiver_;
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  TestRegisterCallback register_callback_receiver_;
};

TEST_F(U2fRegisterOperationTest, TestRegisterSuccess) {
  auto request = CreateRegisterRequest();
  auto device = std::make_unique<MockFidoDevice>();
  EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device"));
  device->ExpectRequestAndRespondWith(
      test_data::kU2fRegisterCommandApdu,
      test_data::kApduEncodedNoErrorRegisterResponse);

  auto u2f_register = std::make_unique<U2fRegisterOperation>(
      device.get(), std::move(request),
      register_callback_receiver().callback());
  u2f_register->Start();
  register_callback_receiver().WaitForCallback();

  EXPECT_EQ(CtapDeviceResponseCode::kSuccess,
            register_callback_receiver().status());
  ASSERT_TRUE(register_callback_receiver().value());
  EXPECT_THAT(register_callback_receiver().value()->raw_credential_id(),
              ::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
}

TEST_F(U2fRegisterOperationTest, TestRegisterSuccessWithFake) {
  auto request = CreateRegisterRequest();

  auto device = std::make_unique<VirtualU2fDevice>();
  auto u2f_register = std::make_unique<U2fRegisterOperation>(
      device.get(), std::move(request),
      register_callback_receiver().callback());
  u2f_register->Start();
  register_callback_receiver().WaitForCallback();

  EXPECT_EQ(CtapDeviceResponseCode::kSuccess,
            register_callback_receiver().status());
  // We don't verify the response from the fake, but do a quick sanity check.
  ASSERT_TRUE(register_callback_receiver().value());
  EXPECT_EQ(32ul,
            register_callback_receiver().value()->raw_credential_id().size());
}

TEST_F(U2fRegisterOperationTest, TestDelayedSuccess) {
  auto request = CreateRegisterRequest();

  auto device = std::make_unique<MockFidoDevice>();
  EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device"));

  // Device error out once waiting for user presence before retrying.
  ::testing::InSequence s;
  device->ExpectRequestAndRespondWith(
      test_data::kU2fRegisterCommandApdu,
      test_data::kU2fConditionNotSatisfiedApduResponse);

  device->ExpectRequestAndRespondWith(
      test_data::kU2fRegisterCommandApdu,
      test_data::kApduEncodedNoErrorRegisterResponse);

  auto u2f_register = std::make_unique<U2fRegisterOperation>(
      device.get(), std::move(request),
      register_callback_receiver().callback());
  u2f_register->Start();
  register_callback_receiver().WaitForCallback();

  EXPECT_EQ(CtapDeviceResponseCode::kSuccess,
            register_callback_receiver().status());
  ASSERT_TRUE(register_callback_receiver().value());
  EXPECT_THAT(register_callback_receiver().value()->raw_credential_id(),
              ::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
}

// Tests a scenario where a single device is connected and registration call
// is received with two unknown key handles. We expect that two check
// only sign-in calls be processed before registration.
TEST_F(U2fRegisterOperationTest, TestRegistrationWithExclusionList) {
  auto request = CreateRegisterRequestWithRegisteredKeys(
      {PublicKeyCredentialDescriptor(
           CredentialType::kPublicKey,
           fido_parsing_utils::Materialize(test_data::kKeyHandleAlpha)),
       PublicKeyCredentialDescriptor(
           CredentialType::kPublicKey,
           fido_parsing_utils::Materialize(test_data::kKeyHandleBeta))});

  auto device = std::make_unique<MockFidoDevice>();
  EXPECT_CALL(*device, GetId()).WillRepeatedly(::testing::Return("device"));
  // DeviceTransact() will be called three times including two check only sign-
  // in calls and one registration call. For the first two calls, device will
  // invoke MockFidoDevice::WrongData/WrongLength as the authenticator did not
  // create the two key handles provided in the exclude list. At the third call,
  // MockFidoDevice::NoErrorRegister will be invoked after registration.
  ::testing::InSequence s;
  device->ExpectRequestAndRespondWith(
      test_data::kU2fSignCommandApduWithKeyAlpha,
      test_data::kU2fWrongDataApduResponse);
  device->ExpectRequestAndRespondWith(test_data::kU2fSignCommandApduWithKeyBeta,
                                      test_data::kU2fWrongLengthApduResponse);
  device->ExpectRequestAndRespondWith(
      test_data::kU2fRegisterCommandApdu,
      test_data::kApduEncodedNoErrorRegisterResponse);

  auto u2f_register = std::make_unique<U2fRegisterOperation>(
      device.get(), std::move(request),
      register_callback_receiver().callback());
  u2f_register->Start();
  register_callback_receiver().WaitForCallback();

  ASSERT_TRUE(register_callback_receiver().value());
  EXPECT_EQ(CtapDeviceResponseCode::kSuccess,
            register_callback_receiver().status());
  EXPECT_THAT(register_callback_receiver().value()->raw_credential_id(),
              ::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
}

// Tests a scenario where single device is connected and registration is
// called with a key in the exclude list that was created by this device. We
// assume that the duplicate key is the last key handle in the exclude list.
// Therefore, after duplicate key handle is found, the process is expected to
// terminate after calling bogus registration which checks for user presence.
TEST_F(U2fRegisterOperationTest, TestRegistrationWithDuplicateHandle) {
  // Simulate two unknown key handles followed by a duplicate key.
  auto request = CreateRegisterRequestWithRegisteredKeys(
      {PublicKeyCredentialDescriptor(
           CredentialType::kPublicKey,
           fido_parsing_utils::Materialize(test_data::kKeyHandleAlpha)),
       PublicKeyCredentialDescriptor(
           CredentialType::kPublicKey,
           fido_parsing_utils::Materialize(test_data::kKeyHandleBeta)),
       PublicKeyCredentialDescriptor(
           CredentialType::kPublicKey,
           fido_parsing_utils::Materialize(test_data::kKeyHandleGamma))});

  auto device = std::make_unique<MockFidoDevice>();
  EXPECT_CALL(*device, GetId()).WillRepeatedly(::testing::Return("device"));
  // For three keys in exclude list, the first two keys will invoke
  // MockFidoDevice::WrongData and the final duplicate key handle will invoke
  // MockFidoDevice::NoErrorSign. Once duplicate key handle is found, bogus
  // registration is called to confirm user presence. This invokes
  // MockFidoDevice::NoErrorRegister.
  ::testing::InSequence s;
  device->ExpectRequestAndRespondWith(
      test_data::kU2fSignCommandApduWithKeyAlpha,
      test_data::kU2fWrongDataApduResponse);
  device->ExpectRequestAndRespondWith(test_data::kU2fSignCommandApduWithKeyBeta,
                                      test_data::kU2fWrongDataApduResponse);
  device->ExpectRequestAndRespondWith(
      test_data::kU2fSignCommandApduWithKeyGamma,
      test_data::kApduEncodedNoErrorSignResponse);

  auto u2f_register = std::make_unique<U2fRegisterOperation>(
      device.get(), std::move(request),
      register_callback_receiver().callback());
  u2f_register->Start();
  register_callback_receiver().WaitForCallback();

  EXPECT_EQ(CtapDeviceResponseCode::kCtap2ErrCredentialExcluded,
            register_callback_receiver().status());
  EXPECT_FALSE(register_callback_receiver().value());
}

MATCHER_P(IndicatesIndividualAttestation, expected, "") {
  return arg.size() > 2 && ((arg[2] & 0x80) == 0x80) == expected;
}

TEST_F(U2fRegisterOperationTest, TestIndividualAttestation) {
  // Test that the individual attestation flag is correctly reflected in the
  // resulting registration APDU.
  for (const auto& individual_attestation : {false, true}) {
    SCOPED_TRACE(individual_attestation);
    TestRegisterCallback cb;
    auto request = CreateRegisterRequest(individual_attestation);

    auto device = std::make_unique<MockFidoDevice>();
    EXPECT_CALL(*device, GetId()).WillRepeatedly(::testing::Return("device"));

    device->ExpectRequestAndRespondWith(
        individual_attestation
            ? test_data::kU2fRegisterCommandApduWithIndividualAttestation
            : test_data::kU2fRegisterCommandApdu,
        test_data::kApduEncodedNoErrorRegisterResponse);

    auto u2f_register = std::make_unique<U2fRegisterOperation>(
        device.get(), std::move(request), cb.callback());
    u2f_register->Start();
    cb.WaitForCallback();

    EXPECT_EQ(CtapDeviceResponseCode::kSuccess, cb.status());
    ASSERT_TRUE(cb.value());
    EXPECT_THAT(cb.value()->raw_credential_id(),
                ::testing::ElementsAreArray(test_data::kU2fSignKeyHandle));
  }
}

}  // namespace device
