Commit 1beb4c29 authored by Jun Choi's avatar Jun Choi Committed by Commit Bot

Plumb transport protocol from //device/fido to UI.

For all successful WebAuthN API transactions, notify observers of
FidoRequestHandler, then AuthenticatorRequestClientDelegate of which
transport protocol was used to talk to the authenticator that was used
to service the request.

This will be saved as Chromium preference, and used to infer which
transport type to default to when user invokes WebAuthN API again.

Bug: 847985
Change-Id: I9ecf27209ec959d740664e34fe088a2e4499e982
Reviewed-on: https://chromium-review.googlesource.com/1175500
Commit-Queue: Jun Choi <hongjunchoi@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583517}
parent dc7ac17b
...@@ -646,7 +646,8 @@ void AuthenticatorImpl::DidFinishNavigation( ...@@ -646,7 +646,8 @@ void AuthenticatorImpl::DidFinishNavigation(
// Callback to handle the async registration response from a U2fDevice. // Callback to handle the async registration response from a U2fDevice.
void AuthenticatorImpl::OnRegisterResponse( void AuthenticatorImpl::OnRegisterResponse(
device::FidoReturnCode status_code, device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorMakeCredentialResponse> response_data) { base::Optional<device::AuthenticatorMakeCredentialResponse> response_data,
device::FidoTransportProtocol transport_used) {
if (!request_) { if (!request_) {
// Either the callback was called immediately and |request_| has not yet // Either the callback was called immediately and |request_| has not yet
// been assigned (this is a bug), or a navigation caused the request to be // been assigned (this is a bug), or a navigation caused the request to be
...@@ -676,6 +677,7 @@ void AuthenticatorImpl::OnRegisterResponse( ...@@ -676,6 +677,7 @@ void AuthenticatorImpl::OnRegisterResponse(
return; return;
case device::FidoReturnCode::kSuccess: case device::FidoReturnCode::kSuccess:
DCHECK(response_data.has_value()); DCHECK(response_data.has_value());
request_delegate_->UpdateLastTransportUsed(transport_used);
if (attestation_preference_ != if (attestation_preference_ !=
blink::mojom::AttestationConveyancePreference::NONE) { blink::mojom::AttestationConveyancePreference::NONE) {
...@@ -752,7 +754,8 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided( ...@@ -752,7 +754,8 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
void AuthenticatorImpl::OnSignResponse( void AuthenticatorImpl::OnSignResponse(
device::FidoReturnCode status_code, device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorGetAssertionResponse> response_data) { base::Optional<device::AuthenticatorGetAssertionResponse> response_data,
device::FidoTransportProtocol transport_used) {
if (!request_) { if (!request_) {
// Either the callback was called immediately and |request_| has not yet // Either the callback was called immediately and |request_| has not yet
// been assigned (this is a bug), or a navigation caused the request to be // been assigned (this is a bug), or a navigation caused the request to be
...@@ -779,6 +782,8 @@ void AuthenticatorImpl::OnSignResponse( ...@@ -779,6 +782,8 @@ void AuthenticatorImpl::OnSignResponse(
return; return;
case device::FidoReturnCode::kSuccess: case device::FidoReturnCode::kSuccess:
DCHECK(response_data.has_value()); DCHECK(response_data.has_value());
request_delegate_->UpdateLastTransportUsed(transport_used);
base::Optional<bool> echo_appid_extension; base::Optional<bool> echo_appid_extension;
if (alternative_application_parameter_) { if (alternative_application_parameter_) {
echo_appid_extension = (response_data->GetRpIdHash() == echo_appid_extension = (response_data->GetRpIdHash() ==
......
...@@ -125,8 +125,8 @@ class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator, ...@@ -125,8 +125,8 @@ class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator,
// Callback to handle the async response from a U2fDevice. // Callback to handle the async response from a U2fDevice.
void OnRegisterResponse( void OnRegisterResponse(
device::FidoReturnCode status_code, device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorMakeCredentialResponse> base::Optional<device::AuthenticatorMakeCredentialResponse> response_data,
response_data); device::FidoTransportProtocol transport_used);
// Callback to complete the registration process once a decision about // Callback to complete the registration process once a decision about
// whether or not to return attestation data has been made. // whether or not to return attestation data has been made.
...@@ -137,7 +137,8 @@ class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator, ...@@ -137,7 +137,8 @@ class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator,
// Callback to handle the async response from a U2fDevice. // Callback to handle the async response from a U2fDevice.
void OnSignResponse( void OnSignResponse(
device::FidoReturnCode status_code, device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorGetAssertionResponse> response_data); base::Optional<device::AuthenticatorGetAssertionResponse> response_data,
device::FidoTransportProtocol transport_used);
// Runs when timer expires and cancels all issued requests to a U2fDevice. // Runs when timer expires and cancels all issued requests to a U2fDevice.
void OnTimeout(); void OnTimeout();
......
...@@ -27,7 +27,8 @@ class FidoRequestHandler : public FidoRequestHandlerBase { ...@@ -27,7 +27,8 @@ class FidoRequestHandler : public FidoRequestHandlerBase {
public: public:
using CompletionCallback = using CompletionCallback =
base::OnceCallback<void(FidoReturnCode status_code, base::OnceCallback<void(FidoReturnCode status_code,
base::Optional<Response> response_data)>; base::Optional<Response> response_data,
FidoTransportProtocol transport_used)>;
FidoRequestHandler(service_manager::Connector* connector, FidoRequestHandler(service_manager::Connector* connector,
const base::flat_set<FidoTransportProtocol>& transports, const base::flat_set<FidoTransportProtocol>& transports,
...@@ -78,7 +79,9 @@ class FidoRequestHandler : public FidoRequestHandlerBase { ...@@ -78,7 +79,9 @@ class FidoRequestHandler : public FidoRequestHandlerBase {
// Once response has been passed to the relying party, cancel all other on // Once response has been passed to the relying party, cancel all other on
// going requests. // going requests.
CancelOngoingTasks(authenticator->GetId()); CancelOngoingTasks(authenticator->GetId());
std::move(completion_callback_).Run(*return_code, std::move(response_data)); std::move(completion_callback_)
.Run(*return_code, std::move(response_data),
authenticator->AuthenticatorTransport());
} }
private: private:
......
...@@ -30,12 +30,14 @@ namespace { ...@@ -30,12 +30,14 @@ namespace {
using FakeTaskCallback = using FakeTaskCallback =
base::OnceCallback<void(CtapDeviceResponseCode status_code, base::OnceCallback<void(CtapDeviceResponseCode status_code,
base::Optional<std::vector<uint8_t>>)>; base::Optional<std::vector<uint8_t>>)>;
using FakeHandlerCallback = base::OnceCallback<void( using FakeHandlerCallback =
FidoReturnCode status_code, base::OnceCallback<void(FidoReturnCode status_code,
base::Optional<std::vector<uint8_t>> response_data)>; base::Optional<std::vector<uint8_t>> response_data,
FidoTransportProtocol)>;
using FakeHandlerCallbackReceiver = using FakeHandlerCallbackReceiver =
test::StatusAndValueCallbackReceiver<FidoReturnCode, test::StatusAndValuesCallbackReceiver<FidoReturnCode,
base::Optional<std::vector<uint8_t>>>; base::Optional<std::vector<uint8_t>>,
FidoTransportProtocol>;
enum class FakeTaskResponse : uint8_t { enum class FakeTaskResponse : uint8_t {
kSuccess = 0x00, kSuccess = 0x00,
......
...@@ -25,9 +25,10 @@ namespace device { ...@@ -25,9 +25,10 @@ namespace device {
namespace { namespace {
using TestGetAssertionRequestCallback = test::StatusAndValueCallbackReceiver< using TestGetAssertionRequestCallback = test::StatusAndValuesCallbackReceiver<
FidoReturnCode, FidoReturnCode,
base::Optional<AuthenticatorGetAssertionResponse>>; base::Optional<AuthenticatorGetAssertionResponse>,
FidoTransportProtocol>;
} // namespace } // namespace
...@@ -96,7 +97,7 @@ TEST_F(FidoGetAssertionHandlerTest, CtapRequestOnSingleDevice) { ...@@ -96,7 +97,7 @@ TEST_F(FidoGetAssertionHandlerTest, CtapRequestOnSingleDevice) {
get_assertion_callback().WaitForCallback(); get_assertion_callback().WaitForCallback();
EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status()); EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
EXPECT_TRUE(get_assertion_callback().value()); EXPECT_TRUE(get_assertion_callback().value<0>());
EXPECT_TRUE(request_handler->is_complete()); EXPECT_TRUE(request_handler->is_complete());
} }
...@@ -116,7 +117,7 @@ TEST_F(FidoGetAssertionHandlerTest, TestU2fSign) { ...@@ -116,7 +117,7 @@ TEST_F(FidoGetAssertionHandlerTest, TestU2fSign) {
discovery()->AddDevice(std::move(device)); discovery()->AddDevice(std::move(device));
scoped_task_environment_.FastForwardUntilNoTasksRemain(); scoped_task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status()); EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
EXPECT_TRUE(get_assertion_callback().value()); EXPECT_TRUE(get_assertion_callback().value<0>());
EXPECT_TRUE(request_handler->is_complete()); EXPECT_TRUE(request_handler->is_complete());
} }
...@@ -139,7 +140,7 @@ TEST_F(FidoGetAssertionHandlerTest, TestU2fSignWithoutCtapFlag) { ...@@ -139,7 +140,7 @@ TEST_F(FidoGetAssertionHandlerTest, TestU2fSignWithoutCtapFlag) {
discovery()->AddDevice(std::move(device)); discovery()->AddDevice(std::move(device));
scoped_task_environment_.FastForwardUntilNoTasksRemain(); scoped_task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status()); EXPECT_EQ(FidoReturnCode::kSuccess, get_assertion_callback().status());
EXPECT_TRUE(get_assertion_callback().value()); EXPECT_TRUE(get_assertion_callback().value<0>());
EXPECT_TRUE(request_handler->is_complete()); EXPECT_TRUE(request_handler->is_complete());
} }
......
...@@ -27,7 +27,8 @@ class AuthenticatorGetAssertionResponse; ...@@ -27,7 +27,8 @@ class AuthenticatorGetAssertionResponse;
using SignResponseCallback = using SignResponseCallback =
base::OnceCallback<void(FidoReturnCode, base::OnceCallback<void(FidoReturnCode,
base::Optional<AuthenticatorGetAssertionResponse>)>; base::Optional<AuthenticatorGetAssertionResponse>,
FidoTransportProtocol)>;
class COMPONENT_EXPORT(DEVICE_FIDO) GetAssertionRequestHandler class COMPONENT_EXPORT(DEVICE_FIDO) GetAssertionRequestHandler
: public FidoRequestHandler<AuthenticatorGetAssertionResponse> { : public FidoRequestHandler<AuthenticatorGetAssertionResponse> {
......
...@@ -30,9 +30,10 @@ namespace device { ...@@ -30,9 +30,10 @@ namespace device {
namespace { namespace {
using TestMakeCredentialRequestCallback = test::StatusAndValueCallbackReceiver< using TestMakeCredentialRequestCallback = test::StatusAndValuesCallbackReceiver<
FidoReturnCode, FidoReturnCode,
base::Optional<AuthenticatorMakeCredentialResponse>>; base::Optional<AuthenticatorMakeCredentialResponse>,
FidoTransportProtocol>;
} // namespace } // namespace
......
...@@ -27,8 +27,10 @@ namespace device { ...@@ -27,8 +27,10 @@ namespace device {
class FidoAuthenticator; class FidoAuthenticator;
class AuthenticatorMakeCredentialResponse; class AuthenticatorMakeCredentialResponse;
using RegisterResponseCallback = base::OnceCallback< using RegisterResponseCallback =
void(FidoReturnCode, base::Optional<AuthenticatorMakeCredentialResponse>)>; base::OnceCallback<void(FidoReturnCode,
base::Optional<AuthenticatorMakeCredentialResponse>,
FidoTransportProtocol)>;
class COMPONENT_EXPORT(DEVICE_FIDO) MakeCredentialRequestHandler class COMPONENT_EXPORT(DEVICE_FIDO) MakeCredentialRequestHandler
: public FidoRequestHandler<AuthenticatorMakeCredentialResponse> { : public FidoRequestHandler<AuthenticatorMakeCredentialResponse> {
......
...@@ -114,6 +114,20 @@ class StatusAndValueCallbackReceiver ...@@ -114,6 +114,20 @@ class StatusAndValueCallbackReceiver
} }
}; };
template <class Status, class... Values>
class StatusAndValuesCallbackReceiver
: public TestCallbackReceiver<Status, Values...> {
public:
const Status& status() const {
return std::get<0>(*TestCallbackReceiver<Status, Values...>::result());
}
template <size_t I>
const std::tuple_element_t<I, std::tuple<Values...>>& value() const {
return std::get<I + 1>(*TestCallbackReceiver<Status, Values...>::result());
}
};
} // namespace test } // namespace test
} // namespace device } // namespace device
......
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