1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
<!DOCTYPE html>
<title>Successful WebAuthn tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/common-inputs.js"></script>
<script src="resources/utils.js"></script>
<script>
"use strict";
let authenticator;
promise_test(async t => {
authenticator = await window.test_driver.add_virtual_authenticator({
protocol: "ctap1/u2f",
transport: "usb",
});
}, "Set up the test environment");
let credential;
let publicKey;
promise_test(async t => {
credential = await navigator.credentials.create({
publicKey: MAKE_CREDENTIAL_OPTIONS,
});
// Perform the validations the Relying Party should do against the credential.
// https://w3c.github.io/webauthn/#sctn-registering-a-new-credential
let jsonText =
new TextDecoder("utf-8").decode(credential.response.clientDataJSON);
let clientData = JSON.parse(jsonText);
assert_equals(clientData.type, "webauthn.create");
assert_equals(clientData.challenge, base64urlEncode(CHALLENGE));
assert_equals(clientData.origin, window.location.origin);
let attestationObject =
new Cbor(credential.response.attestationObject).getCBOR();
let rpIdHash = new Uint8Array(await crypto.subtle.digest(
{ name: "SHA-256" }, new TextEncoder("utf-8").encode(PUBLIC_KEY_RP.id)));
let authenticatorData = parseAuthenticatorData(attestationObject.authData);
assert_array_equals(authenticatorData.rpIdHash, rpIdHash)
assert_true(authenticatorData.flags.up);
assert_false(authenticatorData.flags.uv);
publicKey = authenticatorData.attestedCredentialData.credentialPublicKey;
assert_equals(publicKey.alg, PUBLIC_KEY_PARAMETERS[0].alg);
assert_equals(publicKey.type, 2 /* EC2 */);
assert_equals(authenticatorData.extensions, null);
assert_object_equals(credential.getClientExtensionResults(), {});
}, "Create a credential");
promise_test(async t => {
let assertion = await navigator.credentials.get({
publicKey: {
challenge: new TextEncoder("utf-8").encode(CHALLENGE),
rpId: PUBLIC_KEY_RP.id,
allowCredentials: [{
type: "public-key",
id: credential.rawId,
transports: ["usb"],
}],
userVerification: "discouraged",
},
});
// Perform the validations the Relying Party should do against the assertion.
// https://w3c.github.io/webauthn/#sctn-verifying-assertion
assert_object_equals(credential.rawId, assertion.rawId);
let jsonText =
new TextDecoder("utf-8").decode(assertion.response.clientDataJSON);
let clientData = JSON.parse(jsonText);
assert_equals(clientData.type, "webauthn.get");
assert_equals(clientData.challenge, base64urlEncode(CHALLENGE));
assert_equals(clientData.type, "webauthn.get");
assert_equals(clientData.origin, window.location.origin);
let binaryAuthenticatorData =
new Uint8Array(assertion.response.authenticatorData);
let authenticatorData = parseAuthenticatorData(binaryAuthenticatorData);
let rpIdHash = new Uint8Array(await crypto.subtle.digest(
{ name: "SHA-256" }, new TextEncoder("utf-8").encode(PUBLIC_KEY_RP.id)));
assert_array_equals(authenticatorData.rpIdHash, rpIdHash)
assert_true(authenticatorData.flags.up);
assert_false(authenticatorData.flags.uv);
assert_equals(authenticatorData.extensions, null);
assert_object_equals(credential.getClientExtensionResults(), {});
assert_equals(authenticatorData.attestedCredentialData, null);
let jwkPublicKey = coseObjectToJWK(publicKey);
let key = await crypto.subtle.importKey(
"jwk", jwkPublicKey, {name: "ECDSA", namedCurve: "P-256"},
/*extractable=*/false, ["verify"]);
let signature =
convertDERSignatureToSubtle(new Uint8Array(assertion.response.signature));
let clientDataJsonHash = new Uint8Array(await crypto.subtle.digest(
"SHA-256", assertion.response.clientDataJSON));
let signedData =
new Uint8Array(binaryAuthenticatorData.length + clientDataJsonHash.length);
signedData.set(binaryAuthenticatorData);
signedData.set(clientDataJsonHash, binaryAuthenticatorData.length);
assert_true(await crypto.subtle.verify(
{ name: "ECDSA", hash: "SHA-256" }, key, signature, signedData));
}, "Get an assertion");
promise_test(async t => {
await window.test_driver.remove_virtual_authenticator(authenticator);
}, "Clean up the test environment");
</script>
|