blob: a2ec88e79eba0f7c403097abd204c60299e04cf1 [file] [log] [blame]
'use strict';
// A minimal HTML document that loads this very file. This can be
// document.write()'en to nested documents to include test input/outputs.
const HTML_WITH_TEST_INPUTS = "<script src='/credentialmanager/resources/test-inputs.js'></script>";
// Constructs a script that loads this very script file, and runs |code| once
// loaded. This can be window.eval()'ed in nested documents to include test
// input/outputs (and then run the |code| under test).
function getScriptThatLoadsTestInputsAndRuns(code) {
return "var script = document.createElement('script');"
+ "script.src = '/credentialmanager/resources/test-inputs.js';"
+ "script.onload = _ => {" + code + "};"
+ "document.head.appendChild(script);"
}
// Common mock values for the mockAuthenticator.
var CHALLENGE = new TextEncoder().encode("climb a mountain");
var PUBLIC_KEY_RP = {
id: "subdomain.example.test",
name: "Acme"
};
var PUBLIC_KEY_USER = {
id: new TextEncoder().encode("1098237235409872"),
name: "avery.a.jones@example.com",
displayName: "Avery A. Jones",
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
};
var PUBLIC_KEY_PARAMETERS = [{
type: "public-key",
alg: -7,
},];
var AUTHENTICATOR_SELECTION_CRITERIA = {
requireResidentKey: false,
userVerification: "preferred",
};
var MAKE_CREDENTIAL_OPTIONS = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
user: PUBLIC_KEY_USER,
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
excludeCredentials: [],
};
var ACCEPTABLE_CREDENTIAL_ID = new TextEncoder().encode("acceptableCredential");
var ACCEPTABLE_CREDENTIAL = {
type: "public-key",
id: ACCEPTABLE_CREDENTIAL_ID,
transports: ["usb", "nfc", "ble"]
};
var GET_CREDENTIAL_OPTIONS = {
challenge: CHALLENGE,
rpId: "subdomain.example.test",
allowCredentials: [ACCEPTABLE_CREDENTIAL],
userVerification: "preferred",
};
var RAW_ID = new TextEncoder("utf-8").encode("rawId");
var ID = btoa("rawId");
var CLIENT_DATA_JSON = new TextEncoder("utf-8").encode("clientDataJSON");
var ATTESTATION_OBJECT = new TextEncoder("utf-8").encode("attestationObject");
var AUTHENTICATOR_DATA = new TextEncoder("utf-8").encode("authenticatorData");
var SIGNATURE = new TextEncoder("utf-8").encode("signature");
var CABLE_REGISTRATION = {
versions: [1],
rpPublicKey: new TextEncoder("utf-8").encode("SixteenByteRpKey"),
};
var CABLE_AUTHENTICATION = {
version: 1,
clientEid: new TextEncoder("utf-8").encode("SixteenByteClEid"),
authenticatorEid: new TextEncoder("utf-8").encode("SixteenByteAuEid"),
sessionPreKey: new TextEncoder("utf-8").encode('x'.repeat(32)),
};
var CREATE_CREDENTIALS =
"navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS})"
+ ".then(c => window.parent.postMessage(String(c), '*'))";
+ ".catch(e => window.parent.postMessage(String(e), '*'));";
var GET_CREDENTIAL = "navigator.credentials.get({publicKey : GET_CREDENTIAL_OPTIONS})"
+ ".then(c => window.parent.postMessage(String(c), '*'))";
+ ".catch(e => window.parent.postMessage(String(e), '*'));";
function encloseInScriptTag(code) {
return "<script>" + code + "</scr" + "ipt>";
}
function deepCopy(value) {
if ([Number, String, Boolean, Uint8Array].includes(value.constructor))
return value;
let copy = (value.constructor == Array) ? [] : {};
for (let key of Object.keys(value))
copy[key] = deepCopy(value[key]);
return copy;
}
// Verifies if |r| is the valid response to credentials.create(publicKey).
function assertValidMakeCredentialResponse(r) {
assert_equals(r.id, ID, 'id');
assert_true(r.rawId instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.rawId),
RAW_ID, "rawId returned is the same");
assert_true(r.response instanceof AuthenticatorAttestationResponse);
assert_true(r.response.clientDataJSON instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.response.clientDataJSON),
CLIENT_DATA_JSON, "clientDataJSON returned is the same");
assert_true(r.response.attestationObject instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.response.attestationObject),
ATTESTATION_OBJECT, "attestationObject returned is the same");
assert_false('authenticatorData' in r.response);
assert_false('signature' in r.response);
}
// Verifies if |r| is the valid response to credentials.get(publicKey).
function assertValidGetCredentialResponse(r) {
assert_equals(r.id, ID, 'id');
assert_true(r.rawId instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.rawId),
RAW_ID, "rawId returned is the same");
// The call returned an AssertionResponse, meaning it has
// authenticatorData and signature and does not have an attestationObject.
assert_true(r.response instanceof AuthenticatorAssertionResponse);
assert_true(r.response.clientDataJSON instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.response.clientDataJSON),
CLIENT_DATA_JSON, "clientDataJSON returned is the same");
assert_true(r.response.authenticatorData instanceof ArrayBuffer);
assert_true(r.response.signature instanceof ArrayBuffer);
assert_array_equals(new Uint8Array(r.response.authenticatorData),
AUTHENTICATOR_DATA, "authenticator_data returned is the same");
assert_array_equals(new Uint8Array(r.response.signature),
SIGNATURE, "signature returned is the same");
assert_false('attestationObject' in r.response);
}