Changeset 236842 in webkit
- Timestamp:
- Oct 4, 2018 12:32:14 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 23 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r236841 r236842 1 2018-10-04 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Move time out control from WebProcess to UIProcess 4 https://bugs.webkit.org/show_bug.cgi?id=189642 5 <rdar://problem/44476765> 6 7 Reviewed by Chris Dumez. 8 9 This patch also fixes some flaky behaviours regarding to the dirty ASN.1 decoder. 10 11 * http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt: Added. 12 * http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html. 13 * http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt: 14 * http/wpt/webauthn/public-key-credential-create-failure-local.https.html: 15 * http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt: 16 * http/wpt/webauthn/public-key-credential-create-failure.https.html: 17 * http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt: Added. 18 * http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html. 19 * http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt: 20 * http/wpt/webauthn/public-key-credential-get-failure-local.https.html: 21 * http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt: 22 * http/wpt/webauthn/public-key-credential-get-failure.https.html: 23 * http/wpt/webauthn/resources/util.js: 24 1 25 2018-10-04 Chris Dumez <cdumez@apple.com> 2 26 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html
r236841 r236842 1 1 <!DOCTYPE html> 2 <title>Web Authentication API: PublicKeyCredential's [[create]] failure cases with a mock local authenticator.</title>2 <title>Web Authentication API: PublicKeyCredential's [[create]] silent failure cases with a mock local authenticator.</title> 3 3 <script src="/resources/testharness.js"></script> 4 4 <script src="/resources/testharnessreport.js"></script> … … 7 7 // Default mock configuration. Tests need to override if they need different configuration. 8 8 if (window.testRunner) 9 testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });9 testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } }); 10 10 11 11 promise_test(t => { … … 22 22 challenge: asciiToUint8Array("123456"), 23 23 pubKeyCredParams: [{ type: "public-key", alg: -35 }, { type: "public-key", alg: -257 }], // ES384, RS256 24 timeout: 10 24 25 } 25 26 }; 26 return promiseRejects(t, "Not SupportedError", navigator.credentials.create(options), "The platform attached authenticator doesn't support any provided PublicKeyCredentialParameters.");27 }, "PublicKeyCredential's [[create]] with unsupported public key credential parametersin a mock local authenticator.");27 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out."); 28 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator."); 28 29 29 30 promise_test(t => { … … 40 41 challenge: asciiToUint8Array("123456"), 41 42 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 42 excludeCredentials: [{ type: "public-key", id: Base64URL.parse(testCredentialIdBase64) }] 43 excludeCredentials: [{ type: "public-key", id: Base64URL.parse(testCredentialIdBase64) }], 44 timeout: 10 43 45 } 44 46 }; 45 47 if (window.testRunner) 46 48 testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); 47 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), " At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.").then(() => {49 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => { 48 50 if (window.testRunner) 49 51 testRunner.cleanUpKeychain(testRpId); 50 52 }); 51 }, "PublicKeyCredential's [[create]] with matched exclude credentials in a mock local authenticator.");53 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 2"); 52 54 53 55 promise_test(t => { … … 69 71 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }, 70 72 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] } 71 ] 73 ], 74 timeout: 10 72 75 } 73 76 }; 74 77 if (window.testRunner) 75 78 testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); 76 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), " At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.").then(() => {79 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => { 77 80 if (window.testRunner) 78 81 testRunner.cleanUpKeychain(testRpId); 79 82 }); 80 }, "PublicKeyCredential's [[create]] with matched exclude credentials in a mock local authenticator. 2nd");83 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 3"); 81 84 82 85 promise_test(t => { … … 92 95 }, 93 96 challenge: asciiToUint8Array("123456"), 94 pubKeyCredParams: [{ type: "public-key", alg: -7 }] 97 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 98 timeout: 10 95 99 } 96 100 }; 97 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), " Couldn't get user consent.");98 }, "PublicKeyCredential's [[create]] with out user consent in a mock local authenticator.");101 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out."); 102 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 4"); 99 103 100 104 promise_test(t => { … … 110 114 }, 111 115 challenge: asciiToUint8Array("123456"), 112 pubKeyCredParams: [{ type: "public-key", alg: -7 }] 116 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 117 timeout: 10 113 118 } 114 119 }; 115 120 if (window.testRunner) 116 testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });117 return promiseRejects(t, " UnknownError", navigator.credentials.create(options), "Unknown internal error.");118 }, "PublicKeyCredential's [[create]] with out attestation in a mock local authenticator.");121 testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false } }); 122 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out."); 123 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 5"); 119 124 120 125 promise_test(t => { … … 130 135 }, 131 136 challenge: asciiToUint8Array("123456"), 132 pubKeyCredParams: [{ type: "public-key", alg: -7 }] 137 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 138 timeout: 10 133 139 } 134 140 }; 135 141 if (window.testRunner) { 136 testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });142 testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false } }); 137 143 testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); 138 144 } 139 return promiseRejects(t, " UnknownError", navigator.credentials.create(options), "Unknown internal error.").then(() => {145 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => { 140 146 if (window.testRunner) 141 147 assert_false(testRunner.keyExistsInKeychain(testRpId, testUserhandleBase64)); 142 148 }); 143 }, "PublicKeyCredential's [[create]] deleting old credential in a mock local authenticator.");149 }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 6"); 144 150 </script> -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt
r236481 r236842 6 6 PASS PublicKeyCredential's [[create]] without attestation in a mock local authenticator. 7 7 PASS PublicKeyCredential's [[create]] deleting old credential in a mock local authenticator. 8 PASS PublicKeyCredential's [[create]] with timeout in a mock local authenticator. 8 9 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html
r236686 r236842 142 142 }); 143 143 }, "PublicKeyCredential's [[create]] deleting old credential in a mock local authenticator."); 144 145 promise_test(function(t) { 146 const options = { 147 publicKey: { 148 rp: { 149 name: "example.com" 150 }, 151 user: { 152 name: "John Appleseed", 153 id: asciiToUint8Array("123456"), 154 displayName: "John", 155 }, 156 challenge: asciiToUint8Array("123456"), 157 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 158 timeout: 10, 159 authenticatorSelection: { authenticatorAttachment: "cross-platform" } 160 } 161 }; 162 163 if (window.testRunner) 164 testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } }); 165 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out."); 166 }, "PublicKeyCredential's [[create]] with timeout in a mock local authenticator."); 144 167 </script> -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt
r236625 r236842 1 1 2 PASS PublicKeyCredential's [[create]] with timeout 2 3 PASS PublicKeyCredential's [[create]] with a mismatched RP ID 3 4 PASS PublicKeyCredential's [[create]] with an empty pubKeyCredParams -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html
r236625 r236842 9 9 testRunner.setWebAuthenticationMockConfiguration({ }); 10 10 11 // FIXME(189642): Re-enable the following test. 12 // promise_test(function(t) { 13 // const options = { 14 // publicKey: { 15 // rp: { 16 // name: "example.com" 17 // }, 18 // user: { 19 // name: "John Appleseed", 20 // id: asciiToUint8Array("123456"), 21 // displayName: "John", 22 // }, 23 // challenge: asciiToUint8Array("123456"), 24 // pubKeyCredParams: [{ type: "public-key", alg: -7 }], 25 // timeout: 0, 26 // } 27 // }; 28 // 29 // return promiseRejects(t, "NotAllowedError", 30 // navigator.credentials.create(options), "Operation timed out."); 31 // }, "PublicKeyCredential's [[create]] with timeout"); 11 promise_test(function(t) { 12 const options = { 13 publicKey: { 14 rp: { 15 name: "example.com" 16 }, 17 user: { 18 name: "John Appleseed", 19 id: asciiToUint8Array("123456"), 20 displayName: "John", 21 }, 22 challenge: asciiToUint8Array("123456"), 23 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 24 timeout: 10, 25 } 26 }; 27 28 return promiseRejects(t, "NotAllowedError", 29 navigator.credentials.create(options), "Operation timed out."); 30 }, "PublicKeyCredential's [[create]] with timeout"); 32 31 33 32 promise_test(function(t) { -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html
r236841 r236842 7 7 // Default mock configuration. Tests need to override if they need different configuration. 8 8 if (window.testRunner) 9 testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });9 testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } }); 10 10 11 11 promise_test(t => { … … 18 18 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }, 19 19 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] } 20 ] 20 ], 21 timeout: 10 21 22 } 22 23 }; 23 24 24 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), " No matched credentials are found in the platform attached authenticator.");25 }, "PublicKeyCredential's [[get]] with no matched credentialsin a mock local authenticator.");25 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out."); 26 }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator."); 26 27 27 28 promise_test(t => { … … 31 32 allowCredentials: [ 32 33 { type: "public-key", id: Base64URL.parse(testUserhandleBase64) } 33 ] 34 ], 35 timeout: 10 34 36 } 35 37 }; … … 37 39 if (window.testRunner) 38 40 testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); 39 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), " No matched credentials are found in the platform attached authenticator.").then(() => {41 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.").then(() => { 40 42 if (window.testRunner) 41 43 testRunner.cleanUpKeychain(testRpId); 42 44 }); 43 }, "PublicKeyCredential's [[get]] with no matched credentials in a mock local authenticator. 2nd");45 }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 2"); 44 46 45 47 promise_test(t => { 46 48 const options = { 47 49 publicKey: { 48 challenge: asciiToUint8Array("123456") 50 challenge: asciiToUint8Array("123456"), 51 timeout: 10 49 52 } 50 53 }; … … 52 55 if (window.testRunner) 53 56 testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64); 54 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), " Couldn't get user consent.").then(() => {57 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.").then(() => { 55 58 if (window.testRunner) 56 59 testRunner.cleanUpKeychain(testRpId); 57 60 }); 58 }, "PublicKeyCredential's [[get]] with out user consent in a mock local authenticator.");61 }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 3"); 59 62 </script> -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt
r236481 r236842 3 3 PASS PublicKeyCredential's [[get]] with no matched credentials in a mock local authenticator. 2nd 4 4 PASS PublicKeyCredential's [[get]] without user consent in a mock local authenticator. 5 PASS PublicKeyCredential's [[get]] with timeout in a mock local authenticator. 5 6 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html
r236686 r236842 57 57 }); 58 58 }, "PublicKeyCredential's [[get]] without user consent in a mock local authenticator."); 59 60 promise_test(t => { 61 const options = { 62 publicKey: { 63 challenge: asciiToUint8Array("123456"), 64 allowCredentials: [ 65 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] }, 66 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] }, 67 { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] } 68 ], 69 timeout: 10 70 } 71 }; 72 73 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out."); 74 }, "PublicKeyCredential's [[get]] with timeout in a mock local authenticator."); 59 75 </script> -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt
r236625 r236842 1 1 2 PASS PublicKeyCredential's [[get]] with timeout 2 3 PASS PublicKeyCredential's [[get]] with a mismatched RP ID 3 4 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https.html
r236625 r236842 9 9 testRunner.setWebAuthenticationMockConfiguration({ }); 10 10 11 // FIXME(189642): Re-enable the following test. 12 // promise_test(function(t) { 13 // const options = { 14 // publicKey: { 15 // challenge: asciiToUint8Array("123456"), 16 // timeout: 0, 17 // } 18 // }; 19 // 20 // return promiseRejects(t, "NotAllowedError", 21 // navigator.credentials.get(options), "Operation timed out."); 22 // }, "PublicKeyCredential's [[get]] with timeout"); 11 promise_test(t => { 12 const options = { 13 publicKey: { 14 challenge: asciiToUint8Array("123456"), 15 timeout: 10 16 } 17 }; 23 18 24 promise_test(function(t) { 19 return promiseRejects(t, "NotAllowedError", 20 navigator.credentials.get(options), "Operation timed out."); 21 }, "PublicKeyCredential's [[get]] with timeout"); 22 23 promise_test(t => { 25 24 const options = { 26 25 publicKey: { 27 26 rpId: "example.com", 28 challenge: asciiToUint8Array("123456") ,27 challenge: asciiToUint8Array("123456") 29 28 } 30 29 }; 30 31 31 return promiseRejects(t, "SecurityError", 32 32 navigator.credentials.get(options), "The origin of the document is not a registrable domain suffix of the provided RP ID."); -
trunk/LayoutTests/http/wpt/webauthn/resources/util.js
r236686 r236842 173 173 const signature = new Uint8Array(asn1signature); 174 174 let tmp = new Uint8Array(64); 175 175 176 const rStart = signature[3] - 32; 176 tmp.set(new Uint8Array(signature.slice(4 + rStart, 36 + rStart)), 0); 177 if (rStart >= 0) 178 tmp.set(new Uint8Array(signature.slice(4 + rStart, 36 + rStart)), 0); 179 else 180 tmp.set(new Uint8Array(signature.slice(4, 36 + rStart)), -rStart); 181 177 182 const sStart = signature[37 + rStart] - 32; 178 tmp.set(new Uint8Array(signature.slice(38 + rStart + sStart)), 32); 183 if (sStart >= 0) 184 tmp.set(new Uint8Array(signature.slice(38 + rStart + sStart)), 32); 185 else 186 tmp.set(new Uint8Array(signature.slice(38 + rStart)), 32 - sStart); 187 179 188 return tmp.buffer; 180 189 } -
trunk/Source/WebCore/ChangeLog
r236841 r236842 1 2018-10-04 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Move time out control from WebProcess to UIProcess 4 https://bugs.webkit.org/show_bug.cgi?id=189642 5 <rdar://problem/44476765> 6 7 Reviewed by Chris Dumez. 8 9 Since now the control unit of WebAuthN has been moved to UI Process, i.e. AuthenticatorManager, 10 the time out timer should move to UI Process as well. 11 12 Tests: http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html 13 http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html 14 15 * Modules/webauthn/AuthenticatorCoordinator.cpp: 16 (WebCore::AuthenticatorCoordinator::create const): 17 (WebCore::AuthenticatorCoordinator::discoverFromExternalSource const): 18 (WebCore::AuthenticatorCoordinatorInternal::initTimeoutTimer): Deleted. 19 (WebCore::AuthenticatorCoordinatorInternal::didTimeoutTimerFire): Deleted. 20 * Modules/webauthn/PublicKeyCredentialCreationOptions.h: 21 (WebCore::PublicKeyCredentialCreationOptions::encode const): 22 (WebCore::PublicKeyCredentialCreationOptions::decode): 23 * Modules/webauthn/PublicKeyCredentialRequestOptions.h: 24 (WebCore::PublicKeyCredentialRequestOptions::encode const): 25 (WebCore::PublicKeyCredentialRequestOptions::decode): 26 1 27 2018-10-04 Chris Dumez <cdumez@apple.com> 2 28 -
trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp
r235888 r236842 39 39 #include "PublicKeyCredentialRequestOptions.h" 40 40 #include "SecurityOrigin.h" 41 #include "Timer.h"42 41 #include <pal/crypto/CryptoDigest.h> 43 42 #include <wtf/JSONValues.h> … … 83 82 } 84 83 85 // FIXME(181947): We should probably trim timeOutInMs to some max allowable number.86 static std::unique_ptr<Timer> initTimeoutTimer(std::optional<unsigned long> timeOutInMs, const CredentialPromise& promise)87 {88 if (!timeOutInMs)89 return nullptr;90 91 auto timer = std::make_unique<Timer>([promise = promise] () mutable {92 promise.reject(Exception { NotAllowedError, "Operation timed out."_s });93 });94 timer->startOneShot(Seconds::fromMilliseconds(*timeOutInMs));95 return timer;96 }97 98 static bool didTimeoutTimerFire(Timer* timer)99 {100 if (!timer)101 return false;102 if (!timer->isActive())103 return true;104 timer->stop();105 return false;106 }107 108 84 } // namespace AuthenticatorCoordinatorInternal 109 85 … … 131 107 } 132 108 133 // Step 4 & 17.134 std::unique_ptr<Timer> timeoutTimer = initTimeoutTimer(options.timeout, promise);135 136 109 // Step 5-7. 137 110 // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not. … … 157 130 auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson); 158 131 159 // Step 18-21.132 // Step 4, 17-21. 160 133 // Only platform attachments will be supported at this stage. Assuming one authenticator per device. 161 134 // Also, resident keys, user verifications and direct attestation are enforced at this tage. … … 166 139 } 167 140 168 auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), timeoutTimer = WTFMove(timeoutTimer), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable { 169 if (didTimeoutTimerFire(timeoutTimer.get())) 170 return; 141 auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable { 171 142 if (abortSignal && abortSignal->aborted()) { 172 143 promise.reject(Exception { AbortError, "Aborted by AbortSignal."_s }); … … 199 170 } 200 171 201 // Step 4 & 16.202 std::unique_ptr<Timer> timeoutTimer = initTimeoutTimer(options.timeout, promise);203 204 172 // Step 5-7. 205 173 // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not. … … 217 185 auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson); 218 186 219 // Step 14-15, 17-19.187 // Step 4, 14-19. 220 188 // Only platform attachments will be supported at this stage. Assuming one authenticator per device. 221 189 // Also, resident keys, user verifications and direct attestation are enforced at this tage. … … 226 194 } 227 195 228 auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), timeoutTimer = WTFMove(timeoutTimer), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable { 229 if (didTimeoutTimerFire(timeoutTimer.get())) 230 return; 196 auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable { 231 197 if (abortSignal && abortSignal->aborted()) { 232 198 promise.reject(Exception { AbortError, "Aborted by AbortSignal."_s }); -
trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h
r236481 r236842 79 79 Vector<Parameters> pubKeyCredParams; 80 80 81 std::optional<unsigned long> timeout;81 std::optional<unsigned> timeout; 82 82 Vector<PublicKeyCredentialDescriptor> excludeCredentials; 83 83 std::optional<AuthenticatorSelectionCriteria> authenticatorSelection; … … 126 126 encoder << static_cast<uint64_t>(user.id.length()); 127 127 encoder.encodeFixedLengthData(user.id.data(), user.id.length(), 1); 128 encoder << user.displayName << user.name << user.icon << pubKeyCredParams << excludeCredentials << authenticatorSelection;128 encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection; 129 129 } 130 130 … … 149 149 if (!decoder.decode(result.pubKeyCredParams)) 150 150 return std::nullopt; 151 152 std::optional<std::optional<unsigned>> timeout; 153 decoder >> timeout; 154 if (!timeout) 155 return std::nullopt; 156 result.timeout = WTFMove(*timeout); 157 151 158 if (!decoder.decode(result.excludeCredentials)) 152 159 return std::nullopt; … … 156 163 if (!authenticatorSelection) 157 164 return std::nullopt; 158 result.authenticatorSelection = WTFMove( authenticatorSelection.value());165 result.authenticatorSelection = WTFMove(*authenticatorSelection); 159 166 160 167 return result; -
trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialRequestOptions.h
r230012 r236842 36 36 struct PublicKeyCredentialRequestOptions { 37 37 BufferSource challenge; 38 std::optional<unsigned long> timeout;38 std::optional<unsigned> timeout; 39 39 mutable String rpId; 40 40 Vector<PublicKeyCredentialDescriptor> allowCredentials; … … 48 48 void PublicKeyCredentialRequestOptions::encode(Encoder& encoder) const 49 49 { 50 encoder << rpId << allowCredentials;50 encoder << timeout << rpId << allowCredentials; 51 51 } 52 52 … … 55 55 { 56 56 PublicKeyCredentialRequestOptions result; 57 58 std::optional<std::optional<unsigned>> timeout; 59 decoder >> timeout; 60 if (!timeout) 61 return std::nullopt; 62 result.timeout = WTFMove(*timeout); 63 57 64 if (!decoder.decode(result.rpId)) 58 65 return std::nullopt; -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r236840 r236842 18820 18820 sourceTree = "<group>"; 18821 18821 }; 18822 574F55DD204F3744002948C6 /* cocoa */ = {18823 isa = PBXGroup;18824 children = (18825 );18826 path = cocoa;18827 sourceTree = "<group>";18828 };18829 18822 57C7A6881E56946D00C67D71 /* credentialmanagement */ = { 18830 18823 isa = PBXGroup; … … 18868 18861 children = ( 18869 18862 57303BB32006C6ED00355965 /* cbor */, 18870 574F55DD204F3744002948C6 /* cocoa */,18871 18863 57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */, 18872 18864 57303C292009B2FC00355965 /* AuthenticatorAssertionResponse.idl */, -
trunk/Source/WebKit/ChangeLog
r236840 r236842 1 2018-10-04 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Move time out control from WebProcess to UIProcess 4 https://bugs.webkit.org/show_bug.cgi?id=189642 5 <rdar://problem/44476765> 6 7 Reviewed by Chris Dumez. 8 9 Besides adding a time out timer in the AuthenticatorManager, this patch also adds a new 10 option in MockWebAuthenticationConfiguration to turn on silent failure which is the 11 default policy of treating authenticators' error as suggested by spec. 12 13 * UIProcess/API/C/WKWebsiteDataStoreRef.cpp: 14 (WKWebsiteDataStoreSetWebAuthenticationMockConfiguration): 15 * UIProcess/WebAuthentication/AuthenticatorManager.cpp: 16 (WebKit::AuthenticatorManagerInternal::collectTransports): 17 (WebKit::AuthenticatorManager::makeCredential): 18 (WebKit::AuthenticatorManager::getAssertion): 19 (WebKit::AuthenticatorManager::respondReceived): 20 (WebKit::AuthenticatorManager::initTimeOutTimer): 21 * UIProcess/WebAuthentication/AuthenticatorManager.h: 22 (WebKit::AuthenticatorManager::requestTimeOutTimer): 23 * UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp: 24 (WebKit::MockAuthenticatorManager::respondReceivedInternal): 25 * UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h: 26 1 27 2018-10-04 Yuhan Wu <yuhan_wu@apple.com> 2 28 -
trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
r236686 r236842 578 578 MockWebAuthenticationConfiguration configuration; 579 579 580 auto silentFailureRef = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("SilentFailure")).get())); 581 if (silentFailureRef) 582 configuration.silentFailure = WKBooleanGetValue(silentFailureRef); 583 580 584 auto localRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Local")).get())); 581 585 if (localRef) { -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
r236481 r236842 39 39 40 40 const size_t maxTransportNumber = 1; 41 // Suggested by WebAuthN spec as of 7 August 2018. 42 const unsigned maxTimeOutValue = 120000; 41 43 42 44 // FIXME(188623, 188624, 188625): Support USB, NFC and BLE authenticators. … … 50 52 } 51 53 52 if (authenticatorSelection .value().authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::Platform) {54 if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::Platform) { 53 55 auto addResult = result.add(AuthenticatorTransport::Internal); 54 56 ASSERT_UNUSED(addResult, addResult.isNewEntry); 55 57 return result; 56 58 } 57 if (authenticatorSelection .value().authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform)59 if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform) 58 60 return result; 59 61 … … 105 107 m_pendingRequestData = { hash, true, options, { } }; 106 108 m_pendingCompletionHandler = WTFMove(callback); 109 initTimeOutTimer(options.timeout); 107 110 108 111 // 2. Get available transports and start discovering authenticators on them. … … 122 125 m_pendingRequestData = { hash, false, { }, options }; 123 126 m_pendingCompletionHandler = WTFMove(callback); 127 initTimeOutTimer(options.timeout); 124 128 125 129 // 2. Get available transports and start discovering authenticators on them. … … 148 152 { 149 153 ASSERT(RunLoop::isMain()); 154 ASSERT(m_requestTimeOutTimer); 155 if (!m_requestTimeOutTimer->isActive()) 156 return; 157 150 158 ASSERT(m_pendingCompletionHandler); 151 // FIXME(189642)152 159 if (WTF::holds_alternative<PublicKeyCredentialData>(respond)) { 153 160 m_pendingCompletionHandler(WTFMove(respond)); 154 161 clearState(); 162 m_requestTimeOutTimer->stop(); 155 163 return; 156 164 } … … 179 187 } 180 188 189 void AuthenticatorManager::initTimeOutTimer(const std::optional<unsigned>& timeOutInMs) 190 { 191 using namespace AuthenticatorManagerInternal; 192 193 unsigned timeOutInMsValue = std::min(maxTimeOutValue, timeOutInMs.value_or(maxTimeOutValue)); 194 195 m_requestTimeOutTimer = std::make_unique<Timer>([context = this]() mutable { 196 context->m_pendingCompletionHandler((ExceptionData { NotAllowedError, "Operation timed out."_s })); 197 context->clearState(); 198 }); 199 m_requestTimeOutTimer->startOneShot(Seconds::fromMilliseconds(timeOutInMsValue)); 200 } 201 181 202 } // namespace WebKit 182 203 -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h
r236481 r236842 33 33 #include <WebCore/ExceptionData.h> 34 34 #include <WebCore/PublicKeyCredentialData.h> 35 #include <WebCore/Timer.h> 35 36 #include <wtf/CompletionHandler.h> 36 37 #include <wtf/HashSet.h> … … 58 59 protected: 59 60 Callback& pendingCompletionHandler() { return m_pendingCompletionHandler; } 61 WebCore::Timer* requestTimeOutTimer() { return m_requestTimeOutTimer.get(); } 60 62 void clearState(); 61 63 … … 73 75 74 76 void startDiscovery(const TransportSet&); 77 void initTimeOutTimer(const std::optional<unsigned>& timeOutInMs); 75 78 76 79 // Request: We only allow one request per time. 77 80 WebAuthenticationRequestData m_pendingRequestData; 78 81 Callback m_pendingCompletionHandler; 82 std::unique_ptr<WebCore::Timer> m_requestTimeOutTimer; 79 83 80 84 Vector<UniqueRef<AuthenticatorTransportService>> m_services; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp
r236481 r236842 43 43 void MockAuthenticatorManager::respondReceivedInternal(Respond&& respond) 44 44 { 45 if (m_testConfiguration.silentFailure) 46 return; 47 45 48 pendingCompletionHandler()(WTFMove(respond)); 46 49 clearState(); 50 requestTimeOutTimer()->stop(); 47 51 } 48 52 -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h
r236686 r236842 39 39 }; 40 40 41 bool silentFailure { false }; 41 42 std::optional<Local> local; 42 43 }; -
trunk/Tools/ChangeLog
r236840 r236842 1 2018-10-04 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Move time out control from WebProcess to UIProcess 4 https://bugs.webkit.org/show_bug.cgi?id=189642 5 <rdar://problem/44476765> 6 7 Reviewed by Chris Dumez. 8 9 * WebKitTestRunner/InjectedBundle/TestRunner.cpp: 10 (WTR::TestRunner::setWebAuthenticationMockConfiguration): 11 1 12 2018-10-04 YUHAN WU <yuhan_wu@apple.com> 2 13 -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
r236690 r236842 2356 2356 Vector<WKRetainPtr<WKTypeRef>> configurationValues; 2357 2357 2358 JSRetainPtr<JSStringRef> silentFailurePropertyName(Adopt, JSStringCreateWithUTF8CString("silentFailure")); 2359 JSValueRef silentFailureValue = JSObjectGetProperty(context, configuration, silentFailurePropertyName.get(), 0); 2360 if (!JSValueIsUndefined(context, silentFailureValue)) { 2361 if (!JSValueIsBoolean(context, silentFailureValue)) 2362 return; 2363 bool silentFailure = JSValueToBoolean(context, silentFailureValue); 2364 configurationKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("SilentFailure") }); 2365 configurationValues.append(adoptWK(WKBooleanCreate(silentFailure)).get()); 2366 } 2367 2358 2368 JSRetainPtr<JSStringRef> localPropertyName(Adopt, JSStringCreateWithUTF8CString("local")); 2359 2369 JSValueRef localValue = JSObjectGetProperty(context, configuration, localPropertyName.get(), 0); 2360 if (!JSValueIs Null(context, localValue)) {2370 if (!JSValueIsUndefined(context, localValue) && !JSValueIsNull(context, localValue)) { 2361 2371 if (!JSValueIsObject(context, localValue)) 2362 2372 return;
Note: See TracChangeset
for help on using the changeset viewer.