Changeset 289059 in webkit


Ignore:
Timestamp:
Feb 3, 2022 10:01:45 AM (6 months ago)
Author:
J Pascoe
Message:

[WebAuthn] Allow use of hardware-fixed credentials while using alternate store
https://bugs.webkit.org/show_bug.cgi?id=235923
rdar://88102108

Reviewed by Brent Fulgham.

Source/WebKit:

This patch allows use of credentials created before a user started using
the alternate credential store by searching regardless of status when
querying credentials.

Added API test + tested manually.

  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:

(WebKit::LocalAuthenticatorInternal::getExistingCredentials):
(WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):

Tools:

Add new test for querying credentials created both before and after enabling
alternative credential store.

  • TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:

(TestWebKitAPI::WebCore::addKeyToKeychain):
(TestWebKitAPI::WebCore::cleanUpKeychain):
(TestWebKitAPI::TEST):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r289055 r289059  
     12022-02-03  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Allow use of hardware-fixed credentials while using alternate store
     4        https://bugs.webkit.org/show_bug.cgi?id=235923
     5        rdar://88102108
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch allows use of credentials created before a user started using
     10        the alternate credential store by searching regardless of status when
     11        querying credentials.
     12
     13        Added API test + tested manually.
     14
     15        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
     16        (WebKit::LocalAuthenticatorInternal::getExistingCredentials):
     17        (WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
     18
    1192022-02-03  Per Arne Vollan  <pvollan@apple.com>
    220
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm

    r288816 r289059  
    121121{
    122122    // Search Keychain for existing credential matched the RP ID.
    123     auto query = adoptNS([[NSMutableDictionary alloc] init]);
    124     [query setDictionary:@{
     123    NSDictionary *query = @{
    125124        (id)kSecClass: (id)kSecClassKey,
    126125        (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
     126        (id)kSecAttrSynchronizable: (id)kSecAttrSynchronizableAny,
    127127        (id)kSecAttrLabel: rpId,
    128128        (id)kSecReturnAttributes: @YES,
    129129        (id)kSecMatchLimit: (id)kSecMatchLimitAll,
    130130        (id)kSecUseDataProtectionKeychain: @YES
    131     }];
    132     updateQueryIfNecessary(query.get());
     131    };
    133132
    134133    CFTypeRef attributesArrayRef = nullptr;
    135     OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query.get(), &attributesArrayRef);
     134    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &attributesArrayRef);
    136135    if (status && status != errSecItemNotFound)
    137136        return std::nullopt;
     
    600599            (id)kSecClass: (id)kSecClassKey,
    601600            (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
     601            (id)kSecAttrSynchronizable: (id)kSecAttrSynchronizableAny,
    602602            (id)kSecAttrApplicationLabel: nsCredentialId.get(),
    603603            (id)kSecReturnRef: @YES,
     
    609609
    610610        auto query = adoptNS(queryDictionary);
    611         updateQueryIfNecessary(query.get());
    612611
    613612        CFTypeRef privateKeyRef = nullptr;
     
    634633    // Extra step: update the Keychain item with the same value to update its modification date such that LRU can be used
    635634    // for selectAssertionResponse
    636     auto query = adoptNS([[NSMutableDictionary alloc] init]);
    637     [query setDictionary:@{
     635    NSDictionary *query = @{
    638636        (id)kSecClass: (id)kSecClassKey,
    639637        (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
     638        (id)kSecAttrSynchronizable: (id)kSecAttrSynchronizableAny,
    640639        (id)kSecAttrApplicationLabel: nsCredentialId.get(),
    641640        (id)kSecUseDataProtectionKeychain: @YES
    642     }];
    643     updateQueryIfNecessary(query.get());
     641    };
    644642
    645643    NSDictionary *updateParams = @{
    646644        (id)kSecAttrLabel: requestOptions.rpId,
    647645    };
    648     auto status = SecItemUpdate((__bridge CFDictionaryRef)query.get(), (__bridge CFDictionaryRef)updateParams);
     646    auto status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)updateParams);
    649647    if (status)
    650648        LOG_ERROR("Couldn't update the Keychain item: %d", status);
  • trunk/Tools/ChangeLog

    r289042 r289059  
     12022-02-03  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Allow use of hardware-fixed credentials while using alternate store
     4        https://bugs.webkit.org/show_bug.cgi?id=235923
     5        rdar://88102108
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add new test for querying credentials created both before and after enabling
     10        alternative credential store.
     11
     12        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
     13        (TestWebKitAPI::WebCore::addKeyToKeychain):
     14        (TestWebKitAPI::WebCore::cleanUpKeychain):
     15        (TestWebKitAPI::TEST):
     16
    1172022-02-03  Carlos Garcia Campos  <cgarcia@igalia.com>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm

    r288816 r289059  
    363363#if USE(APPLE_INTERNAL_SDK) || PLATFORM(IOS)
    364364
    365 bool addKeyToKeychain(const String& privateKeyBase64, const String& rpId, const String& userHandleBase64)
     365bool addKeyToKeychain(const String& privateKeyBase64, const String& rpId, const String& userHandleBase64, bool synchronizable = false)
    366366{
    367367    NSDictionary* options = @{
     
    379379        return false;
    380380
    381     NSDictionary* addQuery = @{
     381    auto addQuery = adoptNS([[NSMutableDictionary alloc] init]);
     382    [addQuery setDictionary:@{
    382383        (id)kSecValueRef: (id)key.get(),
    383384        (id)kSecClass: (id)kSecClassKey,
     
    386387        (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock,
    387388        (id)kSecUseDataProtectionKeychain: @YES
    388     };
    389     OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addQuery, NULL);
     389    }];
     390    if (synchronizable)
     391        [addQuery.get() setObject:@YES forKey:(__bridge id)kSecAttrSynchronizable];
     392
     393    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addQuery.get(), NULL);
    390394    if (status)
    391395        return false;
     
    399403        (id)kSecClass: (id)kSecClassKey,
    400404        (id)kSecAttrLabel: rpId,
     405        (id)kSecAttrSynchronizable: (id)kSecAttrSynchronizableAny,
    401406        (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock,
    402407        (id)kSecUseDataProtectionKeychain: @YES
     
    15111516}
    15121517
     1518TEST(WebAuthenticationPanel, LAGetAssertionMultipleCredentialStore)
     1519{
     1520    reset();
     1521    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-get-assertion-la" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     1522
     1523    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     1524    [[configuration preferences] _setEnabled:NO forExperimentalFeature:webAuthenticationModernExperimentalFeature()];
     1525
     1526    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
     1527    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
     1528    [webView setUIDelegate:delegate.get()];
     1529    [webView focus];
     1530
     1531    ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "", testUserEntityBundleBase64));
     1532    ASSERT_TRUE(addKeyToKeychain("BBRoi2JbR0IXTeJmvXUp1YIuM4sph/Lu3eGf75F7n+HojHKG70a4R0rB2PQce5/SJle6T7OO5Cqet/LJZVM6NQ8yDDxWvayf71GTDp2yUtuIbqJLFVbpWymlj9WRizgX3A==", "", "omJpZEoAAQIDBAUGBwgJZG5hbWVkSmFuZQ=="/* { "id": h'00010203040506070809', "name": "Jane" } */, true /* synchronizable */));
     1533
     1534    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     1535    [webView waitForMessage:@"Succeeded!"];
     1536    EXPECT_WK_STREQ(webAuthenticationPanelSelectedCredentialName, "John");
     1537
     1538    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     1539    [webView waitForMessage:@"Succeeded!"];
     1540    EXPECT_WK_STREQ(webAuthenticationPanelSelectedCredentialName, "Jane");
     1541
     1542    cleanUpKeychain("");
     1543}
     1544
    15131545TEST(WebAuthenticationPanel, LAGetAssertionNoMockNoUserGesture)
    15141546{
Note: See TracChangeset for help on using the changeset viewer.