// Copyright 2019 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef U2FD_WEBAUTHN_HANDLER_H_
#define U2FD_WEBAUTHN_HANDLER_H_

#include <functional>
#include <memory>
#include <optional>
#include <queue>
#include <string>
#include <vector>

#include <brillo/dbus/dbus_method_response.h>
#include <cryptohome/proto_bindings/UserDataAuth.pb.h>
#include <cryptohome/proto_bindings/rpc.pb.h>
#include <metrics/metrics_library.h>
#include <u2f/proto_bindings/u2f_interface.pb.h>
#include <user_data_auth-client/user_data_auth/dbus-proxies.h>

#include "u2fd/allowlisting_util.h"
#include "u2fd/client/user_state.h"
#include "u2fd/u2f_mode.h"
#include "u2fd/webauthn_storage.h"

namespace u2f {

class U2fCommandProcessor;

using MakeCredentialMethodResponse =
    brillo::dbus_utils::DBusMethodResponse<MakeCredentialResponse>;
using GetAssertionMethodResponse =
    brillo::dbus_utils::DBusMethodResponse<GetAssertionResponse>;
using IsUvpaaMethodResponse =
    brillo::dbus_utils::DBusMethodResponse<IsUvpaaResponse>;
using ::google::protobuf::RepeatedPtrField;

struct MakeCredentialSession {
  bool empty() { return !response; }
  uint64_t session_id;
  MakeCredentialRequest request;
  std::unique_ptr<MakeCredentialMethodResponse> response;
  bool canceled = false;
};

struct GetAssertionSession {
  bool empty() { return !response; }
  uint64_t session_id;
  GetAssertionRequest request;
  // The credential_id to send to the TPM. May be a resident credential.
  std::string credential_id;
  std::unique_ptr<GetAssertionMethodResponse> response;
  bool canceled = false;
};

struct MatchedCredentials {
  std::vector<std::string> platform_credentials;
  std::vector<std::string> global_legacy_credentials;
  std::vector<std::string> legacy_credentials_for_rp_id;
  std::vector<std::string> legacy_credentials_for_app_id;
  bool has_internal_error = false;
};

enum class PresenceRequirement {
  kNone,  // Does not require presence. Used only after user-verification in
          // MakeCredential.
  kPowerButton,  // Requires a power button press as indication of presence.
  kFingerprint,  // Requires the GPIO line from fingerprint MCU to be active.
  kAuthorizationSecret,  // Requires the correct authorization secret.
};

enum class CredentialSecretType {
  // Platform credentials' credential secrets are randomly generated during
  // MakeCredential, and persisted into WebAuthnStorage.
  kPlatformStored,
  // Legacy credentials' credential secret is the user secret stored in u2fd's
  // daemon directory. Therefore, each user has 1 unique user secret, shared by
  // all legacy credentials created by that user.
  kUserSecret,
  // To make the keys available outside user session, under some conditions (for
  // specific RPs only, or guarded by policy) we create keys just like legacy
  // credentials with kUserSecret type, but with a well-known value as the user
  // secret. These credentials are not bound to users and can be used from all
  // user sessions and guest sessions.
  kGlobalWellKnownSecret,
};

// COSE algorithm ID
// https://www.iana.org/assignments/cose/cose.xhtml#algorithms
enum class CoseAlgorithmIdentifier : int32_t {
  kEs256 = -7,
  kRs256 = -257,
};

// Implementation of the WebAuthn DBus API.
// More detailed documentation is available in u2f_interface.proto
class WebAuthnHandler {
 public:
  WebAuthnHandler();
  ~WebAuthnHandler();

  // Initializes WebAuthnHandler.
  // |bus| - DBus pointer.
  // |user_state| - pointer to a UserState instance, for requesting user secret.
  // Owned by U2fDaemon and should outlive WebAuthnHandler.
  // |u2f_mode| - whether u2f or g2f is enabled.
  // |u2f_command_processor| - processor for executing u2f commands.
  // |allowlisting_util| - utility to append allowlisting data to g2f certs.
  // |metrics| - pointer to metrics library object.
  // |enable_global_key| - whether creation/discovery of global keys (unbound to
  // user session) are enabled.
  void Initialize(dbus::Bus* bus,
                  UserState* user_state,
                  U2fMode u2f_mode,
                  std::unique_ptr<U2fCommandProcessor> u2f_command_processor,
                  std::unique_ptr<AllowlistingUtil> allowlisting_util,
                  MetricsLibraryInterface* metrics,
                  bool enable_global_key);

