// Copyright 2020 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 "u2fd/webauthn_handler.h"

#include <optional>
#include <regex>  // NOLINT(build/c++11)
#include <string>
#include <utility>
#include <vector>

#include <base/check.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/dbus/mock_dbus_method_response.h>
#include <chromeos/cbor/values.h>
#include <chromeos/cbor/writer.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include <user_data_auth-client-test/user_data_auth/dbus-proxy-mocks.h>

#include "u2fd/mock_allowlisting_util.h"
#include "u2fd/mock_u2f_command_processor.h"
#include "u2fd/mock_user_state.h"
#include "u2fd/mock_webauthn_storage.h"
#include "u2fd/util.h"

namespace u2f {
namespace {

using ::brillo::dbus_utils::MockDBusMethodResponse;

using ::testing::_;
using ::testing::DoAll;
using ::testing::Matcher;
using ::testing::MatchesRegex;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrictMock;
using ::testing::Unused;

// Dummy User State.
constexpr char kUserSecret[65] = {[0 ... 63] = 'E', '\0'};
constexpr char kCredentialSecret[65] = {[0 ... 63] = 'F', '\0'};
// Dummy RP id.
constexpr char kRpId[] = "example.com";
// Wrong RP id is used to test app id extension path.
constexpr char kWrongRpId[] = "wrong.com";

// // Dummy cr50 U2F_SIGN_RESP.
const struct u2f_sign_resp kU2fSignResponse = {.sig_r = {[0 ... 31] = 0x12},
                                               .sig_s = {[0 ... 31] = 0x34}};

// AuthenticatorData field sizes, in bytes.
constexpr int kRpIdHashBytes = 32;
constexpr int kAuthenticatorDataFlagBytes = 1;
constexpr int kSignatureCounterBytes = 4;
constexpr int kAaguidBytes = 16;
constexpr int kCredentialIdLengthBytes = 2;

std::vector<uint8_t> GetAuthTimeSecretHash() {
  return std::vector<uint8_t>(32, 0x12);
}

std::vector<uint8_t> GetRpIdHash() {
  return util::Sha256(std::string(kRpId));
}

std::vector<uint8_t> GetWrongRpIdHash() {
  return util::Sha256(std::string(kWrongRpId));
}

std::vector<uint8_t> GetCorrectUserSecret() {
  return std::vector<uint8_t>(32, '\xee');
}

std::string GetClientDataHash() {
  return std::string(SHA256_DIGEST_LENGTH, 0xcd);
}

// // AAGUID for none attestation.
std::vector<uint8_t> GetAaguid() {
  return std::vector<uint8_t>{0x84, 0x03, 0x98, 0x77, 0xa5, 0x4b, 0xdf, 0xbb,
                              0x04, 0xa8, 0x2d, 0xf2, 0xfa, 0x2a, 0x11, 0x6e};
}

std::vector<uint8_t> GetCredId() {
  return std::vector<uint8_t>(64, 0xFD);
}

std::vector<uint8_t> GetVersionedCredId() {
  return std::vector<uint8_t>(145, 0xFD);
}

std::string GetCredIdString() {
  auto cred_id = GetCredId();
  return std::string(cred_id.begin(), cred_id.end());
}

std::string GetVersionedCredIdString() {
  auto cred_id = GetVersionedCredId();
  return std::string(cred_id.begin(), cred_id.end());
}

CredentialPublicKey GetCredPubKey() {
  return CredentialPublicKey{
      .cbor = std::vector<uint8_t>(65, 0xAB),
      .raw = std::vector<uint8_t>(65, 0xAB),
  };
}

std::vector<uint8_t> GetSignature() {
  return *util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                    kU2fSignResponse.sig_s);
}

brillo::SecureBlob ArrayToSecureBlob(const char* array) {
  brillo::SecureBlob blob;
  CHECK(brillo::SecureBlob::HexStringToSecureBlob(array, &blob));
  return blob;
}

brillo::Blob HexArrayToBlob(const char* array) {
  brillo::Blob blob;
  CHECK(base::HexStringToBytes(array, &blob));
  return blob;
}

}  // namespace

// TODO(b/205813697): Add tests for generic TPM flow.
// The base test fixture tests behaviors seen by general consumers. It
// disallows presence-only mode, because U2F isn't offered to general
// consumers.
class WebAuthnHandlerTestBase : public ::testing::Test {
 public:
  void SetUp() override {
    PrepareMockBus();
    CreateHandler(U2fMode::kDisabled, /*allowlisting_util=*/nullptr);
    PrepareMockStorage();
    // We use per-credential secret instead of the old user secret.
    ExpectNoGetUserSecret();
  }

 protected:
  void PrepareMockBus() {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    mock_bus_ = new dbus::MockBus(options);

    mock_auth_dialog_proxy_ = new dbus::MockObjectProxy(
        mock_bus_.get(), chromeos::kUserAuthenticationServiceName,
        dbus::ObjectPath(chromeos::kUserAuthenticationServicePath));

    // Set an expectation so that the MockBus will return our mock proxy.
    EXPECT_CALL(*mock_bus_,
                GetObjectProxy(
                    chromeos::kUserAuthenticationServiceName,
                    dbus::ObjectPath(chromeos::kUserAuthenticationServicePath)))
        .WillOnce(Return(mock_auth_dialog_proxy_.get()));
  }

