Title: [283514] trunk
Revision
283514
Author
[email protected]
Date
2021-10-04 14:25:01 -0700 (Mon, 04 Oct 2021)

Log Message

[WebAuthn] Add SPI to change username of credential
https://bugs.webkit.org/show_bug.cgi?id=230956
<rdar://problem/83471755>

Patch by John Pascoe <[email protected]> on 2021-10-04
Reviewed by Brent Fulgham.

Source/WebKit:

Adds a new method for changing the username of a given stored webauthn credential.

New API test: TestWebKitAPI.WebAuthenticationPanel.UpdateCredentialUsername

* UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
* UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(+[_WKWebAuthenticationPanel setUsernameForLocalCredentialWithID:username:]):

Tools:

API test coverage for updating the username of a webauthn credential.

* TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (283513 => 283514)


--- trunk/Source/WebKit/ChangeLog	2021-10-04 21:02:39 UTC (rev 283513)
+++ trunk/Source/WebKit/ChangeLog	2021-10-04 21:25:01 UTC (rev 283514)
@@ -1,3 +1,19 @@
+2021-10-04  John Pascoe  <[email protected]>
+
+        [WebAuthn] Add SPI to change username of credential
+        https://bugs.webkit.org/show_bug.cgi?id=230956
+        <rdar://problem/83471755>
+
+        Reviewed by Brent Fulgham.
+
+        Adds a new method for changing the username of a given stored webauthn credential.
+
+        New API test: TestWebKitAPI.WebAuthenticationPanel.UpdateCredentialUsername
+
+        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
+        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
+        (+[_WKWebAuthenticationPanel setUsernameForLocalCredentialWithID:username:]):
+
 2021-10-04  Youenn Fablet  <[email protected]>
 
         Send necessary sandbox extensions to WebProcess in case WebRTC codecs run in WebProcess

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h (283513 => 283514)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h	2021-10-04 21:02:39 UTC (rev 283513)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h	2021-10-04 21:25:01 UTC (rev 283514)
@@ -106,6 +106,7 @@
 + (NSArray<NSDictionary *> *)getAllLocalAuthenticatorCredentials WK_API_AVAILABLE(macos(12.0), ios(15.0));
 + (void)deleteLocalAuthenticatorCredentialWithID:(NSData *)credentialID WK_API_AVAILABLE(macos(12.0), ios(15.0));
 + (void)clearAllLocalAuthenticatorCredentials WK_API_AVAILABLE(macos(12.0), ios(15.0));
++ (void)setUsernameForLocalCredentialWithID:(NSData *)credentialID username: (NSString *)username WK_API_AVAILABLE(macos(12.0), ios(15.0));
 
 + (BOOL)isUserVerifyingPlatformAuthenticatorAvailable WK_API_AVAILABLE(macos(12.0), ios(15.0));
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm (283513 => 283514)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2021-10-04 21:02:39 UTC (rev 283513)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2021-10-04 21:25:01 UTC (rev 283514)
@@ -46,6 +46,7 @@
 #import <WebCore/AuthenticatorResponse.h>
 #import <WebCore/AuthenticatorResponseData.h>
 #import <WebCore/CBORReader.h>
+#import <WebCore/CBORWriter.h>
 #import <WebCore/FidoConstants.h>
 #import <WebCore/MockWebAuthenticationConfiguration.h>
 #import <WebCore/PublicKeyCredentialCreationOptions.h>
@@ -52,6 +53,7 @@
 #import <WebCore/PublicKeyCredentialRequestOptions.h>
 #import <WebCore/WebAuthenticationConstants.h>
 #import <WebCore/WebCoreObjCExtras.h>
+#import <objc/runtime.h>
 #import <pal/crypto/CryptoDigest.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
@@ -279,6 +281,65 @@
 #endif
 }
 
