Changeset 284413 in webkit


Ignore:
Timestamp:
Oct 18, 2021 5:07:29 PM (9 months ago)
Author:
commit-queue@webkit.org
Message:

[WebAuthn] Obtain consent to create new credential when platform authenticator in excludedCredentials
https://bugs.webkit.org/show_bug.cgi?id=219813
<rdar://problem/72484635>

Currently, whenever the platform authenticator is within excludedCredentials during makeCredential we
always return NotAllowedError and merely flash a consent screen. This does not match the spec per Step 3.1
of makeCredential (https://w3c.github.io/webauthn/#sctn-op-make-cred). Instead, we should always obtain consent
and return a different error depending on consent was obtained.

Source/WebKit:

A fixme to add this was inadvertently removed in https://bugs.webkit.org/attachment.cgi?id=393180&action=prettypatch

Patch by John Pascoe <J Pascoe> on 2021-10-18
Reviewed by Brent Fulgham.

Added api test TestWebKitAPI.WebAuthenticationPanel.LADuplicateCredentialWithConsent

  • UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:

(WebKit::LocalAuthenticator::makeCredential):

  • UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm:

(WebKit::wkWebAuthenticationPanelUpdate):

  • UIProcess/WebAuthentication/WebAuthenticationFlags.h:

Tools:

This adds a test to confirm a different path is taken whenever consent is obtained.

Patch by John Pascoe <J Pascoe> on 2021-10-18
Reviewed by Brent Fulgham.

  • TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:

(-[TestWebAuthenticationPanelDelegate panel:updateWebAuthenticationPanel:]):
(TestWebKitAPI::TEST):

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html

    r270619 r284413  
    5151        if (window.testRunner)
    5252            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
    53         return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
     53        return promiseRejects(t, "InvalidStateError", navigator.credentials.create(options), "Operation timed out.").then(() => {
    5454            if (window.testRunner)
    5555                testRunner.cleanUpKeychain(testRpId, credentialIDBase64);
     
    8585        if (window.testRunner)
    8686            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
    87         return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
     87        return promiseRejects(t, "InvalidStateError", navigator.credentials.create(options), "Operation timed out.").then(() => {
    8888            if (window.testRunner)
    8989                testRunner.cleanUpKeychain(testRpId, credentialIDBase64);
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html

    r269360 r284413  
    4949        if (window.testRunner)
    5050            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
    51         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(() => {
     51        return promiseRejects(t, "InvalidStateError", navigator.credentials.create(options), "At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.").then(() => {
    5252            if (window.testRunner)
    5353                testRunner.cleanUpKeychain(testRpId, credentialIDBase64);
     
    8282        if (window.testRunner)
    8383            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
    84         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(() => {
     84        return promiseRejects(t, "InvalidStateError", navigator.credentials.create(options), "At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.").then(() => {
    8585            if (window.testRunner)
    8686                testRunner.cleanUpKeychain(testRpId, credentialIDBase64);
  • trunk/Source/WebKit/ChangeLog

    r284406 r284413  
     12021-10-18  John Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Obtain consent to create new credential when platform authenticator in excludedCredentials
     4        https://bugs.webkit.org/show_bug.cgi?id=219813
     5        <rdar://problem/72484635>
     6
     7        Currently, whenever the platform authenticator is within excludedCredentials during makeCredential we
     8        always return NotAllowedError and merely flash a consent screen. This does not match the spec per Step 3.1
     9        of makeCredential (https://w3c.github.io/webauthn/#sctn-op-make-cred). Instead, we should always obtain consent
     10        and return a different error depending on consent was obtained.
     11
     12        A fixme to add this was inadvertently removed in  https://bugs.webkit.org/attachment.cgi?id=393180&action=prettypatch
     13
     14        Reviewed by Brent Fulgham.
     15
     16        Added api test TestWebKitAPI.WebAuthenticationPanel.LADuplicateCredentialWithConsent
     17
     18        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
     19        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
     20        (WebKit::LocalAuthenticator::makeCredential):
     21        * UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm:
     22        (WebKit::wkWebAuthenticationPanelUpdate):
     23        * UIProcess/WebAuthentication/WebAuthenticationFlags.h:
     24
    1252021-10-18  Chris Dumez  <cdumez@apple.com>
    226
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h

    r283514 r284413  
    5252    _WKWebAuthenticationPanelUpdateLAError,
    5353    _WKWebAuthenticationPanelUpdateLAExcludeCredentialsMatched,
     54    _WKWebAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent,
    5455    _WKWebAuthenticationPanelUpdateLANoCredential,
    5556} WK_API_AVAILABLE(macos(10.15.4), ios(13.4));
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm

    r284095 r284413  
    228228            return excludeCredentialIds.contains(base64EncodeToString(rawId->data(), rawId->byteLength()));
    229229        })) {
    230             receiveException({ NotAllowedError, "At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator."_s }, WebAuthenticationStatus::LAExcludeCredentialsMatched);
     230            // Obtain consent per Step 3.1
     231            auto callback = [weakThis = WeakPtr { *this }] (LocalAuthenticatorPolicy policy) {
     232                ASSERT(RunLoop::isMain());
     233                if (!weakThis)
     234                    return;
     235
     236                if (policy == LocalAuthenticatorPolicy::Allow)
     237                    weakThis->receiveException({ InvalidStateError, "At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator."_s }, WebAuthenticationStatus::LAExcludeCredentialsMatchedWithConsent);
     238                else
     239                    weakThis->receiveException({ NotAllowedError, "At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator."_s }, WebAuthenticationStatus::LAExcludeCredentialsMatched);
     240            };
     241            observer()->decidePolicyForLocalAuthenticator(WTFMove(callback));
    231242            return;
    232243        }
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm

    r276621 r284413  
    7575    if (status == WebAuthenticationStatus::LAExcludeCredentialsMatched)
    7676        return _WKWebAuthenticationPanelUpdateLAExcludeCredentialsMatched;
     77    if (status == WebAuthenticationStatus::LAExcludeCredentialsMatchedWithConsent)
     78        return _WKWebAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent;
    7779    if (status == WebAuthenticationStatus::LANoCredential)
    7880        return _WKWebAuthenticationPanelUpdateLANoCredential;
  • trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationFlags.h

    r257954 r284413  
    4949    LAError,
    5050    LAExcludeCredentialsMatched,
     51    LAExcludeCredentialsMatchedWithConsent,
    5152    LANoCredential,
    5253};
  • trunk/Tools/ChangeLog

    r284409 r284413  
     12021-10-18  John Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Obtain consent to create new credential when platform authenticator in excludedCredentials
     4        https://bugs.webkit.org/show_bug.cgi?id=219813
     5        <rdar://problem/72484635>
     6
     7        Currently, whenever the platform authenticator is within excludedCredentials during makeCredential we
     8        always return NotAllowedError and merely flash a consent screen. This does not match the spec per Step 3.1
     9        of makeCredential (https://w3c.github.io/webauthn/#sctn-op-make-cred). Instead, we should always obtain consent
     10        and return a different error depending on consent was obtained.
     11
     12        This adds a test to confirm a different path is taken whenever consent is obtained.
     13
     14        Reviewed by Brent Fulgham.
     15
     16        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
     17        (-[TestWebAuthenticationPanelDelegate panel:updateWebAuthenticationPanel:]):
     18        (TestWebKitAPI::TEST):
     19
    1202021-10-18  Alex Christensen  <achristensen@webkit.org>
    221
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm

    r284071 r284413  
    7171static bool webAuthenticationPanelUpdateLAError = false;
    7272static bool webAuthenticationPanelUpdateLAExcludeCredentialsMatched = false;
     73static bool webAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent = false;
    7374static bool webAuthenticationPanelUpdateLANoCredential = false;
    7475static bool webAuthenticationPanelCancelImmediately = false;
     
    123124        return;
    124125    }
     126    if (update == _WKWebAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent) {
     127        webAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent = true;
     128        return;
     129    }
    125130    if (update == _WKWebAuthenticationPanelUpdateLANoCredential) {
    126131        webAuthenticationPanelUpdateLANoCredential = true;
     
    13871392}
    13881393
     1394TEST(WebAuthenticationPanel, LADuplicateCredentialWithConsent)
     1395{
     1396    reset();
     1397    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-la-duplicate-credential" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     1398
     1399    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     1400    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
     1401    [[configuration preferences] _setEnabled:NO forExperimentalFeature:webAuthenticationModernExperimentalFeature()];
     1402
     1403    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
     1404    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
     1405    [webView setUIDelegate:delegate.get()];
     1406    [webView focus];
     1407
     1408    ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "", testUserEntityBundleBase64));
     1409
     1410    localAuthenticatorPolicy = _WKLocalAuthenticatorPolicyAllow;
     1411
     1412    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     1413    Util::run(&webAuthenticationPanelUpdateLAExcludeCredentialsMatchedWithConsent);
     1414    cleanUpKeychain("");
     1415}
     1416
    13891417TEST(WebAuthenticationPanel, LANoCredential)
    13901418{
Note: See TracChangeset for help on using the changeset viewer.