Diff
Modified: trunk/Source/WebKit/ChangeLog (272825 => 272826)
--- trunk/Source/WebKit/ChangeLog 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Source/WebKit/ChangeLog 2021-02-13 01:40:41 UTC (rev 272826)
@@ -1,3 +1,21 @@
+2021-02-12 Jiewen Tan <[email protected]>
+
+ [WebAuthn] Provide SPI to query local credentials
+ https://bugs.webkit.org/show_bug.cgi?id=221743
+ <rdar://problem/65849832>
+
+ Reviewed by Brent Fulgham.
+
+ Covered by API tests.
+
+ * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
+ * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
+ (getAllLocalAuthenticatorCredentialsImpl):
+ (+[_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentials]):
+ (+[_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentialsWithAccessGroup:]):
+ (+[_WKWebAuthenticationPanel deleteLocalAuthenticatorCredentialWithID:]):
+ * UIProcess/API/Cocoa/_WKWebAuthenticationPanelForTesting.h:
+
2021-02-12 Jer Noble <[email protected]>
[Mac] Unable to play WebM/Opus generated from Chrome MediaRecorder
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h (272825 => 272826)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h 2021-02-13 01:40:41 UTC (rev 272826)
@@ -24,6 +24,7 @@
*/
#import <Foundation/Foundation.h>
+#import <WebKit/WKDeclarationSpecifiers.h>
#import <WebKit/WKFoundation.h>
NS_ASSUME_NONNULL_BEGIN
@@ -79,6 +80,10 @@
_WKWebAuthenticationSourceExternal,
} WK_API_AVAILABLE(macos(11.0), ios(14.0));
+WK_EXPORT extern NSString * const _WKLocalAuthenticatorCredentialNameKey;
+WK_EXPORT extern NSString * const _WKLocalAuthenticatorCredentialIDKey;
+WK_EXPORT extern NSString * const _WKLocalAuthenticatorCredentialRelyingPartyIDKey;
+
@protocol _WKWebAuthenticationPanelDelegate <NSObject>
@optional
@@ -98,9 +103,12 @@
@property (nullable, nonatomic, weak) id <_WKWebAuthenticationPanelDelegate> delegate;
-+ (void)clearAllLocalAuthenticatorCredentials;
-+ (BOOL)isUserVerifyingPlatformAuthenticatorAvailable;
++ (NSArray<NSDictionary *> *)getAllLocalAuthenticatorCredentials WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
++ (void)deleteLocalAuthenticatorCredentialWithID:(NSData *)credentialID WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
++ (void)clearAllLocalAuthenticatorCredentials WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
++ (BOOL)isUserVerifyingPlatformAuthenticatorAvailable WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
- (instancetype)init;
// FIXME: <rdar://problem/71509485> Adds detailed NSError.
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm (272825 => 272826)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm 2021-02-13 01:40:41 UTC (rev 272826)
@@ -44,6 +44,8 @@
#import "_WKPublicKeyCredentialUserEntity.h"
#import <WebCore/AuthenticatorResponse.h>
#import <WebCore/AuthenticatorResponseData.h>
+#import <WebCore/CBORReader.h>
+#import <WebCore/FidoConstants.h>
#import <WebCore/MockWebAuthenticationConfiguration.h>
#import <WebCore/PublicKeyCredentialCreationOptions.h>
#import <WebCore/PublicKeyCredentialRequestOptions.h>
@@ -79,6 +81,10 @@
}
#endif
+NSString * const _WKLocalAuthenticatorCredentialNameKey = @"_WKLocalAuthenticatorCredentialNameKey";
+NSString * const _WKLocalAuthenticatorCredentialIDKey = @"_WKLocalAuthenticatorCredentialIDKey";
+NSString * const _WKLocalAuthenticatorCredentialRelyingPartyIDKey = @"_WKLocalAuthenticatorCredentialRelyingPartyIDKey";
+
@implementation _WKWebAuthenticationPanel {
#if ENABLE(WEB_AUTHN)
WeakPtr<WebKit::WebAuthenticationPanelClient> _client;
@@ -180,6 +186,88 @@
}
#endif // ENABLE(WEB_AUTHN)
+#if ENABLE(WEB_AUTHN)
+static RetainPtr<NSArray> getAllLocalAuthenticatorCredentialsImpl(NSString *accessGroup)
+{
+ NSDictionary *query = @{
+ (__bridge id)kSecClass: (__bridge id)kSecClassKey,
+ (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
+ (__bridge id)kSecAttrAccessGroup: accessGroup,
+ (__bridge id)kSecReturnAttributes: @YES,
+ (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitAll,
+#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)
+ return nullptr;
+ auto retainAttributesArray = adoptCF(attributesArrayRef);
+
+ auto result = adoptNS([[NSMutableArray alloc] init]);
+ for (NSDictionary *attributes in (NSArray *)attributesArrayRef) {
+ auto decodedResponse = cbor::CBORReader::read(vectorFromNSData(attributes[(__bridge id)kSecAttrApplicationTag]));
+ if (!decodedResponse || !decodedResponse->isMap()) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+ auto& responseMap = decodedResponse->getMap();
+
+ auto it = responseMap.find(cbor::CBORValue(fido::kEntityNameMapKey));
+ if (it == responseMap.end() || !it->second.isString()) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+ auto& username = it->second.getString();
+
+ [result addObject:@{
+ _WKLocalAuthenticatorCredentialNameKey: username,
+ _WKLocalAuthenticatorCredentialIDKey: attributes[(__bridge id)kSecAttrApplicationLabel],
+ _WKLocalAuthenticatorCredentialRelyingPartyIDKey: attributes[(__bridge id)kSecAttrLabel]
+ }];
+ }
+
+ return result;
+}
+#endif
+
++ (NSArray<NSDictionary *> *)getAllLocalAuthenticatorCredentials
+{
+#if ENABLE(WEB_AUTHN)
+ return getAllLocalAuthenticatorCredentialsImpl(String(WebCore::LocalAuthenticatiorAccessGroup)).autorelease();
+#else
+ return nullptr;
+#endif
+}
+
++ (NSArray<NSDictionary *> *)getAllLocalAuthenticatorCredentialsWithAccessGroup:(NSString *)accessGroup
+{
+#if ENABLE(WEB_AUTHN)
+ return getAllLocalAuthenticatorCredentialsImpl(accessGroup).autorelease();
+#else
+ return nullptr;
+#endif
+}
+
++ (void)deleteLocalAuthenticatorCredentialWithID:(NSData *)credentialID
+{
+#if ENABLE(WEB_AUTHN)
+ NSDictionary* deleteQuery = @{
+ (__bridge id)kSecClass: (__bridge id)kSecClassKey,
+ (__bridge id)kSecAttrApplicationLabel: credentialID,
+#if HAVE(DATA_PROTECTION_KEYCHAIN)
+ (__bridge id)kSecUseDataProtectionKeychain: @YES
+#else
+ (__bridge id)kSecAttrNoLegacy: @YES
+#endif
+ };
+ SecItemDelete((__bridge CFDictionaryRef)deleteQuery);
+#endif
+}
+
+ (void)clearAllLocalAuthenticatorCredentials
{
#if ENABLE(WEB_AUTHN)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanelForTesting.h (272825 => 272826)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanelForTesting.h 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanelForTesting.h 2021-02-13 01:40:41 UTC (rev 272826)
@@ -38,6 +38,8 @@
+ (WebCore::PublicKeyCredentialCreationOptions)convertToCoreCreationOptionsWithOptions:(_WKPublicKeyCredentialCreationOptions *)options WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+ (WebCore::PublicKeyCredentialRequestOptions)convertToCoreRequestOptionsWithOptions:(_WKPublicKeyCredentialRequestOptions *)options WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
++ (NSArray<NSDictionary *> *)getAllLocalAuthenticatorCredentialsWithAccessGroup:(NSString *)accessGroup WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
// For details of configuration, refer to MockWebAuthenticationConfiguration.h.
@property (nonatomic, copy) NSDictionary *mockConfiguration;
Modified: trunk/Tools/ChangeLog (272825 => 272826)
--- trunk/Tools/ChangeLog 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Tools/ChangeLog 2021-02-13 01:40:41 UTC (rev 272826)
@@ -1,3 +1,14 @@
+2021-02-12 Jiewen Tan <[email protected]>
+
+ [WebAuthn] Provide SPI to query local credentials
+ https://bugs.webkit.org/show_bug.cgi?id=221743
+ <rdar://problem/65849832>
+
+ Reviewed by Brent Fulgham.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
+ (TestWebKitAPI::TEST):
+
2021-02-12 Michael Saboff <[email protected]>
[ARM64e] Harden Mach exception handling
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm (272825 => 272826)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm 2021-02-13 01:27:47 UTC (rev 272825)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm 2021-02-13 01:40:41 UTC (rev 272826)
@@ -1925,6 +1925,37 @@
}];
Util::run(&webAuthenticationPanelRan);
}
+
+TEST(WebAuthenticationPanel, GetAllCredential)
+{
+ reset();
+
+ 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");
+ EXPECT_WK_STREQ([[credentials firstObject][_WKLocalAuthenticatorCredentialIDKey] base64EncodedStringWithOptions:0], "SMSXHngF7hEOsElA73C3RY+8bR4=");
+ EXPECT_WK_STREQ([credentials firstObject][_WKLocalAuthenticatorCredentialRelyingPartyIDKey], "example.com");
+
+ cleanUpKeychain("example.com");
+}
+
+TEST(WebAuthenticationPanel, DeleteOneCredential)
+{
+ reset();
+
+ ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "example.com", testUserEntityBundleBase64));
+
+ [_WKWebAuthenticationPanel deleteLocalAuthenticatorCredentialWithID:adoptNS([[NSData alloc] initWithBase64EncodedString:@"SMSXHngF7hEOsElA73C3RY+8bR4=" options:0]).get()];
+
+ auto *credentials = [_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentialsWithAccessGroup:@"com.apple.TestWebKitAPI"];
+ EXPECT_NOT_NULL(credentials);
+ EXPECT_EQ([credentials count], 0lu);
+}
#endif
} // namespace TestWebKitAPI