Commit 5ef19abc authored by Yicheng Li's avatar Yicheng Li Committed by Commit Bot

device/fido: Enable ChromeOSAuthenticator to check credentials

This enables ChromeOSAuthenticator to check whether non-resident
credentials in a CtapGetAssertionRequest belong to the ChromeOS
device. It also reports the result to the UI (embedder) so that the
embedder is happy to dispatch requests.

      isn't dispatched to ChromeOSAuthenticator, with no sensible
      blocking.

Bug: crbug:1115811, b:144861739, b:161396510
Test: Injected an infinite loop on u2fd side and verified GetAssertion
Change-Id: I21a4308db72d0ddcf590361f3367ebe31979c523
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2358029
Commit-Queue: Yicheng Li <yichengli@chromium.org>
Reviewed-by: default avatarMartin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#798433}
parent a5edcd5f
......@@ -36,6 +36,8 @@ base::string16 ChromeOSAuthenticator::GetDisplayName() const {
namespace {
constexpr int kHasCredentialsTimeoutMs = 3000;
AuthenticatorSupportedOptions ChromeOSAuthenticatorOptions() {
AuthenticatorSupportedOptions options;
options.is_platform_device = true;
......@@ -260,6 +262,50 @@ void ChromeOSAuthenticator::OnGetAssertionResp(CtapGetAssertionRequest request,
std::move(response));
}
bool ChromeOSAuthenticator::HasCredentialForGetAssertionRequest(
const CtapGetAssertionRequest& request) {
dbus::Bus::Options dbus_options;
dbus_options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus = new dbus::Bus(dbus_options);
dbus::ObjectProxy* u2f_proxy = bus->GetObjectProxy(
u2f::kU2FServiceName, dbus::ObjectPath(u2f::kU2FServicePath));
if (!u2f_proxy) {
FIDO_LOG(ERROR) << "Couldn't get u2f proxy";
return false;
}
u2f::HasCredentialsRequest req;
req.set_rp_id(request.rp_id);
for (const PublicKeyCredentialDescriptor& descriptor : request.allow_list) {
const std::vector<uint8_t>& id = descriptor.id();
req.add_credential_id(std::string(id.begin(), id.end()));
}
dbus::MethodCall method_call(u2f::kU2FInterface, u2f::kU2FHasCredentials);
dbus::MessageWriter writer(&method_call);
writer.AppendProtoAsArrayOfBytes(req);
std::unique_ptr<dbus::Response> dbus_response =
u2f_proxy->CallMethodAndBlock(&method_call, kHasCredentialsTimeoutMs);
if (!dbus_response) {
FIDO_LOG(ERROR) << "HasCredentials dbus call had no response or timed out";
return false;
}
dbus::MessageReader reader(dbus_response.get());
u2f::HasCredentialsResponse resp;
if (!reader.PopArrayOfBytesAsProto(&resp)) {
FIDO_LOG(ERROR) << "Failed to parse reply for call to HasCredentials";
return false;
}
return resp.status() ==
u2f::HasCredentialsResponse_HasCredentialsStatus_SUCCESS &&
resp.credential_id().size() > 0;
}
bool ChromeOSAuthenticator::IsInPairingMode() const {
return false;
}
......
......@@ -27,6 +27,9 @@ class COMPONENT_EXPORT(DEVICE_FIDO) ChromeOSAuthenticator
ChromeOSAuthenticator();
~ChromeOSAuthenticator() override;
bool HasCredentialForGetAssertionRequest(
const CtapGetAssertionRequest& request);
// FidoAuthenticator
void InitializeAuthenticator(base::OnceClosure callback) override;
void MakeCredential(CtapMakeCredentialRequest request,
......
......@@ -33,6 +33,10 @@
#include "device/fido/win/type_conversions.h"
#endif
#if defined(OS_CHROMEOS)
#include "device/fido/cros/authenticator.h"
#endif
namespace device {
namespace {
......@@ -374,6 +378,16 @@ void GetAssertionRequestHandler::AuthenticatorAdded(
}
#endif // defined(OS_MAC)
#if defined(OS_CHROMEOS)
// TODO(martinkr): Put this boolean in a ChromeOS equivalent of
// "has_recognized_mac_touch_id_credential".
if (authenticator->IsChromeOSAuthenticator()) {
transport_availability_info().has_recognized_mac_touch_id_credential =
static_cast<ChromeOSAuthenticator*>(authenticator)
->HasCredentialForGetAssertionRequest(request_);
}
#endif // defined(OS_CHROMEOS)
FidoRequestHandlerBase::AuthenticatorAdded(discovery, authenticator);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment