Bug 1329802 - WebAuthn Unit Tests: Add Unit Tests r=keeler

This uses the new mochitest "scheme" option from Bug 1286312. This cannot land
until after Bug 1286312 does.

For now, you can test locally by adding
  --setpref dom.securecontext.whitelist=mochi.test
to your command line, such as:

~/hg/mozilla-central/mach mochitest \
  --setpref dom.securecontext.whitelist=mochi.test ./dom/u2f/tests/

Updated:
Review fixes (thanks keeler!)

MozReview-Commit-ID: 7jTxF3Mrtcg

--HG--
extra : rebase_source : 72c24bdc028e440705598c694f3c4119d5304d83
This commit is contained in:
J.C. Jones 2017-01-09 13:28:02 -07:00
Родитель 2e850d0248
Коммит 0851d956ab
7 изменённых файлов: 697 добавлений и 0 удалений

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

@ -27,3 +27,18 @@ skip-if = !e10s
skip-if = !e10s
[test_appid_facet_subdomain.html]
skip-if = !e10s
[test_webauthn_loopback.html]
skip-if = !e10s
scheme = https
[test_webauthn_no_token.html]
skip-if = !e10s
scheme = https
[test_webauthn_make_credential.html]
skip-if = !e10s
scheme = https
[test_webauthn_get_assertion.html]
skip-if = !e10s
scheme = https
[test_webauthn_sameorigin.html]
skip-if = !e10s
scheme = https

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

@ -0,0 +1,91 @@
<!DOCTYPE html>
<meta charset=utf-8>
<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="u2futil.js"></script>
<script type="text/javascript" src="pkijs/common.js"></script>
<script type="text/javascript" src="pkijs/asn1.js"></script>
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>Tests for GetAssertion for W3C Web Authentication</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
"use strict";
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
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.w3c", true],
["security.webauth.u2f_enable_softtoken", true],
["security.webauth.u2f_enable_usbtoken", false]]},
function() {
isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
let authn = navigator.authentication;
let gAssertionChallenge = new Uint8Array(16);
window.crypto.getRandomValues(gAssertionChallenge);
let invalidCred = { type: "Magic", id: base64ToBytes("AAA=") };
let unknownCred = { type: "ScopedCred", id: base64ToBytes("AAA=") };
Promise.all([
// 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.
authn.getAssertion(gAssertionChallenge)
.then(arrivingHereIsBad)
.catch(expectNotAllowedError),
// Test with an unexpected option
authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
.then(arrivingHereIsBad)
.catch(expectNotAllowedError),
// Test with an invalid credential
authn.getAssertion(gAssertionChallenge, { allowList: [invalidCred] })
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with an unknown credential
authn.getAssertion(gAssertionChallenge, { allowList: [unknownCred] })
.then(arrivingHereIsBad)
.catch(expectNotAllowedError),
// Test with an unexpected option and an invalid credential
authn.getAssertion(gAssertionChallenge, { unknownValue: "hi" })
.then(arrivingHereIsBad)
.catch(expectNotAllowedError)
])
.then(function(){
SimpleTest.finish();
});
});
</script>
</body>
</html>

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

