[WebAuthN] Import a JS CBOR coder
[WebKit-https.git] / LayoutTests / http / wpt / webauthn / public-key-credential-create-success-local.https.html
1 <!DOCTYPE html>
2 <title>Web Authentication API: PublicKeyCredential's [[create]] success cases with a mock local authenticator.</title>
3 <script src="/resources/testharness.js"></script>
4 <script src="/resources/testharnessreport.js"></script>
5 <script src="./resources/util.js"></script>
6 <script src="./resources/cbor.js"></script>
7 <script>
8     // Default mock configuration. Tests need to override if they need different configuration.
9     if (window.testRunner)
10         testRunner.setWebAuthenticationMockConfiguration({
11             local: {
12                 acceptAuthentication: true,
13                 acceptAttestation: true,
14                 privateKeyBase64: testES256PrivateKeyBase64,
15                 userCertificateBase64: testAttestationCertificateBase64,
16                 intermediateCACertificateBase64: testAttestationIssuingCACertificateBase64
17             }
18         });
19
20     function checkResult(credential)
21     {
22         // Check keychain
23         if (window.testRunner) {
24             assert_true(testRunner.keyExistsInKeychain(testRpId, testUserhandleBase64));
25             testRunner.cleanUpKeychain(testRpId);
26         }
27
28         // Check respond
29         assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testCredentialIdBase64));
30         assert_equals(credential.type, 'public-key');
31         assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testCredentialIdBase64));
32         assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443","hashAlgorithm":"SHA-256"}');
33         assert_throws("NotSupportedError", () => { credential.getClientExtensionResults() });
34
35         // Check attestation
36         const attestationObject = CBOR.decode(credential.response.attestationObject);
37         assert_equals(attestationObject.fmt, "Apple");
38         // Check authData
39         const authData = decodeAuthData(attestationObject.authData);
40         assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");
41         assert_equals(authData.flags, 69);
42         assert_equals(authData.counter, 0);
43         assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000");
44         assert_array_equals(authData.credentialID, Base64URL.parse(testCredentialIdBase64));
45         // Check self attestation
46         assert_equals(attestationObject.attStmt.alg, -7);
47         assert_true(checkPublicKey(authData.publicKey));
48         assert_equals(attestationObject.attStmt.x5c.length, 2);
49         assert_array_equals(attestationObject.attStmt.x5c[0], Base64URL.parse(testAttestationCertificateBase64));
50         assert_array_equals(attestationObject.attStmt.x5c[1], Base64URL.parse(testAttestationIssuingCACertificateBase64));
51
52         // Check signature
53         let publicKeyData = new Uint8Array(65);
54         publicKeyData[0] = 0x04;
55         publicKeyData.set(authData.publicKey['-2'], 1);
56         publicKeyData.set(authData.publicKey['-3'], 33);
57         return crypto.subtle.importKey("raw", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => {
58             return crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, publicKey, extractRawSignature(attestationObject.attStmt.sig), attestationObject.authData).then( verified => {
59                 assert_true(verified);
60             });
61         });
62     }
63
64     promise_test(t => {
65         const options = {
66             publicKey: {
67                 rp: {
68                     name: "localhost",
69                 },
70                 user: {
71                     name: "John Appleseed",
72                     id: Base64URL.parse(testUserhandleBase64),
73                     displayName: "Appleseed",
74                 },
75                 challenge: Base64URL.parse("MTIzNDU2"),
76                 pubKeyCredParams: [{ type: "public-key", alg: -7 }],
77             }
78         };
79
80         return navigator.credentials.create(options).then(credential => {
81             checkResult(credential);
82         });
83     }, "PublicKeyCredential's [[create]] with minimum options in a mock local authenticator.");
84
85     promise_test(t => {
86         const options = {
87             publicKey: {
88                 rp: {
89                     name: "localhost",
90                 },
91                 user: {
92                     name: "John Appleseed",
93                     id: Base64URL.parse(testUserhandleBase64),
94                     displayName: "Appleseed",
95                 },
96                 challenge: Base64URL.parse("MTIzNDU2"),
97                 pubKeyCredParams: [{ type: "public-key", alg: -7 }],
98                 authenticatorSelection: { authenticatorAttachment: "platform" }
99             }
100         };
101
102         return navigator.credentials.create(options).then(credential => {
103             checkResult(credential);
104         });
105     }, "PublicKeyCredential's [[create]] with authenticatorSelection { 'platform' } in a mock local authenticator.");
106
107     promise_test(t => {
108         const options = {
109             publicKey: {
110                 rp: {
111                     name: "example.com"
112                 },
113                 user: {
114                     name: "John Appleseed",
115                     id: Base64URL.parse(testUserhandleBase64),
116                     displayName: "John",
117                 },
118                 challenge: asciiToUint8Array("123456"),
119                 pubKeyCredParams: [{ type: "public-key", alg: -7 }],
120                 excludeCredentials: [
121                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
122                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
123                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }
124                 ]
125             }
126         };
127         if (window.testRunner)
128             testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
129
130         return navigator.credentials.create(options).then(credential => {
131             checkResult(credential);
132         });
133     }, "PublicKeyCredential's [[create]] with matched exclude credential ids but not transports in a mock local authenticator.");
134 </script>