  void CreateHandler(U2fMode u2f_mode,
                     std::unique_ptr<AllowlistingUtil> allowlisting_util) {
    handler_ = std::make_unique<WebAuthnHandler>();
    PrepareMockCryptohome();
    auto mock_processor = std::make_unique<MockU2fCommandProcessor>();
    mock_processor_ = mock_processor.get();
    handler_->Initialize(mock_bus_.get(), &mock_user_state_, u2f_mode,
                         std::move(mock_processor),
                         std::move(allowlisting_util), &mock_metrics_);
  }

  void PrepareMockCryptohome() {
    auto mock_cryptohome_proxy =
        std::make_unique<org::chromium::UserDataAuthInterfaceProxyMock>();
    mock_cryptohome_proxy_ = mock_cryptohome_proxy.get();
    handler_->SetCryptohomeInterfaceProxyForTesting(
        std::move(mock_cryptohome_proxy));
  }

  void PrepareMockStorage() {
    auto mock_storage = std::make_unique<MockWebAuthnStorage>();
    mock_webauthn_storage_ = mock_storage.get();
    handler_->SetWebAuthnStorageForTesting(std::move(mock_storage));
    mock_webauthn_storage_->set_allow_access(true);
  }

  void ExpectUVFlowSuccess() {
    mock_auth_dialog_response_ = dbus::Response::CreateEmpty();
    dbus::Response* response = mock_auth_dialog_response_.get();
    dbus::MessageWriter writer(response);
    writer.AppendBool(true);
    EXPECT_CALL(*mock_auth_dialog_proxy_, DoCallMethod(_, _, _))
        .WillOnce(
            [response](Unused, Unused,
                       base::OnceCallback<void(dbus::Response*)>* callback) {
              std::move(*callback).Run(response);
            });
  }

  void ExpectNoGetUserSecret() {
    EXPECT_CALL(mock_user_state_, GetUserSecret()).Times(0);
  }

  void ExpectGetUserSecret() { ExpectGetUserSecretForTimes(1); }

  void ExpectGetUserSecretForTimes(int times) {
    EXPECT_CALL(mock_user_state_, GetUserSecret())
        .Times(times)
        .WillRepeatedly(Return(ArrayToSecureBlob(kUserSecret)));
  }

  void ExpectGetCounter() {
    static const std::vector<uint8_t> kSignatureCounter({42, 23, 42, 23});
    EXPECT_CALL(mock_user_state_, GetCounter())
        .WillOnce(Return(kSignatureCounter));
  }

  void ExpectIncrementCounter() {
    EXPECT_CALL(mock_user_state_, IncrementCounter()).WillOnce(Return(true));
  }

  std::vector<uint8_t> MakeAuthenticatorData(
      const std::vector<uint8_t>& credential_id,
      const std::vector<uint8_t>& credential_public_key,
      bool user_verified,
      bool include_attested_credential_data,
      bool is_u2f_authenticator_credential) {
    std::optional<std::vector<uint8_t>> authenticator_data =
        handler_->MakeAuthenticatorData(
            GetRpIdHash(), credential_id, credential_public_key, user_verified,
            include_attested_credential_data, is_u2f_authenticator_credential);
    DCHECK(authenticator_data);
    return *authenticator_data;
  }

  // Set up an auth-time secret hash as if a user has logged in.
  void SetUpAuthTimeSecretHash() {
    handler_->auth_time_secret_hash_ =
        std::make_unique<brillo::Blob>(GetAuthTimeSecretHash());
  }

  StrictMock<MockUserState> mock_user_state_;

  std::unique_ptr<WebAuthnHandler> handler_;
  MockWebAuthnStorage* mock_webauthn_storage_;
  MockU2fCommandProcessor* mock_processor_;

 private:
  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockObjectProxy> mock_auth_dialog_proxy_;
  std::unique_ptr<dbus::Response> mock_auth_dialog_response_;
  org::chromium::UserDataAuthInterfaceProxyMock* mock_cryptohome_proxy_;
  testing::NiceMock<MetricsLibraryMock> mock_metrics_;
};

