Bug 1406468 - Web Authentication - Implement isUserVerifyingPlatformAuthenticatorAvailable() method r=jcj,smaug

Summary:
We currently implement no platform authenticators, so this would always
resolve to false. For those cases, the spec recommends a resolve timeout
on the order of 10 minutes to avoid fingerprinting.

A simple solution is thus to never resolve the promise, otherwise we'd
have to track every single call to this method along with a promise
and timer to resolve it after exactly X minutes.

A Relying Party has to deal with a non-response in a timely fashion, so
we can keep this as-is (and not resolve) even when we support platform
authenticators but they're not available, or a user rejects a website's
request to use them.

Reviewers: jcj, smaug

Reviewed By: jcj, smaug

Bug #: 1406468

Differential Revision: https://phabricator.services.mozilla.com/D217
This commit is contained in:
Tim Taubert 2017-11-14 11:44:46 +01:00
Родитель d1a9d0eb6d
Коммит ec80cf873c
4 изменённых файлов: 37 добавлений и 22 удалений

Просмотреть файл

@ -84,7 +84,7 @@ PublicKeyCredential::SetResponse(RefPtr<AuthenticatorResponse> aResponse)
}
/* static */ already_AddRefed<Promise>
PublicKeyCredential::IsPlatformAuthenticatorAvailable(GlobalObject& aGlobal)
PublicKeyCredential::IsUserVerifyingPlatformAuthenticatorAvailable(GlobalObject& aGlobal)
{
nsIGlobalObject* globalObject =
xpc::NativeGlobal(JS::CurrentGlobalOrNull(aGlobal.Context()));
@ -94,15 +94,24 @@ PublicKeyCredential::IsPlatformAuthenticatorAvailable(GlobalObject& aGlobal)
ErrorResult rv;
RefPtr<Promise> promise = Promise::Create(globalObject, rv);
if(rv.Failed()) {
if (rv.Failed()) {
return nullptr;
}
// Complete in Bug 1406468. This shouldn't just always return true, it should
// follow the guidelines in
// https://w3c.github.io/webauthn/#isPlatformAuthenticatorAvailable
// such as ensuring that U2FTokenManager isn't in some way disabled.
promise->MaybeResolve(true);
// https://w3c.github.io/webauthn/#isUserVerifyingPlatformAuthenticatorAvailable
//
// We currently implement no platform authenticators, so this would always
// resolve to false. For those cases, the spec recommends a resolve timeout
// on the order of 10 minutes to avoid fingerprinting.
//
// A simple solution is thus to never resolve the promise, otherwise we'd
// have to track every single call to this method along with a promise
// and timer to resolve it after exactly X minutes.
//
// A Relying Party has to deal with a non-response in a timely fashion, so
// we can keep this as-is (and not resolve) even when we support platform
// authenticators but they're not available, or a user rejects a website's
// request to use them.
return promise.forget();
}

Просмотреть файл

@ -47,7 +47,7 @@ public:
SetResponse(RefPtr<AuthenticatorResponse>);
static already_AddRefed<Promise>
IsPlatformAuthenticatorAvailable(GlobalObject& aGlobal);
IsUserVerifyingPlatformAuthenticatorAvailable(GlobalObject& aGlobal);
private:
CryptoBuffer mRawId;

Просмотреть файл

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>Test for W3C Web Authentication isPlatformAuthenticatorAvailable</title>
<title>Test for W3C Web Authentication isUserVerifyingPlatformAuthenticatorAvailable</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="u2futil.js"></script>
<script type="text/javascript" src="pkijs/common.js"></script>
@ -12,7 +12,7 @@
</head>
<body>
<h1>Test for W3C Web Authentication isPlatformAuthenticatorAvailable</h1>
<h1>Test for W3C Web Authentication isUserVerifyingPlatformAuthenticatorAvailable</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
@ -21,24 +21,29 @@
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
// Turn off all tokens. This should result in "not allowed" failures
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
["security.webauth.webauthn_enable_softtoken", true],
["security.webauth.webauthn_enable_usbtoken", false]]},
function() {
PublicKeyCredential.isPlatformAuthenticatorAvailable()
// This test ensures that isUserVerifyingPlatformAuthenticatorAvailable()
// is a callable method, but we currently can't test that it works in an
// automated way. If it resolves to false, per spec, we SHOULD wait
// ~10 minutes before resolving.
let p1 = PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
.then(function(aResult) {
// The specification requires this method, if will return false, to wait 10
// minutes for anti-fingerprinting reasons. So we really can't test that
// in an automated way.
ok(aResult, "Should be available!");
ok(false, "We shouldn't get here.");
})
.catch(function(aProblem) {
is(false, "Problem encountered: " + aProblem);
})
.then(function() {
ok(false, "Problem encountered: " + aProblem);
});
// Finish on the next tick.
let p2 = Promise.resolve();
Promise.race([p1, p2]).then(function() {
ok(true, "isUserVerifyingPlatformAuthenticatorAvailable() is callable");
SimpleTest.finish();
})
});
});
</script>

Просмотреть файл

@ -19,7 +19,7 @@ interface PublicKeyCredential : Credential {
[SecureContext]
partial interface PublicKeyCredential {
static Promise<boolean> isPlatformAuthenticatorAvailable();
static Promise<boolean> isUserVerifyingPlatformAuthenticatorAvailable();
};
[SecureContext, Pref="security.webauth.webauthn"]
@ -124,4 +124,5 @@ typedef long COSEAlgorithmIdentifier;
typedef sequence<AAGUID> AuthenticatorSelectionList;
typedef BufferSource AAGUID;
typedef BufferSource AAGUID;