  // Called when session state changed. Loads/clears state for primary user.
  void OnSessionStarted(const std::string& account_id);
  void OnSessionStopped();

  // Generates a new credential.
  void MakeCredential(
      std::unique_ptr<MakeCredentialMethodResponse> method_response,
      const MakeCredentialRequest& request);

  // Signs a challenge from the relaying party.
  void GetAssertion(std::unique_ptr<GetAssertionMethodResponse> method_response,
                    const GetAssertionRequest& request);

  // Tests validity and/or presence of specified credentials, including u2fhid
  // credentials.
  HasCredentialsResponse HasCredentials(const HasCredentialsRequest& request);

  // Tests whether any credential were registered using the u2fhid (on either
  // WebAuthn API or U2F API).
  HasCredentialsResponse HasLegacyCredentials(
      const HasCredentialsRequest& request);

  // Dismisses user verification UI and abort the operation. This is expected to
  // be called by the browser only in UV operations, because UP operations
  // themselves will timeout after ~5 seconds.
  CancelWebAuthnFlowResponse Cancel(const CancelWebAuthnFlowRequest& request);

  // Checks whether the platform authenticator is initialized. Before
  // initialized, most operations will directly return an error.
  IsPlatformAuthenticatorInitializedResponse IsPlatformAuthenticatorInitialized(
      const IsPlatformAuthenticatorInitializedRequest& request);

  // Checks whether user-verifying platform authenticator is available.
  void IsUvpaa(std::unique_ptr<IsUvpaaMethodResponse> method_response,
               const IsUvpaaRequest& request);

  // Checks whether u2f is enabled (therefore power button mode is supported).
  IsU2fEnabledResponse IsU2fEnabled(const IsU2fEnabledRequest& request);

  // Count how many WebAuthn platform credentials are created within the
  // specified time range.
  CountCredentialsInTimeRangeResponse CountCredentialsInTimeRange(
      const CountCredentialsInTimeRangeRequest& request);

  // Delete all WebAuthn platform credentials created within the specified time
  // range.
  DeleteCredentialsInTimeRangeResponse DeleteCredentialsInTimeRange(
      const DeleteCredentialsInTimeRangeRequest& request);

  // Get the supported algorithms of the platform authenticator. Currently we
  // have no plan to support multiple algorithms on one platform so the response
  // will only contain one entry.
  GetAlgorithmsResponse GetAlgorithms(const GetAlgorithmsRequest& request);

  // Get the supported features of u2fd. currently it only contains whether
  // WebAuthn is enabled on Lacros. This is equivalent to whether the request_id
  // field in WebAuthn requests has changed to str type currently, which is
  // always true.
  GetSupportedFeaturesResponse GetSupportedFeatures(
      const GetSupportedFeaturesRequest& request);

  void SetWebAuthnStorageForTesting(std::unique_ptr<WebAuthnStorage> storage);

  void SetCryptohomeInterfaceProxyForTesting(
      std::unique_ptr<org::chromium::UserDataAuthInterfaceProxyInterface>
          cryptohome_proxy);

 private:
  friend class WebAuthnHandlerTestBase;
  friend class WebAuthnHandlerTestAllowUP;

  bool Initialized();

  // Fetches auth-time WebAuthn secret and keep the hash of it.
  void GetWebAuthnSecretHashAsync(const std::string& account_id);
  void OnGetWebAuthnSecretHashResp(
      const user_data_auth::GetWebAuthnSecretHashReply& reply);
  void OnGetWebAuthnSecretHashCallFailed(brillo::Error* error);

  // Callbacks invoked when UI completes user verification flow.
  void HandleUVFlowResultMakeCredential(dbus::Response* flow_response);
  void HandleUVFlowResultGetAssertion(dbus::Response* flow_response);