namespace {

TEST_F(WebAuthnHandlerTestBase, MakeCredentialUninitialized) {
  // Use an uninitialized WebAuthnHandler object.
  handler_.reset(new WebAuthnHandler());
  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::INTERNAL_ERROR);
        *called_ptr = true;
      },
      &called));

  MakeCredentialRequest request;
  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, MakeCredentialEmptyRpId) {
  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::INVALID_REQUEST);
        *called_ptr = true;
      },
      &called));

  MakeCredentialRequest request;
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);
  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, MakeCredentialNoAuthTimeSecretHash) {
  MakeCredentialRequest request;
  request.set_rp_id(kRpId);
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  ExpectUVFlowSuccess();
  EXPECT_CALL(*mock_processor_,
              U2fGenerate(GetRpIdHash(), _, PresenceRequirement::kNone, true,
                          nullptr, _, _, _))
      .WillRepeatedly(Return(MakeCredentialResponse::INTERNAL_ERROR));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::INTERNAL_ERROR);
        *called_ptr = true;
      },
      &called));

  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, MakeCredentialUPUpgradedToUV) {
  MakeCredentialRequest request;
  request.set_rp_id(kRpId);
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  // Though it's going to be UV, we will still check if any exclude credential
  // matches legacy credentials.
  ExpectGetUserSecret();
  ExpectUVFlowSuccess();
  SetUpAuthTimeSecretHash();
  EXPECT_CALL(*mock_processor_,
              U2fGenerate(GetRpIdHash(), _, PresenceRequirement::kNone, true,
                          Pointee(GetAuthTimeSecretHash()), _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(GetVersionedCredId()),
                      SetArgPointee<6>(GetCredPubKey()),
                      Return(MakeCredentialResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  handler_->MakeCredential(std::move(mock_method_response), request);
}

TEST_F(WebAuthnHandlerTestBase, MakeCredentialVerificationSuccess) {
  MakeCredentialRequest request;
  request.set_rp_id(kRpId);
  request.set_verification_type(
      VerificationType::VERIFICATION_USER_VERIFICATION);

  // Thought it's going to be UV, we will still check if any exclude credential
  // matches legacy credentials.
  ExpectGetUserSecret();
  ExpectUVFlowSuccess();

  SetUpAuthTimeSecretHash();
  EXPECT_CALL(*mock_processor_,
              U2fGenerate(GetRpIdHash(), _, PresenceRequirement::kNone, true,
                          Pointee(GetAuthTimeSecretHash()), _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(GetVersionedCredId()),
                      SetArgPointee<6>(GetCredPubKey()),
                      Return(MakeCredentialResponse::SUCCESS)));
  // TODO(yichengli): Specify the parameter to WriteRecord.
  EXPECT_CALL(*mock_webauthn_storage_, WriteRecord(_)).WillOnce(Return(true));

  auto rp_id_hash = GetRpIdHash();
  auto aaguid = GetAaguid();

  const std::string expected_authenticator_data_regex =
      base::HexEncode(rp_id_hash.data(),
                      rp_id_hash.size()) +  // RP ID hash
      std::string(
          "45"          // Flag: user present, user verified, attested
                        // credential data included.
          "(..){4}") +  // Signature counter
      base::HexEncode(aaguid.data(), aaguid.size()) +  // AAGUID
      std::string(
          "0091"      // Credential ID length
                      // Credential ID, from kU2fGenerateVersionedResponse:
          "(FD){65}"  // Versioned key handle header
          "(FD){16}"  // Authorization salt
          "(FD){32}"  // Hash of authorization secret
          "(FD){32}"  // Authorization hmac
                      // CBOR encoded credential public key:
          "(AB){65}");

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const std::string& expected_authenticator_data,
         const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::SUCCESS);
        EXPECT_THAT(base::HexEncode(resp.authenticator_data().data(),
                                    resp.authenticator_data().size()),
                    MatchesRegex(expected_authenticator_data));
        EXPECT_EQ(resp.attestation_format(), "none");
        EXPECT_EQ(resp.attestation_statement(), "\xa0");
        *called_ptr = true;
      },
      &called, expected_authenticator_data_regex));

  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, GetAssertionUninitialized) {
  // Use an uninitialized WebAuthnHandler object.
  handler_.reset(new WebAuthnHandler());
  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::INTERNAL_ERROR);
        *called_ptr = true;
      },
      &called));

  GetAssertionRequest request;
  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, GetAssertionEmptyRpId) {
  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::INVALID_REQUEST);
        *called_ptr = true;
      },
      &called));

  GetAssertionRequest request;
  request.set_client_data_hash(GetClientDataHash());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);
  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, GetAssertionWrongClientDataHashLength) {
  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::INVALID_REQUEST);
        *called_ptr = true;
      },
      &called));

  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(std::string(SHA256_DIGEST_LENGTH - 1, 0xcd));
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);
  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

// Simulates the case where the KH doesn't match any record in daemon-store, or
// any legacy credential id.
TEST_F(WebAuthnHandlerTestBase, GetAssertionNoCredentialSecret) {
  GetAssertionRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kWrongRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetCredIdString());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillOnce(Return(false));
  ExpectGetUserSecret();

  // We will check for legacy credentials, so two check-only calls to TPM.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .Times(2)
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::UNKNOWN_CREDENTIAL_ID);
        *called_ptr = true;
      },
      &called));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

// Simulates the case where the KH matches a record in daemon-store but is not
// recognized by cr50. This is not very likely in reality unless daemon-store is
// compromised.
TEST_F(WebAuthnHandlerTestBase, GetAssertionInvalidKeyHandle) {
  GetAssertionRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kWrongRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetCredIdString());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillOnce(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                      Return(true)));
  ExpectGetUserSecret();
  // 3 calls to SignCheckOnly, one for each credential type.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(), _, _))
      .Times(3)
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::UNKNOWN_CREDENTIAL_ID);
        *called_ptr = true;
      },
      &called));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, GetAssertionUPUpgradedToUV) {
  // Needed for "InsertAuthTimeSecretHash" workaround.
  SetUpAuthTimeSecretHash();

  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetVersionedCredIdString());

  request.set_verification_type(
      VerificationType::VERIFICATION_USER_VERIFICATION);

  // Pass DoU2fSignCheckOnly so that we can get to UV flow.
  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                            Return(true)));
  ExpectGetUserSecret();

  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillRepeatedly(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(_, GetVersionedCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetVersionedCredId(),
                      HexArrayToBlob(kCredentialSecret), _,
                      PresenceRequirement::kAuthorizationSecret, _))
      .WillOnce(Return(GetAssertionResponse::SUCCESS));

  ExpectUVFlowSuccess();

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  handler_->GetAssertion(std::move(mock_method_response), request);
}