@ -0,0 +1,170 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>Full-run test for MakeCredential/GetAssertion for W3C Web Authentication</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>
<script type="text/javascript" src="pkijs/asn1.js"></script>
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>Full-run test for MakeCredential/GetAssertion for W3C Web Authentication</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
"use strict";
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.webauth.w3c", true],
["security.webauth.u2f_enable_softtoken", true],
["security.webauth.u2f_enable_usbtoken", false]]},
function() {
isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
let authn = navigator.authentication;
let gCredentialChallenge = new Uint8Array(16);
window.crypto.getRandomValues(gCredentialChallenge);
let gAssertionChallenge = new Uint8Array(16);
window.crypto.getRandomValues(gAssertionChallenge);
testMakeCredential();
function checkCredentialValid(aCredInfo) {
/* ScopedCredentialInfo
- Credential
-- ID: Key Handle buffer pulled from U2F Register() Response
-- Type: "ScopedCred"
- WebAuthnAttestation
-- Format: "u2f"
-- ClientData: serialized JSON
-- AuthenticatorData: RP ID Hash || U2F Sign() Response
-- Attestation: U2F Register() Response */
is(aCredInfo.credential.type, "ScopedCred", "Type is correct");
ok(aCredInfo.credential.id.length > 0, "Key ID exists");
is(aCredInfo.attestation.format, "u2f", "Format is correct");
is(aCredInfo.attestation.attestation[0], 0x05, "Reserved byte is correct");
ok(aCredInfo.attestation.authenticatorData.length > 0, "Authenticator data exists");
let clientData = JSON.parse(buffer2string(aCredInfo.attestation.clientData));
is(clientData.challenge, bytesToBase64UrlSafe(gCredentialChallenge), "Challenge is correct");
is(clientData.origin, window.location.origin, "Origin is correct");
is(clientData.hashAlg, "S256", "Hash algorithm is correct");
return decodeU2FRegistration(aCredInfo.attestation.attestation)
.then(function(u2fObj) {
aCredInfo.u2fReg = u2fObj;
return aCredInfo;
});
}
function checkAssertionAndSigValid(aPublicKey, aAssertion) {
/* WebAuthnAssertion
- Credential
-- ID: ID of Credential from AllowList that succeeded
-- Type: "ScopedCred"
- ClientData: serialized JSON
- AuthenticatorData: RP ID Hash || U2F Sign() Response
- Signature: U2F Sign() Response */
is(aAssertion.credential.type, "ScopedCred", "Type is correct");
ok(aAssertion.credential.id.length > 0, "Key ID exists");
ok(aAssertion.authenticatorData.length > 0, "Authenticator data exists");
let clientData = JSON.parse(buffer2string(aAssertion.clientData));
is(clientData.challenge, bytesToBase64UrlSafe(gAssertionChallenge), "Challenge is correct");
is(clientData.origin, window.location.origin, "Origin is correct");
is(clientData.hashAlg, "S256", "Hash algorithm is correct");
// Parse the signature data
if (aAssertion.signature[0] != 0x01) {
throw "User presence byte not set";
}
let presenceAndCounter = aAssertion.signature.slice(0,5);
let signatureValue = aAssertion.signature.slice(5);
let rpIdHash = aAssertion.authenticatorData.slice(0,32);
// Assemble the signed data and verify the signature
return deriveAppAndChallengeParam(clientData.origin, aAssertion.clientData)
.then(function(aParams) {
console.log(aParams.appParam, rpIdHash, presenceAndCounter, aParams.challengeParam);
console.log("ClientData buffer: ", hexEncode(aAssertion.clientData));
console.log("ClientDataHash: ", hexEncode(aParams.challengeParam));
return assembleSignedData(aParams.appParam, presenceAndCounter, aParams.challengeParam);
})
.then(function(aSignedData) {
console.log(aPublicKey, aSignedData, signatureValue);
return verifySignature(aPublicKey, aSignedData, signatureValue);
})
}
function testMakeCredential() {
let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
let param = {type: "ScopedCred", algorithm: "p-256"};
authn.makeCredential(acct, [param], gCredentialChallenge)
.then(checkCredentialValid)
.then(testMakeDuplicate)
.catch(function(aReason) {
ok(false, aReason);
SimpleTest.finish();
});
}
function testMakeDuplicate(aCredInfo) {
let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
let param = {type: "ScopedCred", algorithm: "p-256"};
let options = {rpId: document.origin,
excludeList: [aCredInfo.credential]};
authn.makeCredential(acct, [param], gCredentialChallenge, options)
.then(function() {
// We should have errored here!
ok(false, "The excludeList didn't stop a duplicate being created!");
SimpleTest.finish();
})
.catch(function(aReason) {
ok(aReason.toString().startsWith("NotAllowedError"), "Expect NotAllowedError, got" + aReason);
testAssertion(aCredInfo);
});
}
function testAssertion(aCredInfo) {
let newCredential = {
type: aCredInfo.credential.type,
id: Uint8Array.from(aCredInfo.credential.id),
transports: [ "usb" ],
}
let assertOptions = {rpId: document.origin, timeoutSeconds: 5,
allowList: [ newCredential ]};
authn.getAssertion(gAssertionChallenge, assertOptions)
.then(function(aAssertion) {
/* Pass along the pubKey. */
return checkAssertionAndSigValid(aCredInfo.u2fReg.publicKey, aAssertion);
})
.then(function(aSigVerifyResult) {
ok(aSigVerifyResult, "Signing signature verified");
SimpleTest.finish();
})
.catch(function(reason) {
ok(false, "Signing signature invalid: " + reason);
SimpleTest.finish();
});
}
});
</script>
</body>
</html>

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

