Commit 870705b1 authored by Nina Satragno's avatar Nina Satragno Committed by Commit Bot

Adjust WebAuthn WebDriver API to match the spec

Now that the WebAuthn WebDriver API has landed on the spec [1], update
the implementation to match it closely:

* Add isUserVerified flag to AddVirtualAuthenticator
* hasResidentKey and hasUserVerification are optional and default to
  false.

[1] https://w3c.github.io/webauthn/#sctn-automation-add-virtual-authenticator

Bug: 922572
Change-Id: I884988c15e4a46ab5aad2395c76dca284386dc7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1837477Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Commit-Queue: Nina Satragno <nsatragno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702469}
parent 09e9a601
...@@ -628,7 +628,7 @@ class ChromeDriver(object): ...@@ -628,7 +628,7 @@ class ChromeDriver(object):
def AddVirtualAuthenticator(self, protocol=None, transport=None, def AddVirtualAuthenticator(self, protocol=None, transport=None,
hasResidentKey=None, hasUserVerification=None, hasResidentKey=None, hasUserVerification=None,
isUserVerified=None): isUserConsenting=None, isUserVerified=None):
options = {} options = {}
if protocol is not None: if protocol is not None:
options['protocol'] = protocol options['protocol'] = protocol
...@@ -638,6 +638,8 @@ class ChromeDriver(object): ...@@ -638,6 +638,8 @@ class ChromeDriver(object):
options['hasResidentKey'] = hasResidentKey options['hasResidentKey'] = hasResidentKey
if hasUserVerification is not None: if hasUserVerification is not None:
options['hasUserVerification'] = hasUserVerification options['hasUserVerification'] = hasUserVerification
if isUserConsenting is not None:
options['isUserConsenting'] = isUserConsenting
if isUserVerified is not None: if isUserVerified is not None:
options['isUserVerified'] = isUserVerified options['isUserVerified'] = isUserVerified
......
...@@ -745,8 +745,7 @@ HttpHandler::HttpHandler( ...@@ -745,8 +745,7 @@ HttpHandler::HttpHandler(
base::BindRepeating(&ExecuteSetNetworkConnection))), base::BindRepeating(&ExecuteSetNetworkConnection))),
// Extension for WebAuthn API: // Extension for WebAuthn API:
// TODO(nsatragno): Update the link to the official spec once it lands. // https://w3c.github.io/webauthn/#sctn-automation
// https://github.com/w3c/webauthn/pull/1256
CommandMapping(kPost, "session/:sessionId/webauthn/authenticator", CommandMapping(kPost, "session/:sessionId/webauthn/authenticator",
WrapToCommand("AddVirtualAuthenticator", WrapToCommand("AddVirtualAuthenticator",
base::BindRepeating( base::BindRepeating(
...@@ -760,7 +759,6 @@ HttpHandler::HttpHandler( ...@@ -760,7 +759,6 @@ HttpHandler::HttpHandler(
base::BindRepeating( base::BindRepeating(
&ExecuteWebAuthnCommand, &ExecuteWebAuthnCommand,
base::BindRepeating(&ExecuteRemoveVirtualAuthenticator)))), base::BindRepeating(&ExecuteRemoveVirtualAuthenticator)))),
CommandMapping( CommandMapping(
kPost, kPost,
"session/:sessionId/webauthn/authenticator/:authenticatorId/" "session/:sessionId/webauthn/authenticator/:authenticatorId/"
...@@ -801,6 +799,7 @@ HttpHandler::HttpHandler( ...@@ -801,6 +799,7 @@ HttpHandler::HttpHandler(
base::BindRepeating( base::BindRepeating(
&ExecuteWebAuthnCommand, &ExecuteWebAuthnCommand,
base::BindRepeating(&ExecuteSetUserVerified)))), base::BindRepeating(&ExecuteSetUserVerified)))),
// Extension for Permissions Standard Automation "set permission" command: // Extension for Permissions Standard Automation "set permission" command:
// https://w3c.github.io/permissions/#set-permission-command // https://w3c.github.io/permissions/#set-permission-command
CommandMapping(kPost, "session/:sessionId/permissions", CommandMapping(kPost, "session/:sessionId/permissions",
......
...@@ -2394,6 +2394,23 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer): ...@@ -2394,6 +2394,23 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
transport = 'usb', transport = 'usb',
hasResidentKey = False, hasResidentKey = False,
hasUserVerification = False, hasUserVerification = False,
isUserConsenting = True,
isUserVerified = True,
)
result = self._driver.ExecuteAsyncScript(script)
self.assertEquals('OK', result['status'])
self.assertEquals(['usb'], result['credential']['transports'])
def testAddVirtualAuthenticatorDefaultParams(self):
script = """
let done = arguments[0];
registerCredential().then(done);
"""
self._driver.Load(self.GetHttpsUrlForFile(
'/chromedriver/webauthn_test.html', 'chromedriver.test'))
self._driver.AddVirtualAuthenticator(
protocol = 'ctap2',
transport = 'usb',
) )
result = self._driver.ExecuteAsyncScript(script) result = self._driver.ExecuteAsyncScript(script)
self.assertEquals('OK', result['status']) self.assertEquals('OK', result['status'])
...@@ -2501,6 +2518,7 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer): ...@@ -2501,6 +2518,7 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
transport = 'usb', transport = 'usb',
hasResidentKey = True, hasResidentKey = True,
hasUserVerification = True, hasUserVerification = True,
isUserVerified = True,
)['authenticatorId'] )['authenticatorId']
# Register a credential via the webauthn API. # Register a credential via the webauthn API.
...@@ -2529,8 +2547,6 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer): ...@@ -2529,8 +2547,6 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
authenticatorId = self._driver.AddVirtualAuthenticator( authenticatorId = self._driver.AddVirtualAuthenticator(
protocol = 'ctap2', protocol = 'ctap2',
transport = 'usb', transport = 'usb',
hasResidentKey = True,
hasUserVerification = True,
)['authenticatorId'] )['authenticatorId']
# Register two credentials. # Register two credentials.
...@@ -2562,8 +2578,6 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer): ...@@ -2562,8 +2578,6 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
authenticatorId = self._driver.AddVirtualAuthenticator( authenticatorId = self._driver.AddVirtualAuthenticator(
protocol = 'ctap2', protocol = 'ctap2',
transport = 'usb', transport = 'usb',
hasResidentKey = True,
hasUserVerification = True,
)['authenticatorId'] )['authenticatorId']
# Register a credential via the webauthn API. # Register a credential via the webauthn API.
......
...@@ -110,7 +110,8 @@ Status ExecuteAddVirtualAuthenticator(WebView* web_view, ...@@ -110,7 +110,8 @@ Status ExecuteAddVirtualAuthenticator(WebView* web_view,
{"options.transport", "transport"}, {"options.transport", "transport"},
{"options.hasResidentKey", "hasResidentKey"}, {"options.hasResidentKey", "hasResidentKey"},
{"options.hasUserVerification", "hasUserVerification"}, {"options.hasUserVerification", "hasUserVerification"},
{"options.automaticPresenceSimulation", "isUserVerified"}, {"options.automaticPresenceSimulation", "isUserConsenting"},
{"options.isUserVerified", "isUserVerified"},
}, },
params), params),
value); value);
......
...@@ -152,12 +152,15 @@ Response WebAuthnHandler::AddVirtualAuthenticator( ...@@ -152,12 +152,15 @@ Response WebAuthnHandler::AddVirtualAuthenticator(
transport == device::FidoTransportProtocol::kInternal transport == device::FidoTransportProtocol::kInternal
? device::AuthenticatorAttachment::kPlatform ? device::AuthenticatorAttachment::kPlatform
: device::AuthenticatorAttachment::kCrossPlatform, : device::AuthenticatorAttachment::kCrossPlatform,
options->GetHasResidentKey(), options->GetHasUserVerification()); options->GetHasResidentKey(false /* default */),
options->GetHasUserVerification(false /* default */));
if (!authenticator) if (!authenticator)
return Response::Error(kErrorCreatingAuthenticator); return Response::Error(kErrorCreatingAuthenticator);
authenticator->SetUserPresence( authenticator->SetUserPresence(
options->GetAutomaticPresenceSimulation(true /* default */)); options->GetAutomaticPresenceSimulation(true /* default */));
authenticator->set_user_verified(
options->GetIsUserVerified(false /* default */));
*out_authenticator_id = authenticator->unique_id(); *out_authenticator_id = authenticator->unique_id();
return Response::OK(); return Response::OK();
......
...@@ -7307,11 +7307,16 @@ experimental domain WebAuthn ...@@ -7307,11 +7307,16 @@ experimental domain WebAuthn
properties properties
AuthenticatorProtocol protocol AuthenticatorProtocol protocol
AuthenticatorTransport transport AuthenticatorTransport transport
boolean hasResidentKey # Defaults to false.
boolean hasUserVerification optional boolean hasResidentKey
# Defaults to false.
optional boolean hasUserVerification
# If set to true, tests of user presence will succeed immediately. # If set to true, tests of user presence will succeed immediately.
# Otherwise, they will not be resolved. Defaults to true. # Otherwise, they will not be resolved. Defaults to true.
optional boolean automaticPresenceSimulation optional boolean automaticPresenceSimulation
# Sets whether User Verification succeeds or fails for an authenticator.
# Defaults to false.
optional boolean isUserVerified
type Credential extends object type Credential extends object
properties properties
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
transport: "usb", transport: "usb",
hasResidentKey: true, hasResidentKey: true,
hasUserVerification: true, hasUserVerification: true,
isUserVerified: true,
}, },
})).result.authenticatorId; })).result.authenticatorId;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
transport: "usb", transport: "usb",
hasResidentKey: true, hasResidentKey: true,
hasUserVerification: true, hasUserVerification: true,
isUserVerified: true,
}, },
})).result.authenticatorId; })).result.authenticatorId;
......
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