| <!DOCTYPE html> |
| <title>Web Authentication API: PublicKeyCredential's [[get]] failure cases.</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="./resources/util.js"></script> |
| <script> |
| // Default mock configuration. Tests need to override if they need different configuration. |
| if (window.testRunner) |
| testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } }); |
| |
| function checkResult(credential) |
| { |
| if (window.testRunner) |
| testRunner.cleanUpKeychain(testRpId); |
| |
| // Check respond |
| assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testCredentialIdBase64)); |
| assert_equals(credential.type, 'public-key'); |
| assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testCredentialIdBase64)); |
| assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); |
| assert_equals(bytesToHexString(credential.response.userHandle), "00010203040506070809"); |
| assert_not_exists(credential.getClientExtensionResults(), "appid"); |
| |
| // Check authData |
| const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData)); |
| assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); |
| assert_equals(authData.flags, 5); |
| assert_equals(authData.counter, 0); |
| |
| // Check signature |
| return crypto.subtle.importKey("raw", Base64URL.parse(testES256PublicKeyBase64), { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => { |
| return crypto.subtle.digest("sha-256", credential.response.clientDataJSON).then ( hash => { |
| // credential.response.signature is in ASN.1 and WebCrypto expect signatures provides in r|s. |
| return crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, publicKey, extractRawSignature(credential.response.signature), concatenateBuffers(credential.response.authenticatorData, hash)).then( verified => { |
| assert_true(verified); |
| assert_not_exists(credential.getClientExtensionResults(), "appid"); |
| }); |
| }); |
| }); |
| } |
| |
| promise_test(t => { |
| const options = { |
| publicKey: { |
| challenge: Base64URL.parse("MTIzNDU2") |
| } |
| }; |
| |
| if (window.testRunner) |
| testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); |
| return navigator.credentials.get(options).then(credential => { |
| return checkResult(credential); |
| }); |
| }, "PublicKeyCredential's [[get]] with minimum options in a mock local authenticator."); |
| |
| promise_test(t => { |
| const options = { |
| publicKey: { |
| challenge: Base64URL.parse("MTIzNDU2"), |
| allowCredentials: [ |
| { type: "public-key", id: Base64URL.parse(testUserhandleBase64), transports: ["internal"] }, |
| { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] } |
| ] |
| } |
| }; |
| |
| if (window.testRunner) |
| testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); |
| return navigator.credentials.get(options).then(credential => { |
| return checkResult(credential); |
| }); |
| }, "PublicKeyCredential's [[get]] with matched allow credentials in a mock local authenticator."); |
| </script> |