Skip to content

Commit

Permalink
fido: Implement GetAlgorithms for cros authenticator
Browse files Browse the repository at this point in the history
Currently the cros authenticator doesn't override GetAlgorithms, which
results in no checking of whether the server's supported public key
algorithms and the platform's have any intersection. Call the u2fd API
GetAlgorithms when initializing the authenticator to fetch the supported
algorithms.

Bug: b:221180579
Test: CQ
Test: manually ensure that "This device" option results in an
unsupported warning when performing WebAuthn with TPM 1.2 device on a
site that only supports ECC key (http://screen/9CQNJZuynpWwaAz.png)

Change-Id: Iafc236678779fdc97f4ffcefeb080dc2b163c5c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3515626
Reviewed-by: Adam Langley <agl@chromium.org>
Commit-Queue: Howard Yang <hcyang@google.com>
Cr-Commit-Position: refs/heads/main@{#984667}
  • Loading branch information
hcyang-google authored and Chromium LUCI CQ committed Mar 24, 2022
1 parent 70f12b6 commit 3eac174
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 0 deletions.
6 changes: 6 additions & 0 deletions chromeos/dbus/u2f/fake_u2f_client.cc
Expand Up @@ -80,4 +80,10 @@ void FakeU2FClient::CancelWebAuthnFlow(
NOTREACHED();
}

void FakeU2FClient::GetAlgorithms(
const u2f::GetAlgorithmsRequest& request,
DBusMethodCallback<u2f::GetAlgorithmsResponse> callback) {
NOTREACHED();
}

} // namespace chromeos
3 changes: 3 additions & 0 deletions chromeos/dbus/u2f/fake_u2f_client.h
Expand Up @@ -46,6 +46,9 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_U2F) FakeU2FClient : public U2FClient {
void CancelWebAuthnFlow(
const u2f::CancelWebAuthnFlowRequest& request,
DBusMethodCallback<u2f::CancelWebAuthnFlowResponse> callback) override;
void GetAlgorithms(
const u2f::GetAlgorithmsRequest& request,
DBusMethodCallback<u2f::GetAlgorithmsResponse> callback) override;
};

} // namespace chromeos
Expand Down
15 changes: 15 additions & 0 deletions chromeos/dbus/u2f/u2f_client.cc
Expand Up @@ -116,6 +116,9 @@ class U2FClientImpl : public U2FClient {
void CancelWebAuthnFlow(
const u2f::CancelWebAuthnFlowRequest& request,
DBusMethodCallback<u2f::CancelWebAuthnFlowResponse> callback) override;
void GetAlgorithms(
const u2f::GetAlgorithmsRequest& request,
DBusMethodCallback<u2f::GetAlgorithmsResponse> callback) override;

private:
dbus::ObjectProxy* proxy_ = nullptr;
Expand Down Expand Up @@ -303,6 +306,18 @@ void U2FClientImpl::CancelWebAuthnFlow(
weak_factory_.GetWeakPtr(), std::move(callback)));
}

void U2FClientImpl::GetAlgorithms(
const u2f::GetAlgorithmsRequest& request,
DBusMethodCallback<u2f::GetAlgorithmsResponse> callback) {
dbus::MethodCall method_call(u2f::kU2FInterface, u2f::kU2FGetAlgorithms);
dbus::MessageWriter writer(&method_call);
writer.AppendProtoAsArrayOfBytes(request);
proxy_->CallMethod(
&method_call, kU2FShortTimeout,
base::BindOnce(&U2FClientImpl::HandleResponse<u2f::GetAlgorithmsResponse>,
weak_factory_.GetWeakPtr(), std::move(callback)));
}

} // namespace

U2FClient::U2FClient() {
Expand Down
4 changes: 4 additions & 0 deletions chromeos/dbus/u2f/u2f_client.h
Expand Up @@ -102,6 +102,10 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_U2F) U2FClient {
const u2f::CancelWebAuthnFlowRequest& request,
DBusMethodCallback<u2f::CancelWebAuthnFlowResponse> callback) = 0;

