blob: 8437e9e76f2d125c51f217c1b6eb405013e7ce8b [file] [log] [blame]
<!DOCTYPE html>
<title>Web Authentication API: PublicKeyCredential's [[create]] success cases with a mock hid authenticator.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/util.js"></script>
<script src="./resources/cbor.js"></script>
<script>
// Default mock configuration. Tests need to override if they need different configuration.
if (window.testRunner)
testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testCreationMessageBase64] } });
function checkResult(credential)
{
// Check response
assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64));
assert_equals(credential.type, 'public-key');
assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64));
assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');
assert_not_exists(credential.getClientExtensionResults(), "appid");
// Check attestation
const attestationObject = CBOR.decode(credential.response.attestationObject);
assert_equals(attestationObject.fmt, "packed");
// Check authData
const authData = decodeAuthData(attestationObject.authData);
assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8");
assert_equals(authData.flags, 65);
assert_equals(authData.counter, 78);
assert_equals(bytesToHexString(authData.aaguid), "f8a011f38c0a4d15800617111f9edc7d");
assert_array_equals(authData.credentialID, Base64URL.parse(testHidCredentialIdBase64));
// Check packed attestation
assert_equals(attestationObject.attStmt.alg, -7);
assert_true(checkPublicKey(authData.publicKey));
assert_equals(attestationObject.attStmt.x5c.length, 1);
}
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with minimum options in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { authenticatorAttachment: "cross-platform" },
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { requireResidentKey: false },
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { userVerification: "preferred" },
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { userVerification: "discouraged" },
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { authenticatorAttachment: "cross-platform", requireResidentKey: false, userVerification: "preferred" },
timeout: 100
}
};
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with mixed options in a mock local authenticator.");
promise_test(t => {
const options = {
publicKey: {
rp: {
name: "localhost",
},
user: {
name: "John Appleseed",
id: Base64URL.parse(testUserhandleBase64),
displayName: "Appleseed",
},
challenge: Base64URL.parse("MTIzNDU2"),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
timeout: 100
}
};
promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "This request has been voided by a new request.");
return navigator.credentials.create(options).then(credential => {
checkResult(credential);
});
}, "PublicKeyCredential's [[create]] with two consecutive requests.");
</script>