TEST_F(WebAuthnHandlerTestBase, GetAssertionVerificationSuccess) {
  // Needed for "InsertAuthTimeSecretHash" workaround.
  SetUpAuthTimeSecretHash();

  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());

  request.add_allowed_credential_id(GetVersionedCredIdString());

  request.set_verification_type(
      VerificationType::VERIFICATION_USER_VERIFICATION);

  ExpectUVFlowSuccess();

  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                            Return(true)));

  ExpectGetUserSecret();

  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillRepeatedly(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(_, GetVersionedCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetVersionedCredId(),
                      HexArrayToBlob(kCredentialSecret), _,
                      PresenceRequirement::kAuthorizationSecret, _))
      .WillOnce(DoAll(SetArgPointee<6>(GetSignature()),
                      Return(GetAssertionResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const std::string& expected_credential_id,
         const GetAssertionResponse& resp) {
        auto rp_id_hash = GetRpIdHash();
        EXPECT_EQ(resp.status(), GetAssertionResponse::SUCCESS);
        ASSERT_EQ(resp.assertion_size(), 1);
        auto assertion = resp.assertion(0);
        EXPECT_EQ(assertion.credential_id(), expected_credential_id);
        EXPECT_THAT(
            base::HexEncode(assertion.authenticator_data().data(),
                            assertion.authenticator_data().size()),
            MatchesRegex(base::HexEncode(rp_id_hash.data(),
                                         rp_id_hash.size()) +  // RP ID hash
                         std::string("05"  // Flag: user present, user verified
                                     "(..){4}")));  // Signature counter
        EXPECT_EQ(util::ToVector(assertion.signature()),
                  util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                            kU2fSignResponse.sig_s));
        *called_ptr = true;
      },
      &called, GetVersionedCredIdString()));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestBase, HasCredentialsNoMatch) {
  HasCredentialsRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kWrongRpId);
  request.add_credential_id(GetCredIdString());
  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillRepeatedly(Return(false));
  ExpectGetUserSecret();

  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .Times(2)
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto resp = handler_->HasCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 0);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID);
}

// Match first of the 3 types of credentials, i.e. a credential generated by the
// platform authenticator with a versioned key handle.
TEST_F(WebAuthnHandlerTestBase, HasCredentialsMatchPlatformAuthenticator) {
  HasCredentialsRequest request;
  request.set_rp_id(kRpId);
  request.set_app_id(kRpId);
  request.add_credential_id(GetVersionedCredIdString());

  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillOnce(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                      Return(true)));
  ExpectGetUserSecret();

  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               GetCorrectUserSecret(), _))
      .Times(2)
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto resp = handler_->HasCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

// Match second of the 3 types of credentials: a legacy u2f credential created
// by WebAuthnHandler, scoped to an RP ID.
TEST_F(WebAuthnHandlerTestBase, HasCredentialsMatchU2fhidWebAuthn) {
  HasCredentialsRequest request;
  request.set_rp_id(kRpId);
  request.add_credential_id(GetCredIdString());

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillOnce(Return(false));
  ExpectGetUserSecret();
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));

  auto resp = handler_->HasCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

// Match third of the 3 types of credentials: a legacy credential created by
// u2fhid, scoped to an App ID.
TEST_F(WebAuthnHandlerTestBase, HasCredentialsMatchAppId) {
  HasCredentialsRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kRpId);
  request.add_credential_id(GetCredIdString());

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillOnce(Return(false));
  ExpectGetUserSecret();
  // Matching rp_id fails.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  // Matching app_id succeeds.
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));

  auto resp = handler_->HasCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

TEST_F(WebAuthnHandlerTestBase, HasCredentialsSomeMatches) {
  // Test that HasCredentials with a mix of correct and wrong length credential
  // IDs succeeds.
  HasCredentialsRequest request;
  request.set_rp_id(kRpId);
  request.set_app_id(kRpId);
  request.add_credential_id(GetVersionedCredIdString());
  std::vector<uint8_t> unknown_credential_id(U2F_V0_KH_SIZE + 1, 0xab);
  std::string unknown_credential_id_string(unknown_credential_id.begin(),
                                           unknown_credential_id.end());
  request.add_credential_id(unknown_credential_id_string);

  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillOnce(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                      Return(true)));
  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           unknown_credential_id_string, _, _))
      .WillOnce(Return(false));
  ExpectGetUserSecret();

  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), unknown_credential_id,
                               GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto resp = handler_->HasCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.credential_id()[0], GetVersionedCredIdString());
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

TEST_F(WebAuthnHandlerTestBase, HasLegacyCredentialsNoMatch) {
  HasCredentialsRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kWrongRpId);
  request.add_credential_id(GetCredIdString());

  ExpectGetUserSecret();
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .Times(2)
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto resp = handler_->HasLegacyCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 0);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID);
}

// Match second of the 3 types of credentials.
// If rp_id matches, it's a legacy credential registered with u2fhid on WebAuthn
// API.
TEST_F(WebAuthnHandlerTestBase, HasLegacyCredentialsMatchU2fhidWebAuthn) {
  HasCredentialsRequest request;
  request.set_rp_id(kRpId);
  request.add_credential_id(GetCredIdString());

  ExpectGetUserSecret();
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));

  auto resp = handler_->HasLegacyCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

// Match third of the 3 types of credentials.
// If app_id matches, it's a legacy credential registered with U2F API.
TEST_F(WebAuthnHandlerTestBase, HasLegacyCredentialsMatchAppId) {
  HasCredentialsRequest request;
  request.set_rp_id(kWrongRpId);
  request.set_app_id(kRpId);
  request.add_credential_id(GetCredIdString());

  ExpectGetUserSecret();
  // Matching rp_id fails.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  // Matching app_id succeeds.
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));

  auto resp = handler_->HasLegacyCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