  // Proceeds for the current MakeCredential request, and responds to the
  // request with authenticator data. Called directly if the request is
  // user-presence only. Called on user verification success if the request is
  // user-verification.
  void DoMakeCredential(struct MakeCredentialSession session,
                        PresenceRequirement presence_requirement);

  // Find all matching credentials and return them in 3 categories (see struct
  // MatchedCredentials definition). If a legacy credential matches both rp_id
  // and app_id, it will only appear in "legacy_credentials_for_rp_id".
  MatchedCredentials FindMatchedCredentials(
      const RepeatedPtrField<std::string>& all_credentials,
      const std::string& rp_id,
      const std::string& app_id);

  // Called on user verification success if the request is user-verification.
  void DoGetAssertion(struct GetAssertionSession session,
                      PresenceRequirement presence_requirement,
                      CredentialSecretType secret_type);

  // Creates and returns authenticator data. |include_attested_credential_data|
  // should be set to true for MakeCredential, false for GetAssertion.
  std::optional<std::vector<uint8_t>> MakeAuthenticatorData(
      const std::vector<uint8_t>& rp_id_hash,
      const std::vector<uint8_t>& credential_id,
      const std::vector<uint8_t>& credential_public_key,
      bool user_verified,
      bool include_attested_credential_data,
      CredentialSecretType secret_type);

  // Appends a none attestation to |response|. Only used in MakeCredential.
  void AppendNoneAttestation(MakeCredentialResponse* response);

  // Creates and returns an U2F attestation statement, or nullopt if attestation
  // fails.
  std::optional<std::vector<uint8_t>> MakeFidoU2fAttestationStatement(
      const std::vector<uint8_t>& app_id,
      const std::vector<uint8_t>& challenge,
      const std::vector<uint8_t>& pub_key,
      const std::vector<uint8_t>& key_handle,
      const brillo::SecureBlob& credential_secret,
      const MakeCredentialRequest::AttestationConveyancePreference
          attestation_conveyance_preference);

  // Runs U2F_SIGN command with "check only" flag on each excluded credential
  // id. Returns true if one of them belongs to this device.
  HasCredentialsResponse::HasCredentialsStatus HasExcludedCredentials(
      const MakeCredentialRequest& request);

  // Checks whether the user with |account_id| has PIN set up.
  bool HasPin(const std::string& account_id);

  // Checks whether the user with |account_id| has fingerprint set up.
  bool HasFingerprint(const std::string& account_id);

  // Returns whether presence-only mode (power button mode) is allowed.
  bool AllowPresenceMode();

  UserState* user_state_ = nullptr;
  dbus::Bus* bus_ = nullptr;
  // Proxy to user authentication dialog in Ash. Used only in UV requests.
  dbus::ObjectProxy* auth_dialog_dbus_proxy_ = nullptr;

  std::unique_ptr<org::chromium::UserDataAuthInterfaceProxyInterface>
      cryptohome_proxy_;

  // Presence-only mode (power button mode) should only be allowed if u2f or
  // g2f is enabled for the device (it's a per-device policy). The mode also
  // determines the attestation to add to MakeCredential.
  U2fMode u2f_mode_;

  // Util to append allowlisting data to g2f certificates.
  std::unique_ptr<AllowlistingUtil> allowlisting_util_;

  // The MakeCredential session that's waiting on UI. There can only be one
  // such session. UP sessions should not use this since there can be multiple.
  std::optional<MakeCredentialSession> pending_uv_make_credential_session_;

  // The GetAssertion session that's waiting on UI. There can only be one
  // such session. UP sessions should not use this since there can be multiple.
  std::optional<GetAssertionSession> pending_uv_get_assertion_session_;

  // Hash of the per-user auth-time secret for WebAuthn.
  std::unique_ptr<brillo::Blob> auth_time_secret_hash_;

  // Storage for WebAuthn credential records.
  std::unique_ptr<WebAuthnStorage> webauthn_storage_;

  // Processor for u2f commands.
  std::unique_ptr<U2fCommandProcessor> u2f_command_processor_;

  MetricsLibraryInterface* metrics_;

  // Whether creation/discovery of global keys (unbound to user session) are
  // enabled.
  bool enable_global_key_;
};

}  // namespace u2f

#endif  // U2FD_WEBAUTHN_HANDLER_H_
