mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1435527 - Run to timeout from navigator.credentials.get() when PublicKeyCredentialRequestOptions.allowCredentials is empty r=jcj
Reviewers: jcj Reviewed By: jcj Bug #: 1435527 Differential Revision: https://phabricator.services.mozilla.com/D559 --HG-- extra : amend_source : 0a715d3667f6813d2d1911a46031e452ef300e32
This commit is contained in:
parent
90bbf4505c
commit
85569e86c1
@ -539,13 +539,6 @@ WebAuthnManager::GetAssertion(const PublicKeyCredentialRequestOptions& aOptions,
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// Note: we only support U2F-style authentication for now, so we effectively
|
||||
// require an AllowList.
|
||||
if (aOptions.mAllowCredentials.Length() < 1) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_NOT_ALLOWED_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsTArray<WebAuthnScopedCredential> allowList;
|
||||
for (const auto& s: aOptions.mAllowCredentials) {
|
||||
if (s.mType == PublicKeyCredentialType::Public_key) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>Tests for GetAssertion for W3C Web Authentication</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="text/javascript" src="u2futil.js"></script>
|
||||
<script type="text/javascript" src="pkijs/common.js"></script>
|
||||
<script type="text/javascript" src="pkijs/asn1.js"></script>
|
||||
@ -18,111 +19,140 @@
|
||||
<script class="testbody" type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
// Execute the full-scope test
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
|
||||
isnot(navigator.credentials, undefined, "Credential Management API endpoint must exist");
|
||||
isnot(navigator.credentials.create, undefined, "CredentialManagement create API endpoint must exist");
|
||||
isnot(navigator.credentials.get, undefined, "CredentialManagement get API endpoint must exist");
|
||||
|
||||
let credm = navigator.credentials;
|
||||
|
||||
let gAssertionChallenge = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(gAssertionChallenge);
|
||||
|
||||
let invalidCred = {type: "Magic", id: base64ToBytes("AAA=")};
|
||||
let unknownCred = {type: "public-key", id: base64ToBytes("AAA=")};
|
||||
|
||||
function arrivingHereIsBad(aResult) {
|
||||
ok(false, "Bad result! Received a: " + aResult);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function expectNotAllowedError(aResult) {
|
||||
ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError");
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function expectTypeError(aResult) {
|
||||
ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError");
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]]},
|
||||
runTests);
|
||||
function expectAbortError(aResult) {
|
||||
is(aResult.code, DOMException.ABORT_ERR, "Expecting an AbortError");
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
|
||||
isnot(navigator.credentials, undefined, "Credential Management API endpoint must exist");
|
||||
isnot(navigator.credentials.create, undefined, "CredentialManagement create API endpoint must exist");
|
||||
isnot(navigator.credentials.get, undefined, "CredentialManagement get API endpoint must exist");
|
||||
add_task(() => {
|
||||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", true],
|
||||
["security.webauth.webauthn_enable_usbtoken", false]
|
||||
]});
|
||||
});
|
||||
|
||||
let credm = navigator.credentials;
|
||||
|
||||
let gAssertionChallenge = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(gAssertionChallenge);
|
||||
|
||||
let invalidCred = {type: "Magic", id: base64ToBytes("AAA=")};
|
||||
let unknownCred = {type: "public-key", id: base64ToBytes("AAA=")};
|
||||
|
||||
var testFuncs = [
|
||||
function () {
|
||||
// Test basic good call, but without giving a credential so expect failures
|
||||
// this is OK by the standard, but not supported by U2F-backed authenticators
|
||||
// like the soft token in use here.
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
},
|
||||
function () {
|
||||
// Test with an unexpected option
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
unknownValue: "hi"
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
},
|
||||
function () {
|
||||
// Test with an invalid credential
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: [invalidCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectTypeError);
|
||||
},
|
||||
function () {
|
||||
// Test with an unknown credential
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: [unknownCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
},
|
||||
function () {
|
||||
// Test with an unexpected option and an invalid credential
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
unknownValue: "hi",
|
||||
allowCredentials: [invalidCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectTypeError);
|
||||
}
|
||||
];
|
||||
|
||||
var i = 0;
|
||||
var runNextTest = () => {
|
||||
if (i == testFuncs.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
testFuncs[i]().then(() => { runNextTest(); });
|
||||
i = i + 1;
|
||||
// Test basic good call, but without giving a credential so expect failures
|
||||
// this is OK by the standard, but not supported by U2F-backed authenticators
|
||||
// like the soft token in use here.
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge
|
||||
};
|
||||
runNextTest();
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
});
|
||||
|
||||
}
|
||||
// Test with an unexpected option
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
unknownValue: "hi"
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
});
|
||||
|
||||
// Test with an invalid credential
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: [invalidCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectTypeError);
|
||||
});
|
||||
|
||||
// Test with an unknown credential
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: [unknownCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
});
|
||||
|
||||
// Test with an unexpected option and an invalid credential
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
unknownValue: "hi",
|
||||
allowCredentials: [invalidCred]
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectTypeError);
|
||||
});
|
||||
|
||||
// Test with an empty credential list
|
||||
add_task(() => {
|
||||
let publicKeyCredentialRequestOptions = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: []
|
||||
};
|
||||
return credm.get({publicKey: publicKeyCredentialRequestOptions})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectNotAllowedError);
|
||||
});
|
||||
|
||||
add_task(() => {
|
||||
// Enable USB tokens.
|
||||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.webauth.webauthn", true],
|
||||
["security.webauth.webauthn_enable_softtoken", false],
|
||||
["security.webauth.webauthn_enable_usbtoken", true]
|
||||
]});
|
||||
});
|
||||
|
||||
// Test with an empty credential list
|
||||
add_task(async () => {
|
||||
let publicKey = {
|
||||
challenge: gAssertionChallenge,
|
||||
allowCredentials: []
|
||||
};
|
||||
|
||||
let ctrl = new AbortController();
|
||||
let request = credm.get({publicKey, signal: ctrl.signal})
|
||||
.then(arrivingHereIsBad)
|
||||
.catch(expectAbortError);
|
||||
|
||||
// Wait a tick for the statemachine to start.
|
||||
await Promise.resolve();
|
||||
|
||||
// The request should time out. We'll abort it here and will fail or
|
||||
// succeed upon resolution, when the error code is checked.
|
||||
ctrl.abort();
|
||||
await request;
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user