Commit 925a93d2 authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

webauthn: support CTAP 2.1 in Virtual Authenticator API

Also switch the default in WPTs back to CTAP 2.0 and have LargeBlob
tests enable 2.1 explicitly, since they were relying on it.

Bug: 1117630
Change-Id: Ib3e0fbfe1c1a5532f2246b98b3abfd6f2fcc7d4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2509030
Commit-Queue: Shengfa Lin <shengfa@google.com>
Reviewed-by: default avatarShengfa Lin <shengfa@google.com>
Reviewed-by: default avatarNina Satragno <nsatragno@chromium.org>
Auto-Submit: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#825049}
parent 25c8ab04
......@@ -3065,7 +3065,7 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
self._driver.Load(self.GetHttpsUrlForFile(
'/chromedriver/webauthn_test.html', 'chromedriver.test'))
self._driver.AddVirtualAuthenticator(
protocol = 'ctap2',
protocol = 'ctap2_1',
transport = 'usb',
hasResidentKey = True,
hasUserVerification = True,
......@@ -3078,6 +3078,23 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
self.assertEquals(['usb'], result['credential']['transports'])
self.assertEquals(True, result['extensions']['largeBlob']['supported'])
def testAddVirtualAuthenticatorProtocolVersion(self):
self._driver.Load(self.GetHttpsUrlForFile(
'/chromedriver/webauthn_test.html', 'chromedriver.test'))
for protocol in ['ctap1/u2f', 'ctap2', 'ctap2_1']:
authenticator_id = self._driver.AddVirtualAuthenticator(
protocol = protocol,
transport = 'usb',
)
self.assertTrue(len(authenticator_id) > 0)
self.assertRaisesRegexp(
chromedriver.UnsupportedOperation,
'INVALID is not a recognized protocol version',
self._driver.AddVirtualAuthenticator,
protocol = 'INVALID',
transport = 'usb')
def testAddVirtualBadExtensions(self):
self.assertRaisesRegexp(
chromedriver.InvalidArgument,
......@@ -3188,7 +3205,7 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
'/chromedriver/webauthn_test.html', 'chromedriver.test'))
authenticatorId = self._driver.AddVirtualAuthenticator(
protocol = 'ctap2',
protocol = 'ctap2_1',
transport = 'usb',
hasResidentKey = True,
hasUserVerification = True,
......@@ -3268,7 +3285,7 @@ class ChromeDriverSecureContextTest(ChromeDriverBaseTestWithWebServer):
self._driver.Load(self.GetHttpsUrlForFile(
'/chromedriver/webauthn_test.html', 'chromedriver.test'))
authenticatorId = self._driver.AddVirtualAuthenticator(
protocol = 'ctap2',
protocol = 'ctap2_1',
transport = 'usb',
hasResidentKey = True,
hasUserVerification = True,
......
......@@ -26,6 +26,8 @@ static constexpr char kDevToolsDidNotReturnExpectedValue[] =
"DevTools did not return the expected value";
static constexpr char kUnrecognizedExtension[] =
" is not a recognized extension";
static constexpr char kUnrecognizedProtocol[] =
" is not a recognized protocol version";
// Creates a base::DictionaryValue by cloning the parameters specified by
// |mapping| from |params|.
......@@ -136,17 +138,21 @@ Status ExecuteAddVirtualAuthenticator(WebView* web_view,
}
}
// Large blobs require CTAP 2.1. At the moment webdriver does not allow
// specifying the CTAP version. Since there is no other web visible
// difference between the versions until credProps is introduced, force the
// virtual authenticator to CTAP 2.1.
mapped_params.SetPath("options.ctap2Version", base::Value("ctap2_1"));
// The spec calls u2f "ctap1/u2f", convert the value here since devtools does
// not support slashes on enums.
std::string* protocol = mapped_params.FindStringPath("options.protocol");
if (protocol && *protocol == "ctap1/u2f")
*protocol = "u2f";
if (protocol) {
if (*protocol == "ctap1/u2f") {
*protocol = "u2f";
} else if (*protocol == "ctap2") {
mapped_params.SetPath("options.ctap2Version", base::Value("ctap2_0"));
} else if (*protocol == "ctap2_1") {
*protocol = "ctap2";
mapped_params.SetPath("options.ctap2Version", base::Value("ctap2_1"));
} else {
return Status(kUnsupportedOperation, *protocol + kUnrecognizedProtocol);
}
}
std::unique_ptr<base::Value> result;
Status status = web_view->SendCommandAndGetResult(
......
......@@ -70,7 +70,7 @@ standardSetup(function() {
},
}).runTest("navigator.credentials.create() with largeBlob.support set to required and not supported by authenticator", "NotAllowedError");
}, {
protocol: "ctap2",
protocol: "ctap2_1",
hasResidentKey: true,
hasUserVerification: true,
isUserVerified: true,
......
......@@ -73,7 +73,7 @@ standardSetup(function() {
assert_not_own_property(credential.getClientExtensionResults().largeBlob, "written");
}, "navigator.credentials.create() with largeBlob.support set to required and supported by authenticator");
}, {
protocol: "ctap2",
protocol: "ctap2_1",
hasResidentKey: true,
hasUserVerification: true,
isUserVerified: true,
......
......@@ -83,7 +83,7 @@ standardSetup(async function() {
assert_false(assertion.getClientExtensionResults().largeBlob.written);
}, "navigator.credentials.get() with largeBlob.write set without authenticator support");
}, {
protocol: "ctap2",
protocol: "ctap2_1",
hasResidentKey: true,
hasUserVerification: true,
isUserVerified: true,
......
......@@ -81,7 +81,7 @@ standardSetup(async function(authenticator) {
assert_not_own_property(assertion.getClientExtensionResults().largeBlob, "written");
}, "navigator.credentials.get() read and write blob");
}, {
protocol: "ctap2",
protocol: "ctap2_1",
hasResidentKey: true,
hasUserVerification: true,
extensions: ["largeBlob"],
......
......@@ -309,6 +309,11 @@
break;
case "ctap2":
mojoOptions.protocol = blink.test.mojom.ClientToAuthenticatorProtocol.CTAP2;
mojoOptions.ctap2Version = blink.test.mojom.Ctap2Version.CTAP2_0;
break;
case "ctap2_1":
mojoOptions.protocol = blink.test.mojom.ClientToAuthenticatorProtocol.CTAP2;
mojoOptions.ctap2Version = blink.test.mojom.Ctap2Version.CTAP2_1;
break;
default:
throw "Unknown protocol " + options.protocol;
......@@ -337,9 +342,6 @@
mojoOptions.hasUserVerification = options.hasUserVerification;
mojoOptions.hasLargeBlob = options.extensions.indexOf("largeBlob") !== -1;
mojoOptions.isUserPresent = options.isUserConsenting;
// Force CTAP 2.1 to support large blob. This does not have any impact on
// WPTs until credProps is tested on WPTs, at which point we'll expose this.
mojoOptions.ctap2Version = blink.test.mojom.Ctap2Version.CTAP2_1;
let authenticator = (await manager.createAuthenticator(mojoOptions)).authenticator;
await authenticator.setUserVerified(options.isUserVerified);
......
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