TEST_F(WebAuthnHandlerTestBase, HasLegacyCredentialsSomeMatches) {
  // Test that HasLegacyCredentials with a mix of correct and wrong length
  // credential IDs succeeds.
  HasCredentialsRequest request;
  request.set_rp_id(kRpId);
  request.set_app_id(kRpId);
  request.add_credential_id(GetCredIdString());
  std::vector<uint8_t> unknown_credential_id(U2F_V0_KH_SIZE + 1, 0xab);
  std::string unknown_credential_id_string(unknown_credential_id.begin(),
                                           unknown_credential_id.end());
  request.add_credential_id(unknown_credential_id_string);

  ExpectGetUserSecret();
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), unknown_credential_id,
                               GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));

  auto resp = handler_->HasLegacyCredentials(request);
  EXPECT_EQ(resp.credential_id_size(), 1);
  EXPECT_EQ(resp.credential_id()[0], GetCredIdString());
  EXPECT_EQ(resp.status(), HasCredentialsResponse::SUCCESS);
}

TEST_F(WebAuthnHandlerTestBase, MakeAuthenticatorDataWithAttestedCredData) {
  const std::vector<uint8_t> cred_id(64, 0xAA);
  const std::vector<uint8_t> cred_pubkey(65, 0xBB);

  std::vector<uint8_t> authenticator_data =
      MakeAuthenticatorData(cred_id, cred_pubkey, /* user_verified = */
                            false,
                            /* include_attested_credential_data = */ true,
                            /* is_u2f_authenticator_credential = */ false);
  EXPECT_EQ(authenticator_data.size(),
            kRpIdHashBytes + kAuthenticatorDataFlagBytes +
                kSignatureCounterBytes + kAaguidBytes +
                kCredentialIdLengthBytes + cred_id.size() + cred_pubkey.size());
  auto rp_id_hash = GetRpIdHash();
  auto aaguid = GetAaguid();
  const std::string rp_id_hash_hex =
      base::HexEncode(rp_id_hash.data(), rp_id_hash.size());
  const std::string expected_authenticator_data_regex =
      rp_id_hash_hex +  // RP ID hash
      std::string(
          "41"          // Flag: user present, attested credential data included
          "(..){4}") +  // Signature counter
      base::HexEncode(aaguid.data(), aaguid.size()) +  // AAGUID
      std::string(
          "0040"        // Credential ID length
          "(AA){64}"    // Credential ID
          "(BB){65}");  // Credential public key
  EXPECT_THAT(
      base::HexEncode(authenticator_data.data(), authenticator_data.size()),
      MatchesRegex(expected_authenticator_data_regex));
}

TEST_F(WebAuthnHandlerTestBase, MakeAuthenticatorDataNoAttestedCredData) {
  std::vector<uint8_t> authenticator_data =
      MakeAuthenticatorData(std::vector<uint8_t>(), std::vector<uint8_t>(),
                            /* user_verified = */ false,
                            /* include_attested_credential_data = */ false,
                            /* is_u2f_authenticator_credential = */ false);
  EXPECT_EQ(
      authenticator_data.size(),
      kRpIdHashBytes + kAuthenticatorDataFlagBytes + kSignatureCounterBytes);
  auto rp_id_hash = GetRpIdHash();
  const std::string rp_id_hash_hex =
      base::HexEncode(rp_id_hash.data(), rp_id_hash.size());
  const std::string expected_authenticator_data_regex =
      rp_id_hash_hex +  // RP ID hash
      std::string(
          "01"         // Flag: user present
          "(..){4}");  // Signature counter
  EXPECT_THAT(
      base::HexEncode(authenticator_data.data(), authenticator_data.size()),
      MatchesRegex(expected_authenticator_data_regex));
}

TEST_F(WebAuthnHandlerTestBase,
       MakeAuthenticatorDataU2fAuthenticatorCredential) {
  // For U2F authenticator credentials only, the counter comes from UserState.
  ExpectGetCounter();
  ExpectIncrementCounter();

  std::vector<uint8_t> authenticator_data =
      MakeAuthenticatorData(std::vector<uint8_t>(), std::vector<uint8_t>(),
                            /* user_verified = */ false,
                            /* include_attested_credential_data = */ false,
                            /* is_u2f_authenticator_credential = */ true);

  EXPECT_EQ(
      base::HexEncode(authenticator_data),
      base::HexEncode(GetRpIdHash()) +
          std::string("01"           // Flag: user present
                      "2A172A17"));  // kSignatureCounter in network byte order
}

TEST_F(WebAuthnHandlerTestBase, GetAlgorithms) {
  GetAlgorithmsRequest request;
  EXPECT_CALL(*mock_processor_, GetAlgorithm())
      .WillOnce(Return(CoseAlgorithmIdentifier::kEs256));

  auto resp = handler_->GetAlgorithms(request);
  ASSERT_EQ(resp.algorithm_size(), 1);
  EXPECT_EQ(resp.algorithm(0),
            static_cast<int32_t>(CoseAlgorithmIdentifier::kEs256));
  EXPECT_EQ(resp.status(), GetAlgorithmsResponse::SUCCESS);
}

}  // namespace