virtual void GetAlgorithms(
const u2f::GetAlgorithmsRequest& request,
DBusMethodCallback<u2f::GetAlgorithmsResponse> callback) = 0;

protected:
U2FClient();
virtual ~U2FClient();
Expand Down
31 changes: 31 additions & 0 deletions device/fido/cros/authenticator.cc
Expand Up @@ -9,6 +9,7 @@
#include "device/fido/cros/authenticator.h"

#include "base/bind.h"
#include "base/containers/span.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/dbus/u2f/u2f_client.h"
Expand Down Expand Up @@ -68,9 +69,39 @@ ChromeOSAuthenticator::AuthenticatorTransport() const {

void ChromeOSAuthenticator::InitializeAuthenticator(
base::OnceClosure callback) {
u2f::GetAlgorithmsRequest request;
chromeos::U2FClient::Get()->GetAlgorithms(
request, base::BindOnce(&ChromeOSAuthenticator::OnGetAlgorithmsResponse,
weak_factory_.GetWeakPtr(), std::move(callback)));
}

void ChromeOSAuthenticator::OnGetAlgorithmsResponse(
base::OnceClosure callback,
absl::optional<u2f::GetAlgorithmsResponse> response) {
if (response && response->status() ==
u2f::GetAlgorithmsResponse_GetAlgorithmsStatus_SUCCESS) {
supported_algorithms_ = std::vector<int32_t>();
for (int i = 0; i < response->algorithm_size(); i++) {
supported_algorithms_->push_back(response->algorithm(i));
}
} else {
// Keep `supported_algorithms_` as nullopt if fetching supported algorithms
// from u2fd failed, since the caller of `GetAlgorithms` method might want
// to provide defaults.
supported_algorithms_ = absl::nullopt;
}

std::move(callback).Run();
}

absl::optional<base::span<const int32_t>>
ChromeOSAuthenticator::GetAlgorithms() {
if (supported_algorithms_) {
return base::span<const int32_t>(*supported_algorithms_);
}
return absl::nullopt;
}

void ChromeOSAuthenticator::MakeCredential(
CtapMakeCredentialRequest request,
MakeCredentialOptions request_options,
Expand Down
14 changes: 14 additions & 0 deletions device/fido/cros/authenticator.h
Expand Up @@ -8,6 +8,7 @@
#include <string>

#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/dbus/u2f/u2f_interface.pb.h"
#include "dbus/bus.h"
Expand Down Expand Up @@ -60,7 +61,14 @@ class COMPONENT_EXPORT(DEVICE_FIDO) ChromeOSAuthenticator
base::OnceCallback<void(bool is_enabled)> callback);

// FidoAuthenticator

// Calls the u2fd API `GetAlgorithms` and cache the result.
void InitializeAuthenticator(base::OnceClosure callback) override;

// Since this method is synchronous, it will simply return the GetAlgorithms
// result obtained during `InitializeAuthenticator`.
absl::optional<base::span<const int32_t>> GetAlgorithms() override;

void MakeCredential(CtapMakeCredentialRequest request,
MakeCredentialOptions request_options,
MakeCredentialCallback callback) override;
Expand All @@ -84,6 +92,11 @@ class COMPONENT_EXPORT(DEVICE_FIDO) ChromeOSAuthenticator
base::WeakPtr<FidoAuthenticator> GetWeakPtr() override;

private:
// Cache the supported algorithms in response, and run the completion callback
// of `InitializeAuthenticator`.
void OnGetAlgorithmsResponse(
base::OnceClosure callback,
absl::optional<u2f::GetAlgorithmsResponse> response);
void OnMakeCredentialResponse(
CtapMakeCredentialRequest request,
MakeCredentialCallback callback,
Expand All @@ -104,6 +117,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) ChromeOSAuthenticator
// Callback to set request_id in the window property.
base::RepeatingCallback<uint32_t()> generate_request_id_callback_;
const Config config_;
absl::optional<std::vector<int32_t>> supported_algorithms_;
base::WeakPtrFactory<ChromeOSAuthenticator> weak_factory_;
};

Expand Down

0 comments on commit 3eac174

Please sign in to comment.