++ (void)setUsernameForLocalCredentialWithID:(NSData *)credentialID username: (NSString *)username
+{
+#if ENABLE(WEB_AUTHN)
+    NSDictionary* query = @{
+        (__bridge id)kSecClass: (__bridge id)kSecClassKey,
+        (__bridge id)kSecReturnAttributes: @YES,
+        (__bridge id)kSecAttrApplicationLabel: credentialID,
+        (__bridge id)kSecReturnPersistentRef : (__bridge id)kCFBooleanTrue,
+#if HAVE(DATA_PROTECTION_KEYCHAIN)
+        (__bridge id)kSecUseDataProtectionKeychain: @YES
+#else
+        (__bridge id)kSecAttrNoLegacy: @YES
+#endif
+    };
+    CFTypeRef attributesArrayRef = nullptr;
+    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &attributesArrayRef);
+    if (status && status != errSecItemNotFound) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    NSDictionary *attributes = (__bridge NSDictionary *)attributesArrayRef;
+    auto decodedResponse = cbor::CBORReader::read(vectorFromNSData(attributes[(__bridge id)kSecAttrApplicationTag]));
+    if (!decodedResponse || !decodedResponse->isMap()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    auto& previousUserMap = decodedResponse->getMap();
+
+    bool usernameSet = false;
+    cbor::CBORValue::MapValue updatedUserMap;
+    for (auto it = previousUserMap.begin(); it != previousUserMap.end(); ++it) {
+        if (it->first.isString() && it->first.getString() == fido::kEntityNameMapKey) {
+            updatedUserMap[it->first.clone()] = cbor::CBORValue(String(username));
+            usernameSet = true;
+        } else
+            updatedUserMap[it->first.clone()] = it->second.clone();
+    }
+    if (!usernameSet) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    auto updatedTag = cbor::CBORWriter::write(cbor::CBORValue(WTFMove(updatedUserMap)));
+    auto secAttrApplicationTag = [NSData dataWithBytesNoCopy:updatedTag->data() length:updatedTag->size()];
+
+    NSDictionary *updateParams = @{
+        (__bridge id)kSecAttrApplicationTag: secAttrApplicationTag,
+    };
+    query = @{
+        (__bridge id)kSecValuePersistentRef: [attributes objectForKey:(__bridge id)kSecValuePersistentRef],
+        (__bridge id)kSecClass: (__bridge id)kSecClassKey,
+    };
+    status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)updateParams);
+    if (status && status != errSecItemNotFound) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+#endif
+}
+
 - (void)cancel
 {
 #if ENABLE(WEB_AUTHN)

Modified: trunk/Tools/ChangeLog (283513 => 283514)


--- trunk/Tools/ChangeLog	2021-10-04 21:02:39 UTC (rev 283513)
+++ trunk/Tools/ChangeLog	2021-10-04 21:25:01 UTC (rev 283514)
@@ -1,3 +1,16 @@
+2021-10-04  John Pascoe  <[email protected]>
+
+        [WebAuthn] Add SPI to change username of credential
+        https://bugs.webkit.org/show_bug.cgi?id=230956
+        <rdar://problem/83471755>
+
+        Reviewed by Brent Fulgham.
+
+        API test coverage for updating the username of a webauthn credential.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
+        (TestWebKitAPI::TEST):
+
 2021-10-04  Aakash Jain  <[email protected]>
 
         Send EWS exception emails to bot watchers instead of Aakash

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm (283513 => 283514)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2021-10-04 21:02:39 UTC (rev 283513)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2021-10-04 21:25:01 UTC (rev 283514)
@@ -2032,6 +2032,32 @@
     cleanUpKeychain("example.com");
 }
 
+TEST(WebAuthenticationPanel, UpdateCredentialUsername)
+{
+    reset();
+    cleanUpKeychain("example.com");
+
+    ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "example.com", testUserEntityBundleBase64));
+
+    auto *credentials = [_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentialsWithAccessGroup:@"com.apple.TestWebKitAPI"];
+    EXPECT_NOT_NULL(credentials);
+    EXPECT_EQ([credentials count], 1lu);
+
+    EXPECT_NOT_NULL([credentials firstObject]);
+    EXPECT_WK_STREQ([credentials firstObject][_WKLocalAuthenticatorCredentialNameKey], "John");
+
+    [_WKWebAuthenticationPanel setUsernameForLocalCredentialWithID:[credentials firstObject][_WKLocalAuthenticatorCredentialIDKey] username: @"Saffron"];
+
+    credentials = [_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentialsWithAccessGroup:@"com.apple.TestWebKitAPI"];
+    EXPECT_NOT_NULL(credentials);
+    EXPECT_EQ([credentials count], 1lu);
+
+    EXPECT_NOT_NULL([credentials firstObject]);
+    EXPECT_WK_STREQ([credentials firstObject][_WKLocalAuthenticatorCredentialNameKey], "Saffron");
+
+    cleanUpKeychain("example.com");
+}
+
 TEST(WebAuthenticationPanel, DeleteOneCredential)
 {
     reset();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to