// This test fixture tests the behavior when u2f is enabled on the device.
class WebAuthnHandlerTestU2fMode : public WebAuthnHandlerTestBase {
 public:
  void SetUp() override {
    PrepareMockBus();
    CreateHandler(U2fMode::kU2f, /*allowlisting_util=*/nullptr);
    PrepareMockStorage();
  }
};

namespace {

TEST_F(WebAuthnHandlerTestU2fMode, MakeCredentialPresenceSuccess) {
  MakeCredentialRequest request;
  request.set_rp_id(kRpId);
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  ExpectGetCounter();
  ExpectIncrementCounter();

  // 1. LegacyCredential uses "user secret" instead of per credential secret.
  // 2. We will still check if any exclude credential matches legacy
  // credentials.
  ExpectGetUserSecretForTimes(2);
  SetUpAuthTimeSecretHash();
  EXPECT_CALL(*mock_processor_,
              U2fGenerate(GetRpIdHash(), GetCorrectUserSecret(),
                          PresenceRequirement::kPowerButton, false,
                          Pointee(GetAuthTimeSecretHash()), _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(GetCredId()),
                      SetArgPointee<6>(GetCredPubKey()),
                      Return(MakeCredentialResponse::SUCCESS)));

  // Since this creates a legacy credential with legacy secret, we won't write
  // to storage.
  EXPECT_CALL(*mock_webauthn_storage_, WriteRecord(_)).Times(0);

  const std::string expected_authenticator_data_regex =
      base::HexEncode(GetRpIdHash()) +
      std::string(
          "41"        // Flag: user present, attested credential data included
          "2A172A17"  // kSignatureCounter in network byte order
          "(00){16}"  // AAGUID
          "0040"      // Credential ID length
                      // Credential ID, from kU2fGenerateResponse:
          "(FD){64}"  // (non-versioned) key handle
                      // CBOR encoded credential public key:
          "(AB){65}");

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const std::string& expected_authenticator_data,
         const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::SUCCESS);
        EXPECT_THAT(base::HexEncode(resp.authenticator_data().data(),
                                    resp.authenticator_data().size()),
                    MatchesRegex(expected_authenticator_data));
        EXPECT_EQ(resp.attestation_format(), "fido-u2f");
        const std::string expected_attestation_statement =
            "A2"      // Start a CBOR map of 2 elements
            "63"      // Start CBOR text of 3 chars
            "736967"  // "sig"
            ".+"      // Random signature
            "63"      // Start CBOR text of 3 chars
            "783563"  // "x5c"
            "81"      // Start CBOR array of 1 element
            ".+";     // Random x509
        EXPECT_THAT(base::HexEncode(resp.attestation_statement().data(),
                                    resp.attestation_statement().size()),
                    MatchesRegex(expected_attestation_statement));
        *called_ptr = true;
      },
      &called, expected_authenticator_data_regex));

  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestU2fMode, GetAssertionSignLegacyCredentialNoPresence) {
  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetCredIdString());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  ExpectGetCounter();
  ExpectIncrementCounter();

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .Times(2)
      .WillRepeatedly(Return(false));
  // LegacyCredential uses "user secret" instead of per credential secret.
  ExpectGetUserSecretForTimes(2);

  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetCredId(), GetCorrectUserSecret(), _,
                      PresenceRequirement::kPowerButton, _))
      .WillOnce(Return(GetAssertionResponse::VERIFICATION_FAILED));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::VERIFICATION_FAILED);
        *called_ptr = true;
      },
      &called));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestU2fMode, GetAssertionSignLegacyCredentialSuccess) {
  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetCredIdString());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  ExpectGetCounter();
  ExpectIncrementCounter();

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .Times(2)
      .WillRepeatedly(Return(false));
  // LegacyCredential uses "user secret" instead of per credential secret.
  ExpectGetUserSecretForTimes(2);
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetCredId(), GetCorrectUserSecret(), _,
                      PresenceRequirement::kPowerButton, _))
      .WillOnce(DoAll(SetArgPointee<6>(GetSignature()),
                      Return(GetAssertionResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::SUCCESS);
        ASSERT_EQ(resp.assertion_size(), 1);
        auto assertion = resp.assertion(0);
        EXPECT_EQ(assertion.credential_id(), GetCredIdString());
        EXPECT_EQ(
            base::HexEncode(assertion.authenticator_data().data(),
                            assertion.authenticator_data().size()),
            base::HexEncode(GetRpIdHash()) +
                std::string(
                    "01"           // Flag: user present
                    "2A172A17"));  // kSignatureCounter in network byte order
        EXPECT_EQ(util::ToVector(assertion.signature()),
                  util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                            kU2fSignResponse.sig_s));
        *called_ptr = true;
      },
      &called));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestU2fMode, GetAssertionSignLegacyCredentialAppIdMatch) {
  GetAssertionRequest request;
  request.set_rp_id(kWrongRpId);
  // Legacy credentials registered via U2F interface use the app id.
  request.set_app_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());
  request.add_allowed_credential_id(GetCredIdString());
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);

  ExpectGetCounter();
  ExpectIncrementCounter();

  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .Times(2)
      .WillRepeatedly(Return(false));
  // LegacyCredential uses "user secret" instead of per credential secret.
  ExpectGetUserSecretForTimes(2);

  // Rp id doesn't match.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetWrongRpIdHash(), GetCredId(),
                               GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  // App id matches.
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetCredId(), GetCorrectUserSecret(), _,
                      PresenceRequirement::kPowerButton, _))
      .WillOnce(DoAll(SetArgPointee<6>(GetSignature()),
                      Return(GetAssertionResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const GetAssertionResponse& resp) {
        EXPECT_EQ(resp.status(), GetAssertionResponse::SUCCESS);
        ASSERT_EQ(resp.assertion_size(), 1);
        auto assertion = resp.assertion(0);
        EXPECT_EQ(assertion.credential_id(), GetCredIdString());
        EXPECT_EQ(
            base::HexEncode(assertion.authenticator_data().data(),
                            assertion.authenticator_data().size()),
            base::HexEncode(GetRpIdHash()) +
                std::string(
                    "01"           // Flag: user present
                    "2A172A17"));  // kSignatureCounter in network byte order
        EXPECT_EQ(util::ToVector(assertion.signature()),
                  util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                            kU2fSignResponse.sig_s));
        *called_ptr = true;
      },
      &called));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestU2fMode,
       GetAssertionSignVersionedCredentialInUVMode) {
  // Needed for "InsertAuthTimeSecretHash" workaround.
  SetUpAuthTimeSecretHash();

  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());

  request.add_allowed_credential_id(GetVersionedCredIdString());

  request.set_verification_type(
      VerificationType::VERIFICATION_USER_VERIFICATION);

  ExpectUVFlowSuccess();

  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                            Return(true)));
  ExpectGetUserSecret();
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(_, GetVersionedCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetVersionedCredId(),
                      HexArrayToBlob(kCredentialSecret), _,
                      PresenceRequirement::kAuthorizationSecret, _))
      .WillOnce(DoAll(SetArgPointee<6>(GetSignature()),
                      Return(GetAssertionResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const std::string& expected_credential_id,
         const GetAssertionResponse& resp) {
        auto rp_id_hash = GetRpIdHash();
        EXPECT_EQ(resp.status(), GetAssertionResponse::SUCCESS);
        ASSERT_EQ(resp.assertion_size(), 1);
        auto assertion = resp.assertion(0);
        EXPECT_EQ(assertion.credential_id(), expected_credential_id);
        EXPECT_THAT(
            base::HexEncode(assertion.authenticator_data().data(),
                            assertion.authenticator_data().size()),
            MatchesRegex(base::HexEncode(rp_id_hash.data(),
                                         rp_id_hash.size()) +  // RP ID hash
                         std::string("05"  // Flag: user present, user verified
                                     "(..){4}")));  // Signature counter
        EXPECT_EQ(util::ToVector(assertion.signature()),
                  util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                            kU2fSignResponse.sig_s));
        *called_ptr = true;
      },
      &called, GetVersionedCredIdString()));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

