| <!DOCTYPE html><!-- webkit-test-runner [ WebAuthenticationModernEnabled=false ] --> |
| <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> |
| function checkResult(credential, credentialID, privateKeyBase64, isUV = true) |
| { |
| if (window.testRunner) |
| testRunner.cleanUpKeychain(testRpId, base64encode(credentialID)); |
| |
| // Check respond |
| assert_array_equals(Base64URL.parse(credential.id), credentialID); |
| assert_equals(credential.type, 'public-key'); |
| assert_array_equals(new Uint8Array(credential.rawId), credentialID); |
| assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); |
| assert_array_equals(new Uint8Array(credential.response.userHandle), Base64URL.parse(testUserhandleBase64)); |
| assert_not_own_property(credential.getClientExtensionResults(), "appid"); |
| |
| // Check authData |
| const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData)); |
| assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); |
| if (isUV) |
| assert_equals(authData.flags, 5); |
| else |
| assert_equals(authData.flags, 1); |
| assert_equals(authData.counter, 0); |
| |
| // Check signature |
| return crypto.subtle.importKey("raw", Base64URL.parse(privateKeyBase64).slice(0, 65), { 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_own_property(credential.getClientExtensionResults(), "appid"); |
| }); |
| }); |
| }); |
| } |
| |
| promise_test(async t => { |
| const privateKeyBase64 = await generatePrivateKeyBase64(); |
| const credentialID = await calculateCredentialID(privateKeyBase64); |
| const credentialIDBase64 = base64encode(credentialID); |
| // Default mock configuration. Tests need to override if they need different configuration. |
| if (window.internals) |
| internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } }); |
| |
| const options = { |
| publicKey: { |
| challenge: Base64URL.parse("MTIzNDU2") |
| } |
| }; |
| |
| if (window.testRunner) |
| testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64); |
| return navigator.credentials.get(options).then(credential => { |
| return checkResult(credential, credentialID, privateKeyBase64); |
| }); |
| }, "PublicKeyCredential's [[get]] with minimum options in a mock local authenticator."); |
| |
| promise_test(async t => { |
| const privateKeyBase64 = await generatePrivateKeyBase64(); |
| const credentialID = await calculateCredentialID(privateKeyBase64); |
| const credentialIDBase64 = base64encode(credentialID); |
| // Default mock configuration. Tests need to override if they need different configuration. |
| if (window.internals) |
| internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } }); |
| |
| const options = { |
| publicKey: { |
| challenge: Base64URL.parse("MTIzNDU2"), |
| allowCredentials: [ |
| { type: "public-key", id: Base64URL.parse(testUserhandleBase64), transports: ["internal"] }, |
| { type: "public-key", id: credentialID, transports: ["internal"] } |
| ] |
| } |
| }; |
| |
| if (window.testRunner) |
| testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64); |
| return navigator.credentials.get(options).then(credential => { |
| return checkResult(credential, credentialID, privateKeyBase64); |
| }); |
| }, "PublicKeyCredential's [[get]] with matched allow credentials in a mock local authenticator."); |
| |
| promise_test(async t => { |
| const privateKeyBase64 = await generatePrivateKeyBase64(); |
| const credentialID = await calculateCredentialID(privateKeyBase64); |
| const credentialIDBase64 = base64encode(credentialID); |
| // Default mock configuration. Tests need to override if they need different configuration. |
| if (window.internals) |
| internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "presence", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } }); |
| |
| const options = { |
| publicKey: { |
| challenge: Base64URL.parse("MTIzNDU2") |
| } |
| }; |
| |
| if (window.testRunner) |
| testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64); |
| return navigator.credentials.get(options).then(credential => { |
| return checkResult(credential, credentialID, privateKeyBase64, false); |
| }); |
| }, "PublicKeyCredential's [[get]] with user presence in a mock local authenticator."); |
| </script> |