mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1436522 [wpt PR 9237] - WebAuthn WD-07 api tests, a=testonly
Automatic update from web-platform-tests new tests based on Working Draft 7 <!-- Reviewable:start --> <!-- Reviewable:end --> wpt-commits: 025a5577b9a881d14783aec39d4c6963647d09a0 wpt-pr: 9237 reapplied-commits: 370e267e160568862f1fd9ec246ab5bb840f586e, fe4514c84e7ad28e46bad5da93381deb99b177f3, 7806af854343c043a2645a4034fdc7812f65daad, 9ddfd21554293dec5a4bf2e5375ae4f3c9f2ded0, 75f63c4d1ebc949647184fd60972fc7b9fd4affb, 1f3a5b496acd2288cc8cf0c32af86cb35157ea4e, 88b42bd5847abac58a62c4d6b33c1509bfce5f3d, 15c2e4c690700c6c115f8afe5e44ded10d943538, c8d461ef1437641ae7d4ea1d21e1e60cd62910b0, a6088a5f48ee299386a84d2f771902267d7355b1, 0634cd8f08ebe0905a9188fb1398c7b5f889c5dc, c8ee4a012dae506ae06bb5b2ad50942b04c1aaaa, c2c352456a4cf62dcc12f851138b04397675a445, b93a8879555d2fa7e7d4e00a275513a3a6338b35, b86e1331cb36634fd33677043b61fc0c1d8485bc, 44ddf14fd3346658c3223f13652073fafbfa48fa, a1a5840a6bb53e305ba02bcbeb215659342d0edb, 7465cb110ae5ec2e2ca73182caf5293f0efc8fd5, aad5349b3458bc3414e274b33fa86a1123901ff2, eca0907980d2769c449894a6277c60c1a306792f, 38626987c0cfd6e715cfcc6f4f1a1209191a03c5, e4a67f7ddcde6cd99348e9104bd7ed07074da44a, bb3c9990840a0fae2afc840b5952d7874785b112, 042d7adef0bdb9dc80e825c3997ace7519477c42, 99f1ea44fc7915b8b7b33bce4732fa8765fd3ac2, b81999f30c1516a70c153de51a0331d14c8faead
This commit is contained in:
parent
8447305c9d
commit
5e8605b43d
@ -359779,24 +359779,96 @@
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-attestation.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-attestation.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-authnrselection.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-authnrselection.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-challenge.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-challenge.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-rp.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-rp.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-badargs-user.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-badargs-user.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-excludecredentials.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-excludecredentials.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-extensions.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-extensions.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-passing.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-passing.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-pubkeycredparams.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-pubkeycredparams.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/createcredential-timeout.https.html": [
|
||||
[
|
||||
"/webauthn/createcredential-timeout.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-badargs-rpid.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-badargs-rpid.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-badargs-userverification.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-badargs-userverification.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-extensions.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-extensions.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-passing.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-passing.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/getcredential-timeout.https.html": [
|
||||
[
|
||||
"/webauthn/getcredential-timeout.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webauthn/interfaces.https.html": [
|
||||
[
|
||||
"/webauthn/interfaces.https.html",
|
||||
@ -385855,7 +385927,7 @@
|
||||
"support"
|
||||
],
|
||||
"./lint.whitelist": [
|
||||
"2292c83ea0bd1432a7ba43e86a6b9f9fa8836e23",
|
||||
"67c693358b77f86e338e779ec808d00caeb5a253",
|
||||
"support"
|
||||
],
|
||||
"./serve.py": [
|
||||
@ -593042,20 +593114,68 @@
|
||||
"368ab4153a7f6843ce65ce924a3b4af92f3488ee",
|
||||
"support"
|
||||
],
|
||||
"webauthn/createcredential-badargs-attestation.https.html": [
|
||||
"397a6f0b95e75cf2b743eb208f6c79c767ec648a",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-authnrselection.https.html": [
|
||||
"f5f5c8316551a921823bfe000031d42d91d9baa1",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-challenge.https.html": [
|
||||
"741efba3e4c583d5983a5005803f718bdaa435b0",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-rp.https.html": [
|
||||
"941a9bda02e22b7d54855e3a4714a49d8392fa9d",
|
||||
"8ab678da79853a5c41ff142704bb4732b026e06c",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-badargs-user.https.html": [
|
||||
"37f734eed5ecd34f6feb90bb96154e16a763140a",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-excludecredentials.https.html": [
|
||||
"387387626892215c1552ef5e742fd32d800df4ad",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-extensions.https.html": [
|
||||
"9642dafa7ed7ce75d5812328fcd3ac2239e33ebd",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-passing.https.html": [
|
||||
"32a6ac38f91ec6b887e9e57519eb1603b4abcdbb",
|
||||
"e89da85133f56cf0b5b78f6d6f39b43926ed9fda",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-pubkeycredparams.https.html": [
|
||||
"009193df4404190c820618840104da8db380eaa8",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/createcredential-timeout.https.html": [
|
||||
"c0e639f8a32a1bc3553fd437a4fcf694a63960c2",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-badargs-rpid.https.html": [
|
||||
"275511dbafc9a536f92e74ef4c0531a7d8b7a437",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-badargs-userverification.https.html": [
|
||||
"5ac7b919d473bfc126c3e57df70c2f0defc60671",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-extensions.https.html": [
|
||||
"ea4d0533a5939927dd9eaa5d81116dbcc2f3ccbe",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-passing.https.html": [
|
||||
"6272128ea3af65ecb4fc40055b062a678bfbb2fd",
|
||||
"1b0f77b533a4e528b3abc484ba4d74b56833131f",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/getcredential-timeout.https.html": [
|
||||
"b8c71a3fccdf39c2e35bd34a3cd42561cac5836b",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/helpers.js": [
|
||||
"e6224e8e2be8657e2e312f4197cbe0225c819cea",
|
||||
"9ce729fb89ba1863fb14dfc4d567e6b544a5238d",
|
||||
"support"
|
||||
],
|
||||
"webauthn/interfaces.https.html": [
|
||||
@ -593067,11 +593187,11 @@
|
||||
"support"
|
||||
],
|
||||
"webauthn/securecontext.http.html": [
|
||||
"afc1492723d140e34027a3bdbf0d1e09843ef5d6",
|
||||
"7abf48e74debed79578e39934d1b84655731a3ea",
|
||||
"testharness"
|
||||
],
|
||||
"webauthn/securecontext.https.html": [
|
||||
"7f7a7aba32b9e049c618203121fae0884936643a",
|
||||
"9bdd7e09c7f468b9b0c106d4764d61e77b32131f",
|
||||
"testharness"
|
||||
],
|
||||
"webdriver/OWNERS": [
|
||||
|
@ -226,6 +226,7 @@ SET TIMEOUT: streams/writable-streams/byte-length-queuing-strategy.js
|
||||
SET TIMEOUT: user-timing/*
|
||||
SET TIMEOUT: webaudio/js/lodash.js
|
||||
SET TIMEOUT: webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html
|
||||
SET TIMEOUT: webauthn/*timeout.https.html
|
||||
SET TIMEOUT: webdriver/*
|
||||
SET TIMEOUT: webmessaging/*
|
||||
SET TIMEOUT: websockets/*
|
||||
|
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() attestation parameter Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// attestation bad values
|
||||
new CreateCredentialsTest("options.publicKey.attestation", {}).runTest("Bad attestation parameter: attestation is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", []).runTest("Bad attestation parameter: attestation is empty array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", null).runTest("Bad attestation parameter: attestation is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "noneofyourbusiness").runTest("Bad attestation parameter: attestation is \"noneofyourbusiness\"", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "").runTest("Bad attestation parameter: attestation is empty string", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() authenticator selection Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var defaultAuthnrSel = {
|
||||
authenticatorAttachment: "cross-platform",
|
||||
requireResidentKey: false,
|
||||
userVerification: "preferred"
|
||||
};
|
||||
// attachment
|
||||
var authnrSelAttachPlatform = cloneObject(defaultAuthnrSel);
|
||||
authnrSelAttachPlatform.authenticatorAttachment = "platform";
|
||||
var authnrSelBadAttachEmptyStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachEmptyStr.authenticatorAttachment = "";
|
||||
var authnrSelBadAttachEmptyObj = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachEmptyObj.authenticatorAttachment = {};
|
||||
var authnrSelBadAttachNull = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadAttachNull.authenticatorAttachment = null;
|
||||
// resident key
|
||||
var authnrSelRkTrue = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkTrue.requireResidentKey = true;
|
||||
var authnrSelRkBadString = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkBadString.requireResidentKey = "foo";
|
||||
// user verification
|
||||
var authnrSelUvRequired = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvRequired.userVerification = "required";
|
||||
var authnrSelBadUvEmptyStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvEmptyStr.userVerification = "";
|
||||
var authnrSelBadUvEmptyObj = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvEmptyObj.userVerification = {};
|
||||
var authnrSelBadUvStr = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvStr.userVerification = "requiredshirtshoestshirt";
|
||||
var authnrSelBadUvNull = cloneObject(defaultAuthnrSel);
|
||||
authnrSelBadUvNull.userVerification = null;
|
||||
|
||||
// authenticatorSelection bad values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", []).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", null).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", "").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", "none").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is string", new TypeError());
|
||||
|
||||
// authenticatorSelection bad attachment values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is null", new TypeError());
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachPlatform).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment platform", "NotAllowedError");
|
||||
|
||||
// authenticatorSelection bad requireResidentKey values
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkTrue).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey true", "NotAllowedError");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkBadString).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey is string", new TypeError());
|
||||
// TODO: not sure if rk is "boolean" or "truthy"; add test cases if it should only accept boolean values
|
||||
|
||||
// authenticatorSelection bad userVerification values
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification bad value", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification null", new TypeError());
|
||||
// XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvRequired).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification required", "NotAllowedError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, cloneObject */
|
||||
</script>
|
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() challenge Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad challenge values
|
||||
new CreateCredentialsTest({path: "options.publicKey.challenge", value: undefined}).runTest("Bad challenge: challenge missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", "hi mom").runTest("Bad challenge: challenge is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", null).runTest("Bad challenge: challenge is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", {}).runTest("Bad challenge: challenge is empty object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Array()).runTest("Bad challenge: challenge is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(0)).runTest("Bad challenge: challenge is empty ArrayBuffer", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
@ -12,29 +12,29 @@ standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// rp bad values
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).testBadArgs("rp missing");
|
||||
new CreateCredentialsTest("options.publicKey.rp", "hi mom").testBadArgs("rp is string");
|
||||
// new CreateCredentialsTest("options.publicKey.rp", {}).testBadArgs("rp is empty object");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).runTest("Bad rp: rp missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp", "hi mom").runTest("Bad rp: rp is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp", {}).runTest("Bad rp: rp is empty object", new TypeError());
|
||||
|
||||
// rp.id
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.id", value: undefined}).testBadArgs("rp missing id");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", {}).testBadArgs("Bad rp: id is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", null).testBadArgs("Bad rp: id is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "").testBadArgs("Bad rp: id is empty String");
|
||||
// // rp.id
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", {}).runTest("Bad rp: id is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", null).runTest("Bad rp: id is null", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "").runTest("Bad rp: id is empty String", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "invalid domain.com").runTest("Bad rp: id is invalid domain (has space)", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "-invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with dash)", "SecurityError");
|
||||
new CreateCredentialsTest("options.publicKey.rp.id", "0invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with number)", "SecurityError");
|
||||
|
||||
// rp.name
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).testBadArgs("rp missing name");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", {}).testBadArgs("Bad rp: name is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", null).testBadArgs("Bad rp: name is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", "").testBadArgs("Bad rp: name is empty String");
|
||||
// // rp.name
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).runTest("rp missing name", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", {}).runTest("Bad rp: name is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", null).runTest("Bad rp: name is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.name", "").runTest("Bad rp: name is empty String", new TypeError());
|
||||
|
||||
// rp.icon
|
||||
// new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).testBadArgs("rp missing icon");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", {}).testBadArgs("Bad rp: icon is object");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", null).testBadArgs("Bad rp: icon is null");
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", "").testBadArgs("Bad rp: icon is empty String");
|
||||
// TODO: see https://github.com/w3c/webauthn/issues/587 for the 'undefined' tests that are commented out above
|
||||
// TODO: unicode tests for icon URL (see also: USVString)
|
||||
// // rp.icon
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", {}).runTest("Bad rp: icon is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", null).runTest("Bad rp: icon is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.rp.icon", "").runTest("Bad rp: icon is empty String", new TypeError());
|
||||
// // TODO: unicode tests for icon URL (see also: USVString)
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
|
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() user Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// user bad values
|
||||
new CreateCredentialsTest({path: "options.publicKey.user", value: undefined}).runTest("Bad user: user missing", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user", "hi mom").runTest("Bad user: user is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user", {}).runTest("Bad user: user is empty object", new TypeError());
|
||||
|
||||
// // user.id
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.id", value: undefined}).runTest("Bad user: id is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", {}).runTest("Bad user: id is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", null).runTest("Bad user: id is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", "").runTest("Bad user: id is empty String", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Array()).runTest("Bad user: id is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(0)).runTest("Bad user: id is empty ArrayBuffer", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(65)).runTest("Bad user: ArrayBuffer id is too long (65 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(33)).runTest("Bad user: Int16Array id is too long (66 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(17)).runTest("Bad user: Int32Array id is too long (68 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(17)).runTest("Bad user: Float32Array id is too long (68 bytes)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float64Array(9)).runTest("Bad user: Float64Array id is too long (72 bytes)", new TypeError());
|
||||
var buf = new ArrayBuffer(65);
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new DataView(buf)).runTest("Bad user: id is too long (65 bytes)", new TypeError());
|
||||
|
||||
// // user.name
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.name", value: undefined}).runTest("user missing name", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", {}).runTest("Bad user: name is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", null).runTest("Bad user: name is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.name", "").runTest("Bad user: name is empty String", new TypeError());
|
||||
|
||||
// // user.icon
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", {}).runTest("Bad user: icon is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", null).runTest("Bad user: icon is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.icon", "").runTest("Bad user: icon is empty String", new TypeError());
|
||||
// // TODO: unicode tests for icon URL (see also: USVString)
|
||||
|
||||
// // user.displayName
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.displayName", value: undefined}).runTest("Bad user: displayName is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", {}).runTest("Bad user: displayName is object", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", null).runTest("Bad user: displayName is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.user.displayName", "").runTest("Bad user: displayName is empty String", new TypeError());
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
</script>
|
@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() excludeCredentials Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad excludeCredentials values
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", "hi mom").runTest("Bad excludeCredentials: string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", {}).runTest("Bad excludeCredentials: empty object", new TypeError());
|
||||
// TODO: bad excludeCredentials with [{.type}] or [{.id}] or [{.transports}] wrong
|
||||
|
||||
// good excludeCredentials values
|
||||
new CreateCredentialsTest({path: "options.publicKey.excludeCredentials", value: undefined}).runTest("excludeCredentials missing");
|
||||
new CreateCredentialsTest("options.publicKey.excludeCredentials", []).runTest("excludeCredentials empty array");
|
||||
|
||||
// proper excludeCredentials behavior
|
||||
// should error on excluding existing credential
|
||||
promise_test((t) => {
|
||||
var cred1;
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
return createCredential();
|
||||
})
|
||||
.then((cred) => {
|
||||
cred1 = cred;
|
||||
var excludeCred = {
|
||||
id: cred.rawId,
|
||||
type: "public-key"
|
||||
};
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
excludeCredentials: [excludeCred]
|
||||
}
|
||||
}
|
||||
};
|
||||
var p = createCredential(args);
|
||||
return promise_rejects (t, "NotAllowedError", p, "expected to fail on excluded credenetial");
|
||||
});
|
||||
}, "exclude existing credential");
|
||||
|
||||
// should not error on excluding random credential
|
||||
promise_test(() => {
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
return createCredential();
|
||||
})
|
||||
.then(() => {
|
||||
var randomCredId = new Uint8Array(162);
|
||||
window.crypto.getRandomValues(randomCredId);
|
||||
|
||||
var excludeCred = {
|
||||
id: randomCredId,
|
||||
type: "public-key"
|
||||
};
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
excludeCredentials: [excludeCred]
|
||||
}
|
||||
}
|
||||
};
|
||||
return createCredential(args);
|
||||
});
|
||||
}, "exclude random (non-existing) credential");
|
||||
|
||||
// TODO: exclude including transport type (USB, BLE, NFC)
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test, promise_rejects */
|
||||
</script>
|
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() extensions Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var dummyExtension = {
|
||||
foo: true,
|
||||
bar: "yup"
|
||||
};
|
||||
|
||||
// bad extension values
|
||||
new CreateCredentialsTest("options.publicKey.extensions", "hi mom").runTest("Bad extensions: extensions is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", null).runTest("Bad extensions: extensions is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", []).runTest("Bad extensions: extensions is empty Array", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0)).runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
|
||||
var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: badJson}).runTest("Bad extensions: malformatted JSON", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: dummyExtension}).runTest("Bad extensions: JavaScript object", new TypeError());
|
||||
var badExtId = {};
|
||||
badExtId[createRandomString(65)] = dummyExtension;
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension}).runTest("Bad extensions: extension ID too long", new TypeError());
|
||||
|
||||
// phony extensions
|
||||
// TODO: not sure if this should pass or fail
|
||||
// should be clarified as part of https://github.com/w3c/webauthn/pull/765
|
||||
var randomExtId = {};
|
||||
randomExtId[createRandomString(64)] = dummyExtension;
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)}).runTest("extensions is a nonsensical JSON string");
|
||||
|
||||
// TODO
|
||||
// defined extensions:
|
||||
// * appid
|
||||
// * txAuthSimple
|
||||
// * txAuthGeneric
|
||||
// * authnSel
|
||||
// * exts
|
||||
// * uvi
|
||||
// * loc
|
||||
// * uvm
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createRandomString */
|
||||
</script>
|
@ -12,9 +12,108 @@ standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// CreateCredentialTest passing tests
|
||||
new CreateCredentialsTest().test();
|
||||
|
||||
// default arguments
|
||||
new CreateCredentialsTest().runTest("passing credentials.create() with default arguments");
|
||||
|
||||
// rp
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.host}).runTest("passing credentials.create() with rpId (host and port)");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.hostname}).runTest("passing credentials.create() with rpId (hostname)");
|
||||
new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).runTest("passing credentials.create() without rp.icon");
|
||||
|
||||
// user
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(1)).runTest("very short user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(64)).runTest("max length user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Uint8Array(64)).runTest("Uint8Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int8Array(64)).runTest("Int8Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(32)).runTest("Int16Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(16)).runTest("Int32Array user id");
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(16)).runTest("Float32Array user id");
|
||||
var dvBuf1 = new ArrayBuffer(16);
|
||||
new CreateCredentialsTest("options.publicKey.user.id", new DataView(dvBuf1)).runTest("DataView user id");
|
||||
new CreateCredentialsTest({path: "options.publicKey.user.icon", value: undefined}).runTest("passing credentials.create() without user.icon");
|
||||
|
||||
// good challenge values
|
||||
// all these challenges are zero-filled buffers... think anyone will complain?
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Int16Array(33)).runTest("Int16Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Int32Array(17)).runTest("Int32Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Float32Array(17)).runTest("Float32Array challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new Float64Array(9)).runTest("Float64Array challenge");
|
||||
var dvBuf2 = new ArrayBuffer(65);
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new DataView(dvBuf2)).runTest("DataView challenge");
|
||||
new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(8192)).runTest("Absurdly large challenge");
|
||||
|
||||
// good pubKeyCredParams values
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", []).runTest("Bad pubKeyCredParams: pubKeyCredParams is empty Array");
|
||||
const pkParamEC256 = {
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256
|
||||
};
|
||||
const pkParamEC512 = {
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA512
|
||||
};
|
||||
// XXX: presumes all mock authenticators support EC256
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256]).runTest("EC256 pubKeyCredParams");
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
|
||||
.runTest("SelectEC256 pubKeyCredParams from a list");
|
||||
// TODO: currently most browsers are mocking FIDO U2F, which is EC256 only
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512]).runTest("EC512 pubKeyCredParams");
|
||||
|
||||
// NOTE: excludeCredentials parameter -- see also: createcredential-excludecredentials.https.html
|
||||
|
||||
// timeout
|
||||
new CreateCredentialsTest({path: "options.publicKey.timeout", value: undefined}).runTest("passing credentials.create() with no timeout");
|
||||
|
||||
// valid authenticatorSelection values
|
||||
var defaultAuthnrSel = {
|
||||
authenticatorAttachment: "cross-platform",
|
||||
requireResidentKey: false,
|
||||
userVerification: "preferred"
|
||||
};
|
||||
// attachment
|
||||
var authnrSelAttachUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelAttachUndef.authenticatorAttachment = undefined;
|
||||
// resident key
|
||||
var authnrSelRkUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkUndef.requireResidentKey = undefined;
|
||||
var authnrSelRkFalse = cloneObject(defaultAuthnrSel);
|
||||
authnrSelRkFalse.requireResidentKey = false;
|
||||
// user verification
|
||||
var authnrSelUvUndef = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvUndef.userVerification = undefined;
|
||||
var authnrSelUvDiscouraged = cloneObject(defaultAuthnrSel);
|
||||
authnrSelUvDiscouraged.userVerification = "discouraged";
|
||||
new CreateCredentialsTest({path: "options.publicKey.authenticatorSelection", value: undefined}).runTest("authenticatorSelection is undefined");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", {}).runTest("authenticatorSelection is empty object");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", cloneObject(defaultAuthnrSel)).runTest("authenticatorSelection default values");
|
||||
|
||||
// authnr selection attachment
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachUndef).runTest("authenticatorSelection attachment undefined");
|
||||
|
||||
// authnr selection resident key
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkUndef).runTest("authenticatorSelection residentKey undefined");
|
||||
// XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkFalse).runTest("authenticatorSelection residentKey false");
|
||||
|
||||
// authnr selection user verification
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvUndef).runTest("authenticatorSelection userVerification undefined");
|
||||
new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvDiscouraged).runTest("authenticatorSelection userVerification discouraged");
|
||||
|
||||
|
||||
// good attestation values
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "none").runTest("attestation parameter: attestation is \"none\"");
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "indirect").runTest("attestation parameter: attestation is \"indirect\"");
|
||||
new CreateCredentialsTest("options.publicKey.attestation", "direct").runTest("attestation parameter: attestation is \"direct\"");
|
||||
new CreateCredentialsTest({path: "options.publicKey.attestation", value: undefined}).runTest("attestation parameter: attestation is undefined");
|
||||
// TODO: test this with multiple mock authenticators to make sure that the right options are chosen when available?
|
||||
|
||||
// good extension values
|
||||
new CreateCredentialsTest({path: "options.publicKey.extensions", value: undefined}).runTest("extensions undefined");
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {}).runTest("extensions are empty object");
|
||||
new CreateCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""}).runTest("extensions are dict of empty strings");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest */
|
||||
/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA256, cose_alg_ECDSA_w_SHA512, cloneObject */
|
||||
</script>
|
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() pubKeyCredParams Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var badType = {
|
||||
type: "something-else",
|
||||
alg: cose_alg_ECDSA_w_SHA512
|
||||
};
|
||||
var badTypeEmptyString = cloneObject(badType);
|
||||
badTypeEmptyString.type = "";
|
||||
var badTypeNull = cloneObject(badType);
|
||||
badTypeNull.type = null;
|
||||
var badTypeEmptyObj = cloneObject(badType);
|
||||
badTypeEmptyObj.type = {};
|
||||
|
||||
var badAlg = {
|
||||
type: "public-key",
|
||||
alg: 42
|
||||
};
|
||||
var badAlgZero = cloneObject(badAlg);
|
||||
badAlgZero.alg = 0;
|
||||
|
||||
// bad pubKeyCredParams values
|
||||
new CreateCredentialsTest({path: "options.publicKey.pubKeyCredParams", value: undefined}).runTest("Bad pubKeyCredParams: pubKeyCredParams is undefined", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", "hi mom").runTest("Bad pubKeyCredParams: pubKeyCredParams is string", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", null).runTest("Bad pubKeyCredParams: pubKeyCredParams is null", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badType]).runTest("Bad pubKeyCredParams: first param has bad type (\"something-else\")", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyString]).runTest("Bad pubKeyCredParams: first param has bad type (\"\")", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeNull]).runTest("Bad pubKeyCredParams: first param has bad type (null)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyObj]).runTest("Bad pubKeyCredParams: first param has bad type (empty object)", new TypeError());
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlg]).runTest("Bad pubKeyCredParams: first param has bad alg (42)", "NotSupportedError");
|
||||
new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlgZero]).runTest("Bad pubKeyCredParams: first param has bad alg (0)", "NotSupportedError");
|
||||
|
||||
// TODO: come back to this when mock authenticators support multiple cryptos so that we can test the preference ranking
|
||||
// function verifyEC256(res) {
|
||||
// debug ("verifyEC256 got", res);
|
||||
// debug ("client data JSON", ab2str(res.response.clientDataJSON));
|
||||
// parseAuthenticatorData(res.response.attestationObject);
|
||||
// }
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256, pkParamEC512])
|
||||
// .afterTest(verifyEC256)
|
||||
// .runTest("EC256, EC512 pubKeyCredParams");
|
||||
// function verifyEC512(res) {
|
||||
// debug ("verifyEC512 got", res);
|
||||
// debug ("client data JSON", ab2str(res.response.clientDataJSON));
|
||||
// // parseAuthenticatorData(res.response.attestationObject);
|
||||
// printHex ("clientDataJSON", res.response.clientDataJSON);
|
||||
// printHex ("attestationObject", res.response.attestationObject);
|
||||
// }
|
||||
// new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
|
||||
// .afterTest(verifyEC512)
|
||||
// .runTest("EC512, EC256 pubKeyCredParams");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA512, cloneObject */
|
||||
</script>
|
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.create() timeout Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// bad timeout values
|
||||
// TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
|
||||
// new CreateCredentialsTest({path: "options.publicKey.timeout", value: -1}).runTest("Bad timeout: negative", new TypeError());
|
||||
// new CreateCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1}).runTest("Bad timeout: too big", new TypeError());
|
||||
|
||||
// timeout test
|
||||
// XXX: this probably always passes with most mock authenticators unless
|
||||
// some setup happens right here to make sure they don't return a credential
|
||||
// right away. So... uhh... I guess test this with a real authenticator if you
|
||||
// want to see if it really works.
|
||||
promise_test(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var args = {
|
||||
options: {
|
||||
publicKey: {
|
||||
timeout: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
reject(new Error ("timed out"));
|
||||
}, 1000);
|
||||
|
||||
createCredential(args).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
}, "ensure create credential times out");
|
||||
// TODO: createCredential.timeout > 1s && setTimeout < 1s
|
||||
// TODO: createCredential.timeout < 5s && setTimeout > 5s
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test */
|
||||
</script>
|
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn credential.get() rpId Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
new GetCredentialsTest("options.publicKey.rpId", "")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: empty string", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: null", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "invalid domain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (has space)", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "-invaliddomain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (starts with dash)", "SecurityError");
|
||||
new GetCredentialsTest("options.publicKey.rpId", "0invaliddomain.com")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad rpId: invalid domain (starts with number)", "SecurityError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() user verification Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
// authenticatorSelection bad userVerification values
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: empty string", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", {})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: empty object", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "requiredshirtshoestshirt")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: bad value", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.userVerification", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: null", new TypeError());
|
||||
// XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "required")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad userVerification: \"required\"", "NotAllowedError");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() extensions Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var dummyExtension = {
|
||||
foo: true,
|
||||
bar: "yup"
|
||||
};
|
||||
var credPromise = createCredential();
|
||||
|
||||
// bad extension values
|
||||
new GetCredentialsTest("options.publicKey.extensions", "hi mom")
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is string", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", null)
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is null", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", [])
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is empty Array", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0))
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
|
||||
var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: badJson})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: malformatted JSON", new TypeError());
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: dummyExtension})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: JavaScript object", new TypeError());
|
||||
var badExtId = {};
|
||||
badExtId[createRandomString(65)] = dummyExtension;
|
||||
new GetCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension})
|
||||
.addCredential(credPromise)
|
||||
.runTest("Bad extensions: extension ID too long", new TypeError());
|
||||
|
||||
// phony extensions
|
||||
// TODO: not sure if this should pass or fail
|
||||
// should be clarified as part of https://github.com/w3c/webauthn/pull/765
|
||||
var randomExtId = {};
|
||||
randomExtId[createRandomString(64)] = dummyExtension;
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions is a nonsensical JSON string");
|
||||
|
||||
// TODO
|
||||
// defined extensions:
|
||||
// * appid
|
||||
// * txAuthSimple
|
||||
// * txAuthGeneric
|
||||
// * authnSel
|
||||
// * exts
|
||||
// * uvi
|
||||
// * loc
|
||||
// * uvm
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createRandomString, createCredential */
|
||||
</script>
|
@ -11,11 +11,56 @@
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
// GetCredentialsTest passing tests
|
||||
// new GetCredentialsTest().addCredential();
|
||||
new GetCredentialsTest().addCredential().test();
|
||||
var credPromise = createCredential();
|
||||
|
||||
// GetCredentialsTest with default args
|
||||
new GetCredentialsTest()
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with default args");
|
||||
|
||||
// timeout
|
||||
new GetCredentialsTest({path: "options.publicKey.timeout", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.create() with no timeout");
|
||||
|
||||
// rpId
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("rpId undefined");
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.host})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with rpId (host and port)");
|
||||
new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.hostname})
|
||||
.addCredential(credPromise)
|
||||
.runTest("passing credentials.get() with rpId (hostname)");
|
||||
|
||||
// allowCredentials
|
||||
new GetCredentialsTest({path: "options.publicKey.allowCredentials", value: undefined})
|
||||
.runTest("no credential specified");
|
||||
|
||||
// authnr selection user verification
|
||||
new GetCredentialsTest({path: "options.publicKey.userVerification", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification undefined");
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "preferred")
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification preferred");
|
||||
new GetCredentialsTest("options.publicKey.userVerification", "discouraged")
|
||||
.addCredential(credPromise)
|
||||
.runTest("authenticatorSelection userVerification discouraged");
|
||||
|
||||
// good extension values
|
||||
new GetCredentialsTest({path: "options.publicKey.extensions", value: undefined})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions undefined");
|
||||
new GetCredentialsTest("options.publicKey.extensions", {})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions are empty object");
|
||||
new GetCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""})
|
||||
.addCredential(credPromise)
|
||||
.runTest("extensions are dict of empty strings");
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>WebAuthn navigator.credentials.get() timeout Tests</title>
|
||||
<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
|
||||
<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=helpers.js></script>
|
||||
<body></body>
|
||||
<script>
|
||||
standardSetup(function() {
|
||||
"use strict";
|
||||
|
||||
var credPromise = createCredential();
|
||||
|
||||
// bad timeout values
|
||||
// TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
|
||||
// new GetCredentialsTest({path: "options.publicKey.timeout", value: -1})
|
||||
// .addCredential(credPromise)
|
||||
// .runTest("Bad timeout: negative", new TypeError());
|
||||
// new GetCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1})
|
||||
// .addCredential(credPromise)
|
||||
// .runTest("Bad timeout: too big", new TypeError());
|
||||
|
||||
// timeout test
|
||||
// XXX: this probably always passes with most mock authenticators unless
|
||||
// some setup happens right here to make sure they don't return a credential
|
||||
// right away. So... uhh... I guess test this with a real authenticator if you
|
||||
// want to see if it really works.
|
||||
var timer;
|
||||
function startTimer() {
|
||||
timer = setTimeout(() => {
|
||||
throw new Error("Timer went off before timeout");
|
||||
}, 1000);
|
||||
}
|
||||
function stopTimer() {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
new GetCredentialsTest({path: "options.publicKey.timeout", value: 1})
|
||||
.addCredential(credPromise)
|
||||
.beforeTest(startTimer)
|
||||
.afterTest(stopTimer)
|
||||
.runTest("ensure create credential times out");
|
||||
// TODO: createCredential.timeout > 1s && setTimeout < 1s
|
||||
// TODO: createCredential.timeout < 5s && setTimeout > 5s
|
||||
});
|
||||
|
||||
/* JSHINT */
|
||||
/* globals standardSetup, GetCredentialsTest, createCredential */
|
||||
</script>
|
@ -1,5 +1,4 @@
|
||||
|
||||
/* Useful constants for working with COSE key objects */
|
||||
// Useful constants for working with COSE key objects
|
||||
const cose_kty = 1;
|
||||
const cose_kty_ec2 = 2;
|
||||
const cose_alg = 3;
|
||||
@ -10,6 +9,117 @@ const cose_crv_P256 = 1;
|
||||
const cose_crv_x = -2;
|
||||
const cose_crv_y = -3;
|
||||
|
||||
/**
|
||||
* These are the default arguments that will be passed to navigator.credentials.create()
|
||||
* unless modified by a specific test case
|
||||
*/
|
||||
var createCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
// Relying Party:
|
||||
rp: {
|
||||
name: "Acme",
|
||||
icon: "https://www.w3.org/StyleSheets/TR/2016/logos/W3C"
|
||||
},
|
||||
|
||||
// User:
|
||||
user: {
|
||||
id: new Uint8Array(16), // Won't survive the copy, must be rebuilt
|
||||
name: "john.p.smith@example.com",
|
||||
displayName: "John P. Smith",
|
||||
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
|
||||
},
|
||||
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256,
|
||||
}],
|
||||
|
||||
timeout: 60000, // 1 minute
|
||||
excludeCredentials: [] // No excludeList
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* These are the default arguments that will be passed to navigator.credentials.get()
|
||||
* unless modified by a specific test case
|
||||
*/
|
||||
var getCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
timeout: 60000
|
||||
// allowCredentials: [newCredential]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function createCredential(opts) {
|
||||
opts = opts || {};
|
||||
|
||||
// set the default options
|
||||
var createArgs = cloneObject(createCredentialDefaultArgs);
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
createArgs.options.publicKey.challenge = challengeBytes;
|
||||
createArgs.options.publicKey.user.id = new Uint8Array(16);
|
||||
|
||||
// change the defaults with any options that were passed in
|
||||
extendObject (createArgs, opts);
|
||||
|
||||
// create the credential, return the Promise
|
||||
return navigator.credentials.create(createArgs.options);
|
||||
}
|
||||
|
||||
function createRandomString(len) {
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for(var i = 0; i < len; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
function ab2str(buf) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buf));
|
||||
}
|
||||
|
||||
// Useful constants for working with attestation data
|
||||
const authenticator_data_user_present = 0x01;
|
||||
const authenticator_data_user_verified = 0x04;
|
||||
const authenticator_data_attested_cred_data = 0x40;
|
||||
const authenticator_data_extension_data = 0x80;
|
||||
|
||||
function parseAuthenticatorData(buf) {
|
||||
if (buf.byteLength < 37) {
|
||||
throw new TypeError ("parseAuthenticatorData: buffer must be at least 37 bytes");
|
||||
}
|
||||
|
||||
printHex ("authnrData", buf);
|
||||
|
||||
var authnrData = new DataView(buf);
|
||||
var authnrDataObj = {};
|
||||
authnrDataObj.length = buf.byteLength;
|
||||
|
||||
authnrDataObj.rpIdHash = new Uint8Array (buf.slice (0,32));
|
||||
authnrDataObj.rawFlags = authnrData.getUint8(32);
|
||||
authnrDataObj.counter = authnrData.getUint32(33, false);
|
||||
authnrDataObj.rawCounter = [];
|
||||
authnrDataObj.rawCounter[0] = authnrData.getUint8(33);
|
||||
authnrDataObj.rawCounter[1] = authnrData.getUint8(34);
|
||||
authnrDataObj.rawCounter[2] = authnrData.getUint8(35);
|
||||
authnrDataObj.rawCounter[3] = authnrData.getUint8(36);
|
||||
authnrDataObj.flags = {};
|
||||
|
||||
authnrDataObj.flags.userPresent = (authnrDataObj.rawFlags&authenticator_data_user_present)?true:false;
|
||||
authnrDataObj.flags.userVerified = (authnrDataObj.rawFlags&authenticator_data_user_verified)?true:false;
|
||||
authnrDataObj.flags.attestedCredentialData = (authnrDataObj.rawFlags&authenticator_data_attested_cred_data)?true:false;
|
||||
authnrDataObj.flags.extensionData = (authnrDataObj.rawFlags&authenticator_data_extension_data)?true:false;
|
||||
|
||||
return authnrDataObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* TestCase
|
||||
*
|
||||
@ -118,66 +228,127 @@ class TestCase {
|
||||
|
||||
/**
|
||||
* run the test function with the top-level properties of the test object applied as arguments
|
||||
* expects the test to pass, and then validates the results
|
||||
*/
|
||||
test(desc) {
|
||||
promise_test(() => {
|
||||
return this.doIt()
|
||||
.then((ret) => {
|
||||
// check the result
|
||||
this.validateRet(ret);
|
||||
return ret;
|
||||
});
|
||||
}, desc);
|
||||
testPasses(desc) {
|
||||
return this.doIt()
|
||||
.then((ret) => {
|
||||
// check the result
|
||||
this.validateRet(ret);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* run the test function with the top-level properties of the test object applied as arguments
|
||||
* expects the test to fail
|
||||
*/
|
||||
testFails(t, testDesc, expectedErr) {
|
||||
return promise_rejects(t, expectedErr, this.doIt(), "Expected bad parameters to fail");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the test that's implemented by the class by calling the doIt() function
|
||||
* @param {String} desc A description of the test being run
|
||||
* @param [Error|String] expectedErr A string matching an error type, such as "SecurityError" or an object with a .name value that is an error type string
|
||||
*/
|
||||
runTest(desc, expectedErr) {
|
||||
promise_test((t) => {
|
||||
return Promise.resolve().then(() => {
|
||||
return this.testSetup();
|
||||
}).then(() => {
|
||||
if (expectedErr === undefined) {
|
||||
return this.testPasses(desc);
|
||||
} else {
|
||||
return this.testFails(t, desc, expectedErr);
|
||||
}
|
||||
}).then((res) => {
|
||||
return this.testTeardown(res);
|
||||
})
|
||||
}, desc)
|
||||
}
|
||||
|
||||
/**
|
||||
* called before runTest
|
||||
* virtual method expected to be overridden by child class if needed
|
||||
*/
|
||||
testSetup() {
|
||||
if (this.beforeTestFn) {
|
||||
this.beforeTestFn.call(this);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback function that gets called in the TestCase context
|
||||
* and within the testing process.
|
||||
*/
|
||||
beforeTest(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new Error ("Tried to call non-function before test");
|
||||
}
|
||||
|
||||
this.beforeTestFn = fn;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* called after runTest
|
||||
* virtual method expected to be overridden by child class if needed
|
||||
*/
|
||||
testTeardown(res) {
|
||||
if (this.afterTestFn) {
|
||||
this.afterTestFn.call(this, res);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback function that gets called in the TestCase context
|
||||
* and within the testing process. Good for validating results.
|
||||
*/
|
||||
afterTest(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new Error ("Tried to call non-function after test");
|
||||
}
|
||||
|
||||
this.afterTestFn = fn;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the value returned from the test function
|
||||
* virtual method expected to be overridden by child class
|
||||
*/
|
||||
validateRet() {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* calls doIt() with testObject() and expects it to fail with a TypeError()
|
||||
*/
|
||||
testBadArgs(testDesc) {
|
||||
promise_test(function(t) {
|
||||
return promise_rejects(t, new TypeError(), this.doIt(), "Expected bad parameters to fail");
|
||||
}.bind(this), testDesc);
|
||||
}
|
||||
}
|
||||
|
||||
var createCredentialDefaultArgs = {
|
||||
options: {
|
||||
publicKey: {
|
||||
// Relying Party:
|
||||
rp: {
|
||||
name: "Acme"
|
||||
},
|
||||
|
||||
// User:
|
||||
user: {
|
||||
id: new Uint8Array(), // Won't survive the copy, must be rebuilt
|
||||
name: "john.p.smith@example.com",
|
||||
displayName: "John P. Smith",
|
||||
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
|
||||
},
|
||||
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: cose_alg_ECDSA_w_SHA256,
|
||||
}],
|
||||
|
||||
timeout: 60000, // 1 minute
|
||||
excludeCredentials: [] // No excludeList
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function cloneObject(o) {
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
}
|
||||
|
||||
function extendObject(dst, src) {
|
||||
Object.keys(src).forEach(function(key) {
|
||||
if (isSimpleObject(src[key])) {
|
||||
extendObject (dst[key], src[key]);
|
||||
} else {
|
||||
dst[key] = src[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isSimpleObject(o) {
|
||||
return (typeof o === "object" &&
|
||||
!Array.isArray(o) &&
|
||||
!(o instanceof ArrayBuffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateCredentialTest
|
||||
*
|
||||
@ -198,7 +369,7 @@ class CreateCredentialsTest extends TestCase {
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
this.testObject = cloneObject(createCredentialDefaultArgs);
|
||||
// cloneObject can't clone the BufferSource in user.id, so let's recreate it.
|
||||
this.testObject.options.publicKey.user.id = new Uint8Array();
|
||||
this.testObject.options.publicKey.user.id = new Uint8Array(16);
|
||||
this.testObject.options.publicKey.challenge = challengeBytes;
|
||||
|
||||
// how to order the properties of testObject when passing them to makeCredential
|
||||
@ -235,15 +406,8 @@ class GetCredentialsTest extends TestCase {
|
||||
// default arguments
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
this.testObject = {
|
||||
options: {
|
||||
publicKey: {
|
||||
challenge: challengeBytes,
|
||||
// timeout: 60000,
|
||||
// allowCredentials: [newCredential]
|
||||
}
|
||||
}
|
||||
};
|
||||
this.testObject = cloneObject(getCredentialDefaultArgs);
|
||||
this.testObject.options.publicKey.challenge = challengeBytes;
|
||||
|
||||
// how to order the properties of testObject when passing them to makeCredential
|
||||
this.argOrder = [
|
||||
@ -266,33 +430,28 @@ class GetCredentialsTest extends TestCase {
|
||||
// if a Promise was passed in, add it to the list
|
||||
if (arg instanceof Promise) {
|
||||
this.credentialPromiseList.push(arg);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
// if a credential object was passed in, convert it to a Promise for consistency
|
||||
if (typeof arg === "object") {
|
||||
this.credentialPromiseList.push(Promise.resolve(arg));
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
// if a credential wasn't passed in, create one
|
||||
let challengeBytes = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(challengeBytes);
|
||||
var createArgs = cloneObject(createCredentialDefaultArgs);
|
||||
createArgs.options.publicKey.challenge = challengeBytes;
|
||||
createArgs.options.publicKey.user.id = new Uint8Array();
|
||||
var p = navigator.credentials.create(createArgs.options);
|
||||
// if no credential specified then create one
|
||||
var p = createCredential();
|
||||
this.credentialPromiseList.push(p);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
test() {
|
||||
testSetup(desc) {
|
||||
if (!this.credentialPromiseList.length) {
|
||||
throw new Error("Attempting list without defining credential to test");
|
||||
}
|
||||
|
||||
Promise.all(this.credentialPromiseList)
|
||||
return Promise.all(this.credentialPromiseList)
|
||||
.then((credList) => {
|
||||
var idList = credList.map((cred) => {
|
||||
return {
|
||||
@ -302,12 +461,15 @@ class GetCredentialsTest extends TestCase {
|
||||
};
|
||||
});
|
||||
this.testObject.options.publicKey.allowCredentials = idList;
|
||||
return super.test();
|
||||
// return super.test(desc);
|
||||
})
|
||||
.catch((err) => {
|
||||
throw Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
validateRet(ret) {
|
||||
validatePublicKeyCredential (ret);
|
||||
validatePublicKeyCredential(ret);
|
||||
validateAuthenticatorAssertionResponse(ret.response);
|
||||
}
|
||||
}
|
||||
@ -335,12 +497,16 @@ function validatePublicKeyCredential(cred) {
|
||||
function validateAuthenticatorAttestationResponse(attr) {
|
||||
// class
|
||||
assert_class_string(attr, "AuthenticatorAttestationResponse", "Expected credentials.create() to return instance of 'AuthenticatorAttestationResponse' class");
|
||||
|
||||
// clientDataJSON
|
||||
assert_idl_attribute(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with clientDataJSON attribute");
|
||||
assert_readonly(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with readonly clientDataJSON attribute");
|
||||
// TODO: clientDataJSON() and make sure fields are correct
|
||||
|
||||
// attestationObject
|
||||
assert_idl_attribute(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with attestationObject attribute");
|
||||
assert_readonly(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with readonly attestationObject attribute");
|
||||
// TODO: parseAuthenticatorData() and make sure flags are correct
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,15 +515,20 @@ function validateAuthenticatorAttestationResponse(attr) {
|
||||
function validateAuthenticatorAssertionResponse(assert) {
|
||||
// class
|
||||
assert_class_string(assert, "AuthenticatorAssertionResponse", "Expected credentials.create() to return instance of 'AuthenticatorAssertionResponse' class");
|
||||
|
||||
// clientDataJSON
|
||||
assert_idl_attribute(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with clientDataJSON attribute");
|
||||
assert_readonly(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with readonly clientDataJSON attribute");
|
||||
// TODO: clientDataJSON() and make sure fields are correct
|
||||
|
||||
// signature
|
||||
assert_idl_attribute(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with signature attribute");
|
||||
assert_readonly(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with readonly signature attribute");
|
||||
|
||||
// authenticatorData
|
||||
assert_idl_attribute(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with authenticatorData attribute");
|
||||
assert_readonly(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with readonly authenticatorData attribute");
|
||||
// TODO: parseAuthenticatorData() and make sure flags are correct
|
||||
}
|
||||
|
||||
//************* BEGIN DELETE AFTER 1/1/2018 *************** //
|
||||
@ -370,8 +541,8 @@ var debug = function() {};
|
||||
// note that the polyfill only gets loaded if navigator.credentials create doesn't exist
|
||||
// AND if the polyfill script is found at the right path (i.e. - the polyfill is opt-in)
|
||||
function ensureInterface() {
|
||||
if (typeof navigator.credentials.create !== "function") {
|
||||
debug = console.log;
|
||||
if (typeof navigator.credentials === "object" && typeof navigator.credentials.create !== "function") {
|
||||
// debug = onsole.log;
|
||||
|
||||
return loadJavaScript("/webauthn/webauthn-polyfill/webauthn-polyfill.js")
|
||||
.then(() => {
|
||||
|
@ -17,7 +17,7 @@ standardSetup(function() {
|
||||
// Example 1
|
||||
// http://example.com/ opened in a top-level browsing context is not a secure context, as it was not delivered over an authenticated and encrypted channel.
|
||||
test (() => {
|
||||
assert_false (typeof navigator.credentials.create === "function");
|
||||
assert_false (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
|
||||
}, "no navigator.credentials.create in non-secure context");
|
||||
|
||||
// Example 4: TODO
|
||||
|
@ -17,7 +17,7 @@ standardSetup(function() {
|
||||
// Example 2
|
||||
// https://example.com/ opened in a top-level browsing context is a secure context, as it was delivered over an authenticated and encrypted channel.
|
||||
test (() => {
|
||||
assert_true (typeof navigator.credentials.create === "function");
|
||||
assert_true (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
|
||||
}, "navigator.credentials.create exists in secure context");
|
||||
|
||||
// Example 3: TODO
|
||||
|
Loading…
Reference in New Issue
Block a user