TEST_F(WebAuthnHandlerTestU2fMode,
       GetAssertionWithTwoTypesOfAllowedCredentials) {
  // Needed for "InsertAuthTimeSecretHash" workaround.
  SetUpAuthTimeSecretHash();

  GetAssertionRequest request;
  request.set_rp_id(kRpId);
  request.set_client_data_hash(GetClientDataHash());
  // Add a U2F credential to the allow list first.
  request.add_allowed_credential_id(GetCredIdString());
  // Add a platform credential (second type).
  request.add_allowed_credential_id(GetVersionedCredIdString());
  request.set_verification_type(
      VerificationType::VERIFICATION_USER_VERIFICATION);

  ExpectUVFlowSuccess();

  EXPECT_CALL(*mock_webauthn_storage_, GetSecretAndKeyBlobByCredentialId(
                                           GetVersionedCredIdString(), _, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(HexArrayToBlob(kCredentialSecret)),
                            Return(true)));
  EXPECT_CALL(*mock_webauthn_storage_,
              GetSecretAndKeyBlobByCredentialId(GetCredIdString(), _, _))
      .WillRepeatedly(Return(false));
  ExpectGetUserSecret();
  // Both credentials should pass U2fSignCheckOnly, but only the platform
  // credential should go through U2fSign.
  EXPECT_CALL(*mock_processor_,
              U2fSignCheckOnly(GetRpIdHash(), GetVersionedCredId(),
                               HexArrayToBlob(kCredentialSecret), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(_, GetVersionedCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillRepeatedly(Return(HasCredentialsResponse::UNKNOWN_CREDENTIAL_ID));
  EXPECT_CALL(*mock_processor_, U2fSignCheckOnly(GetRpIdHash(), GetCredId(),
                                                 GetCorrectUserSecret(), _))
      .WillOnce(Return(HasCredentialsResponse::SUCCESS));

  EXPECT_CALL(*mock_processor_,
              U2fSign(GetRpIdHash(), _, GetVersionedCredId(),
                      HexArrayToBlob(kCredentialSecret), _,
                      PresenceRequirement::kAuthorizationSecret, _))
      .WillOnce(DoAll(SetArgPointee<6>(GetSignature()),
                      Return(GetAssertionResponse::SUCCESS)));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<GetAssertionResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const std::string& expected_credential_id,
         const GetAssertionResponse& resp) {
        auto rp_id_hash = GetRpIdHash();
        EXPECT_EQ(resp.status(), GetAssertionResponse::SUCCESS);
        ASSERT_EQ(resp.assertion_size(), 1);
        auto assertion = resp.assertion(0);
        EXPECT_EQ(assertion.credential_id(), expected_credential_id);
        EXPECT_THAT(
            base::HexEncode(assertion.authenticator_data().data(),
                            assertion.authenticator_data().size()),
            MatchesRegex(base::HexEncode(rp_id_hash.data(),
                                         rp_id_hash.size()) +  // RP ID hash
                         std::string("05"  // Flag: user present, user verified
                                     "(..){4}")));  // Signature counter
        EXPECT_EQ(util::ToVector(assertion.signature()),
                  util::SignatureToDerBytes(kU2fSignResponse.sig_r,
                                            kU2fSignResponse.sig_s));
        *called_ptr = true;
      },
      // The platform credential should appear in the assertion even though it
      // comes second in the allowed credential list.
      &called, GetVersionedCredIdString()));

  handler_->GetAssertion(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

}  // namespace

// This test fixture tests the behavior when g2f is enabled on the device.
class WebAuthnHandlerTestG2fMode : public WebAuthnHandlerTestU2fMode {
 public:
  void SetUp() override {
    PrepareMockBus();
    mock_allowlisting_util_ = new StrictMock<MockAllowlistingUtil>();
    CreateHandler(U2fMode::kU2fExtended,
                  std::unique_ptr<AllowlistingUtil>(mock_allowlisting_util_));
    PrepareMockStorage();
  }

 protected:
  StrictMock<MockAllowlistingUtil>* mock_allowlisting_util_;  // Not Owned.
};

namespace {

// Example of a cert that would be returned by cr50.
constexpr char kDummyG2fCert[] =
    "308201363081DDA0030201020210442D32429223D041240350303716EE6B300A06082A8648"
    "CE3D040302300F310D300B06035504031304637235303022180F3230303030313031303030"
    "3030305A180F32303939313233313233353935395A300F310D300B06035504031304637235"
    "303059301306072A8648CE3D020106082A8648CE3D030107034200045165719A9975F6FD30"
    "CC2516C22FE841F65F9D2EE7B8B72F76807AEBD8CA3376005C7FA86453E4B10DB7BFAD5D2B"
    "D00DB4A7C4845AD06D686ACD0252387618ECA31730153013060B2B0601040182E51C020101"
    "040403020308300A06082A8648CE3D0403020348003045022100F09976F373920FEF8205C4"
    "B1FB1DA21EB9F3F176B7DF433A1ADE0F3F38B721960220179D9B9051BFCCCC90BA6BB42B86"
    "111D7A9C4FB56DFD39FB426081DD027AD609";

std::vector<uint8_t> GetDummyG2fCert() {
  std::vector<uint8_t> cert;
  base::HexStringToBytes(kDummyG2fCert, &cert);
  return cert;
}

TEST_F(WebAuthnHandlerTestG2fMode, MakeCredentialPresenceSuccess) {
  MakeCredentialRequest request;
  request.set_rp_id(kRpId);
  request.set_verification_type(VerificationType::VERIFICATION_USER_PRESENCE);
  request.set_attestation_conveyance_preference(MakeCredentialRequest::G2F);

  ExpectGetCounter();
  ExpectIncrementCounter();

  // We will need user secret 3 times:
  // first time for u2f_generate (legacy credential),
  // second time for g2f attestation command,
  // third time for checking if any exclude credential matches legacy
  // credentials.
  ExpectGetUserSecretForTimes(3);
  SetUpAuthTimeSecretHash();
  EXPECT_CALL(*mock_processor_,
              U2fGenerate(GetRpIdHash(), _, PresenceRequirement::kPowerButton,
                          false, Pointee(GetAuthTimeSecretHash()), _, _, _))
      .WillOnce(DoAll(SetArgPointee<5>(GetCredId()),
                      SetArgPointee<6>(GetCredPubKey()),
                      Return(MakeCredentialResponse::SUCCESS)));

  // Since this creates a legacy credential with legacy secret, we won't write
  // to storage.
  EXPECT_CALL(*mock_webauthn_storage_, WriteRecord(_)).Times(0);

  // G2f attestation mock.
  EXPECT_CALL(*mock_processor_, GetG2fCert())
      .WillOnce(Return(GetDummyG2fCert()));
  EXPECT_CALL(*mock_processor_, G2fAttest(_, _, _, _))
      .WillOnce(Return(MakeCredentialResponse::SUCCESS));
  EXPECT_CALL(*mock_allowlisting_util_, AppendDataToCert(_))
      .WillOnce(Return(true));

  auto mock_method_response =
      std::make_unique<MockDBusMethodResponse<MakeCredentialResponse>>();
  bool called = false;
  mock_method_response->set_return_callback(base::BindRepeating(
      [](bool* called_ptr, const MakeCredentialResponse& resp) {
        EXPECT_EQ(resp.status(), MakeCredentialResponse::SUCCESS);
        EXPECT_EQ(resp.attestation_format(), "fido-u2f");
        const std::string expected_attestation_statement =
            "A2"      // Start a CBOR map of 2 elements
            "63"      // Start CBOR text of 3 chars
            "736967"  // "sig"
            ".+"      // Random signature
            "63"      // Start CBOR text of 3 chars
            "783563"  // "x5c"
            "81"      // Start CBOR array of 1 element
            ".+";     // Random x509
        EXPECT_THAT(base::HexEncode(resp.attestation_statement().data(),
                                    resp.attestation_statement().size()),
                    MatchesRegex(expected_attestation_statement));
        *called_ptr = true;
      },
      &called));

  handler_->MakeCredential(std::move(mock_method_response), request);
  ASSERT_TRUE(called);
}

}  // namespace
}  // namespace u2f
