Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>W3C Web Authentication - Authenticator Transports</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="u2futil.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>W3C Web Authentication - Authenticator Transports</h1>
<script class="testbody" type="text/javascript">
"use strict";
add_task(async () => {
await addVirtualAuthenticator();
});
function arrivingHereIsGood(aResult) {
ok(true, "Good result! Received a: " + aResult);
}
function arrivingHereIsBad(aResult) {
ok(false, "Bad result! Received a: " + aResult);
}
function expectNotAllowedError(aResult) {
ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError, got " + aResult);
}
function expectInvalidStateError(aResult) {
ok(aResult.toString().startsWith("InvalidStateError"), "Expecting a InvalidStateError, got " + aResult);
}
// Store the credential and transports of the first successful make credential
// operation so we can use them to get assertions later.
let gCredential;
let gTransports;
// Start a new MakeCredential() request.
function requestMakeCredential(excludeCredentials) {
let publicKey = {
rp: {id: document.domain, name: "none"},
user: {id: new Uint8Array(), name: "none", displayName: "none"},
challenge: crypto.getRandomValues(new Uint8Array(16)),
timeout: 5000, // the minimum timeout is actually 15 seconds
pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
excludeCredentials
};
return navigator.credentials.create({publicKey});
}
// Start a new GetAssertion() request.
function requestGetAssertion(allowCredentials) {
let publicKey = {
challenge: crypto.getRandomValues(new Uint8Array(16)),
timeout: 5000, // the minimum timeout is actually 15 seconds
rpId: document.domain,
allowCredentials
};
return navigator.credentials.get({publicKey});
}
// Test make credential behavior.
add_task(async function test_make_credential() {
// Make a credential.
await requestMakeCredential([])
// Save the credential for later.
.then(res => {
gCredential = res.rawId;
gTransports = res.response.getTransports();
})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// gTransports should be "a sequence of zero or more unique DOMStrings in lexicographical order."
for (let i = 0; i < gTransports.length - 1; i++) {
if (gTransports[i] >= gTransports[i+1]) {
ok(false, "getTransports() should return a sorted list");
}
}
// Pass a random credential to exclude.
await requestMakeCredential([{
type: "public-key",
id: crypto.getRandomValues(new Uint8Array(16)),
transports: gTransports,
}]).then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Pass gCredential with transport=usb.
// The credential already exists, and the softoken consents to create,
// so the error is InvalidState and not NotAllowed.
await requestMakeCredential([{
type: "public-key",
id: gCredential,
transports: ["usb"],
}]).then(arrivingHereIsBad)
.catch(expectInvalidStateError);
// Pass gCredential with transport=nfc.
// The softoken pretends to support all transports.
// Also, as above, the credential exists and the token indicates consent.
await requestMakeCredential([{
type: "public-key",
id: gCredential,
transports: ["nfc"],
}]).then(arrivingHereIsBad)
.catch(expectInvalidStateError);
// Pass gCredential with an empty transports list.
// As above, the token indicates consent, so expect InvalidStateError.
await requestMakeCredential([{
type: "public-key",
id: gCredential,
transports: [],
}]).then(arrivingHereIsBad)
.catch(expectInvalidStateError);
});
// Test get assertion behavior.
add_task(async function test_get_assertion() {
// Request an assertion for gCredential.
await requestGetAssertion([{
type: "public-key",
id: gCredential,
transports: gTransports,
}]).then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Request an assertion for a random credential. This should be
// indistinguishable from the user denying consent for a known
// credential, so expect a NotAllowedError.
await requestGetAssertion([{
type: "public-key",
id: crypto.getRandomValues(new Uint8Array(16)),
transports: ["usb"],
}]).then(arrivingHereIsBad)
.catch(expectNotAllowedError);
// Request an assertion for gCredential with transport=nfc.
// The softoken pretends to support all transports.
await requestGetAssertion([{
type: "public-key",
id: gCredential,
transports: ["nfc"],
}]).then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
// Request an assertion for gCredential with an empty transports list.
await requestGetAssertion([{
type: "public-key",
id: gCredential,
transports: [],
}]).then(arrivingHereIsGood)
.catch(arrivingHereIsBad);
});
</script>
</body>
</html>