@ -0,0 +1,158 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>Test for MakeCredential for W3C Web Authentication</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>
<script type="text/javascript" src="pkijs/asn1.js"></script>
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>Test for MakeCredential for W3C Web Authentication</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
"use strict";
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
function arrivingHereIsGood(aResult) {
ok(true, "Good result! Received a: " + aResult);
return Promise.resolve();
}
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();
}
function expectNotSupportedError(aResult) {
ok(aResult.toString().startsWith("NotSupportedError"), "Expecting a NotSupportedError");
return Promise.resolve();
}
SpecialPowers.pushPrefEnv({"set": [["security.webauth.w3c", true],
["security.webauth.u2f_enable_softtoken", true],
["security.webauth.u2f_enable_usbtoken", false]]},
function() {
isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
let authn = navigator.authentication;
let gCredentialChallenge = new Uint8Array(16);
window.crypto.getRandomValues(gCredentialChallenge);
let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
let param = {type: "ScopedCred", algorithm: "p-256"};
let unsupportedParam = {type: "ScopedCred", algorithm: "3DES"};
let badParam = {type: "SimplePassword", algorithm: "MaxLength=2"};
Promise.all([
// Test basic good call
authn.makeCredential(acct, [param], gCredentialChallenge)
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test empty account
authn.makeCredential({}, [param], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test without a parameter
authn.makeCredential(acct, [], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectNotSupportedError),
// Test without a parameter array at all
authn.makeCredential(acct, null, gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with an unsupported parameter
authn.makeCredential(acct, [unsupportedParam], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectNotSupportedError),
// Test with an unsupported parameter and a good one
authn.makeCredential(acct, [unsupportedParam, param], gCredentialChallenge)
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test with a bad parameter
authn.makeCredential(acct, [badParam], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with an unsupported parameter, and a bad one
authn.makeCredential(acct, [unsupportedParam, badParam],
gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with an unsupported parameter, a bad one, and a good one. This
// should still fail, as anything with a badParam should fail.
authn.makeCredential(acct, [unsupportedParam, badParam, param],
gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test without a challenge
authn.makeCredential(acct, [param], null)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with an invalid challenge
authn.makeCredential(acct, [param], "begone, thou ill-fitting moist glove!")
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test with duplicate parameters
authn.makeCredential(acct, [param, param, param], gCredentialChallenge)
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test an incomplete account
authn.makeCredential({id: "none"}, [param], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
authn.makeCredential({name: "none", imageURL: "http://example.com/404"},
[param], gCredentialChallenge)
.then(arrivingHereIsBad)
.catch(expectTypeError),
// Test a complete account
authn.makeCredential({rpDisplayName: "Foxxy", displayName: "Foxxy V",
id: "foxes_are_the_best@example.com",
name: "Fox F. Foxington",
imageURL: "https://example.com/fox.svg"},
[param], gCredentialChallenge)
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad)
])
.then(function() {
SimpleTest.finish();
});
});
</script>
</body>
</html>

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

@ -0,0 +1,80 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>Test for W3C Web Authentication with no token</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>
<script type="text/javascript" src="pkijs/asn1.js"></script>
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>Test for W3C Web Authentication with no token</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
"use strict";
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.webauth.w3c", true],
["security.webauth.u2f_enable_softtoken", false],
["security.webauth.u2f_enable_usbtoken", false]]},
function() {
isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
isnot(navigator.authentication.makeCredential, undefined, "WebAuthn makeCredential API endpoint must exist");
isnot(navigator.authentication.getAssertion, undefined, "WebAuthn getAssertion API endpoint must exist");
let authn = navigator.authentication;
let credentialChallenge = new Uint8Array(16);
window.crypto.getRandomValues(credentialChallenge);
let assertionChallenge = new Uint8Array(16);
window.crypto.getRandomValues(assertionChallenge);
let credentialId = new Uint8Array(128);
window.crypto.getRandomValues(credentialId);
testMakeCredential();
function testMakeCredential() {
let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
let param = {type: "ScopedCred", algorithm: "p-256"};
authn.makeCredential(acct, [param], credentialChallenge)
.then(function(aResult) {
ok(false, "Should have failed.");
testAssertion();
})
.catch(function(aReason) {
ok(aReason.toString().startsWith("NotAllowedError"), aReason);
testAssertion();
});
}
function testAssertion() {
let newCredential = {
type: "ScopedCred",
id: credentialId,
transports: [ "usb" ],
}
let assertOptions = {rpId: document.origin, timeoutSeconds: 5,
allowList: [ newCredential ]};
authn.getAssertion(assertionChallenge, assertOptions)
.then(function(aResult) {
ok(false, "Should have failed.");
SimpleTest.finish();
})
.catch(function(aReason) {
ok(aReason.toString().startsWith("NotAllowedError"), aReason);
SimpleTest.finish();
})
}
});
</script>
</body>
</html>

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

@ -0,0 +1,162 @@
<!DOCTYPE html>
<meta charset=utf-8>
<head>
<title>Test for MakeCredential for W3C Web Authentication</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>
<script type="text/javascript" src="pkijs/asn1.js"></script>
<script type="text/javascript" src="pkijs/x509_schema.js"></script>
<script type="text/javascript" src="pkijs/x509_simpl.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<h1>Test Same Origin Policy for W3C Web Authentication</h1>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
<script class="testbody" type="text/javascript">
"use strict";
// Execute the full-scope test
SimpleTest.waitForExplicitFinish();
var gTrackedCredential = {};
function arrivingHereIsGood(aResult) {
ok(true, "Good result! Received a: " + aResult);
return Promise.resolve();
}
function arrivingHereIsBad(aResult) {
// TODO: Change to `ok` when Bug 1329764 lands
todo(false, "Bad result! Received a: " + aResult);
return Promise.resolve();
}
function expectSecurityError(aResult) {
// TODO: Change to `ok` when Bug 1329764 lands
todo(aResult.toString().startsWith("SecurityError"), "Expecting a SecurityError");
return Promise.resolve();
}
function keepThisScopedCredential(aScopedCredInfo) {
gTrackedCredential = {
type: aScopedCredInfo.credential.type,
id: Uint8Array.from(aScopedCredInfo.credential.id),
transports: [ "usb" ],
}
return Promise.resolve(aScopedCredInfo);
}
SpecialPowers.pushPrefEnv({"set": [["security.webauth.w3c", true],
["security.webauth.u2f_enable_softtoken", true],
["security.webauth.u2f_enable_usbtoken", false]]},
function() {
isnot(navigator.authentication, undefined, "WebAuthn API endpoint must exist");
isnot(navigator.authentication.makeCredential, undefined,
"WebAuthn makeCredential API endpoint must exist");
isnot(navigator.authentication.getAssertion, undefined,
"WebAuthn getAssertion API endpoint must exist");
let authn = navigator.authentication;
let chall = new Uint8Array(16);
window.crypto.getRandomValues(chall);
let acct = {rpDisplayName: "none", displayName: "none", id: "none"};
let param = {type: "ScopedCred", algorithm: "p-256"};
Promise.all([
// Test basic good call
authn.makeCredential(acct, [param], chall, {rpId: document.origin})
.then(keepThisScopedCredential)
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test rpId being unset
authn.makeCredential(acct, [param], chall, {})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test this origin with optional fields
authn.makeCredential(acct, [param], chall,
{rpId: "user:pass@" + document.origin + ":8888"})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test blank rpId
authn.makeCredential(acct, [param], chall, {rpId: ""})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test subdomain of this origin
authn.makeCredential(acct, [param], chall,
{rpId: "subdomain." + document.origin})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test another origin
authn.makeCredential(acct, [param], chall, {rpId: "example.com"})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// est a different domain within the same TLD
authn.makeCredential(acct, [param], chall, {rpId: "alt.test"})
.then(arrivingHereIsBad)
.catch(expectSecurityError)
])
.then(function(){
return Promise.all([
// Test basic good call
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: document.origin})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test rpId being unset
authn.getAssertion(chall, {allowList: [ gTrackedCredential ]})
.then(arrivingHereIsGood)
.catch(arrivingHereIsBad),
// Test this origin with optional fields
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: "user:pass@" + document.origin + ":8888"})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test blank rpId
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: ""})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test subdomain of this origin
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: "subdomain." + document.origin})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test another origin
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: "example.com"})
.then(arrivingHereIsBad)
.catch(expectSecurityError),
// Test a different domain within the same TLD
authn.getAssertion(chall, {allowList: [ gTrackedCredential ],
rpId: "alt.test"})
.then(arrivingHereIsBad)
.catch(expectSecurityError)
]);
})
.then(function(){
SimpleTest.finish();
});
});
</script>
</body>
</html>

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

@ -127,6 +127,27 @@ function hexDecode(str) {
return new Uint8Array(str.match(/../g).map(x => parseInt(x, 16)));
}
function decodeU2FRegistration(aRegData) {
if (aRegData[0] != 0x05) {
return Promise.reject("Sentinal byte != 0x05");
}
let keyHandleLength = aRegData[66];
let u2fRegObj = {
publicKeyBytes: aRegData.slice(1, 66),
keyHandleBytes: aRegData.slice(67, 67 + keyHandleLength),
attestationBytes: aRegData.slice(67 + keyHandleLength)
}
u2fRegObj.keyHandle = bytesToBase64UrlSafe(u2fRegObj.keyHandleBytes);
return importPublicKey(u2fRegObj.publicKeyBytes)
.then(function(keyObj) {
u2fRegObj.publicKey = keyObj;
return u2fRegObj;
});
}
function importPublicKey(keyBytes) {
if (keyBytes[0] != 0x04 || keyBytes.byteLength != 65) {
throw "Bad public key octet string";