Title: [290381] trunk
Revision
290381
Author
j_pas...@apple.com
Date
2022-02-23 10:19:54 -0800 (Wed, 23 Feb 2022)

Log Message

[WebAuthn] userHandle not marked nullable in _WKWebAuthenticationAssertionResponse
https://bugs.webkit.org/show_bug.cgi?id=237043
rdar://89317740

Reviewed by Brent Fulgham.

Source/WebCore:

The userHandle is a nullable field on UserEntity. This patch changes
various API/SPI to allow passing null userHandle.

* Modules/webauthn/AuthenticatorAssertionResponse.cpp:
(WebCore::AuthenticatorAssertionResponse::create):
(WebCore::AuthenticatorAssertionResponse::AuthenticatorAssertionResponse):
* Modules/webauthn/AuthenticatorAssertionResponse.h:

Source/WebKit:

The userHandle is a nullable field on UserEntity. This patch changes
various API/SPI to allow passing null userHandle.

* Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
Update forward declared SPI, reflecting userHandle as nullable.
* UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h:
* UIProcess/API/Cocoa/_WKWebAuthenticationAssertionResponse.h:
Update userHandle property to null.
* UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(getAllLocalAuthenticatorCredentialsImpl):
* UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
(WebKit::LocalAuthenticatorInternal::getExistingCredentials):

Tools:

Create tests to check for null userHandle.

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

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290380 => 290381)


--- trunk/Source/WebCore/ChangeLog	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebCore/ChangeLog	2022-02-23 18:19:54 UTC (rev 290381)
@@ -1,3 +1,19 @@
+2022-02-23  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] userHandle not marked nullable in _WKWebAuthenticationAssertionResponse
+        https://bugs.webkit.org/show_bug.cgi?id=237043
+        rdar://89317740
+
+        Reviewed by Brent Fulgham.
+
+        The userHandle is a nullable field on UserEntity. This patch changes
+        various API/SPI to allow passing null userHandle.
+
+        * Modules/webauthn/AuthenticatorAssertionResponse.cpp:
+        (WebCore::AuthenticatorAssertionResponse::create):
+        (WebCore::AuthenticatorAssertionResponse::AuthenticatorAssertionResponse):
+        * Modules/webauthn/AuthenticatorAssertionResponse.h:
+
 2022-02-23  Antti Koivisto  <an...@apple.com>
 
         [CSS Container Queries] offsetWidth/Height and similar should update layout for container queries

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp (290380 => 290381)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp	2022-02-23 18:19:54 UTC (rev 290381)
@@ -48,7 +48,7 @@
     return create(ArrayBuffer::create(rawId.data(), rawId.size()), ArrayBuffer::create(authenticatorData.data(), authenticatorData.size()), ArrayBuffer::create(signature.data(), signature.size()), WTFMove(userhandleBuffer), std::nullopt, attachment);
 }
 
-Ref<AuthenticatorAssertionResponse> AuthenticatorAssertionResponse::create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef accessControl, AuthenticatorAttachment attachment)
+Ref<AuthenticatorAssertionResponse> AuthenticatorAssertionResponse::create(Ref<ArrayBuffer>&& rawId, RefPtr<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef accessControl, AuthenticatorAttachment attachment)
 {
     return adoptRef(*new AuthenticatorAssertionResponse(WTFMove(rawId), WTFMove(userHandle), WTFMove(name), accessControl, attachment));
 }
@@ -66,7 +66,7 @@
 {
 }
 
-AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef accessControl, AuthenticatorAttachment attachment)
+AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(Ref<ArrayBuffer>&& rawId, RefPtr<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef accessControl, AuthenticatorAttachment attachment)
     : AuthenticatorResponse(WTFMove(rawId), attachment)
     , m_userHandle(WTFMove(userHandle))
     , m_name(WTFMove(name))

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h (290380 => 290381)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h	2022-02-23 18:19:54 UTC (rev 290381)
@@ -39,7 +39,7 @@
 public:
     static Ref<AuthenticatorAssertionResponse> create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& authenticatorData, Ref<ArrayBuffer>&& signature, RefPtr<ArrayBuffer>&& userHandle, std::optional<AuthenticationExtensionsClientOutputs>&&, AuthenticatorAttachment);
     WEBCORE_EXPORT static Ref<AuthenticatorAssertionResponse> create(const Vector<uint8_t>& rawId, const Vector<uint8_t>& authenticatorData, const Vector<uint8_t>& signature,  const Vector<uint8_t>& userHandle, AuthenticatorAttachment);
-    WEBCORE_EXPORT static Ref<AuthenticatorAssertionResponse> create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef, AuthenticatorAttachment);
+    WEBCORE_EXPORT static Ref<AuthenticatorAssertionResponse> create(Ref<ArrayBuffer>&& rawId, RefPtr<ArrayBuffer>&& userHandle, String&& name, SecAccessControlRef, AuthenticatorAttachment);
     virtual ~AuthenticatorAssertionResponse() = default;
 
     ArrayBuffer* authenticatorData() const { return m_authenticatorData.get(); }
@@ -64,7 +64,7 @@
 
 private:
     AuthenticatorAssertionResponse(Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, RefPtr<ArrayBuffer>&&, AuthenticatorAttachment);
-    AuthenticatorAssertionResponse(Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, String&&, SecAccessControlRef, AuthenticatorAttachment);
+    AuthenticatorAssertionResponse(Ref<ArrayBuffer>&&, RefPtr<ArrayBuffer>&&, String&&, SecAccessControlRef, AuthenticatorAttachment);
 
     Type type() const final { return Type::Assertion; }
     AuthenticatorResponseData data() const final;

Modified: trunk/Source/WebKit/ChangeLog (290380 => 290381)


--- trunk/Source/WebKit/ChangeLog	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/ChangeLog	2022-02-23 18:19:54 UTC (rev 290381)
@@ -1,3 +1,24 @@
+2022-02-23  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] userHandle not marked nullable in _WKWebAuthenticationAssertionResponse
+        https://bugs.webkit.org/show_bug.cgi?id=237043
+        rdar://89317740
+
+        Reviewed by Brent Fulgham.
+
+        The userHandle is a nullable field on UserEntity. This patch changes
+        various API/SPI to allow passing null userHandle.
+
+        * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
+        Update forward declared SPI, reflecting userHandle as nullable.
+        * UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h:
+        * UIProcess/API/Cocoa/_WKWebAuthenticationAssertionResponse.h:
+        Update userHandle property to null.
+        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
+        (getAllLocalAuthenticatorCredentialsImpl):
+        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
+        (WebKit::LocalAuthenticatorInternal::getExistingCredentials):
+
 2022-02-23  Philippe Normand  <pnorm...@igalia.com>
 
         [GStreamer] De-initialize GStreamer before terminating WebProcess

Modified: trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h (290380 => 290381)


--- trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-02-23 18:19:54 UTC (rev 290381)
@@ -221,7 +221,7 @@
 
 @property (nonatomic, readonly, copy) NSString *name;
 @property (nonatomic, readonly, copy) NSString *displayName;
-@property (nonatomic, readonly, copy) NSData *userHandle;
+@property (nonatomic, readonly, nullable, copy) NSData *userHandle;
 @property (nonatomic, readonly) BOOL isRegistrationRequest;
 
 + (instancetype)new NS_UNAVAILABLE;

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h (290380 => 290381)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h	2022-02-23 18:19:54 UTC (rev 290381)
@@ -34,7 +34,7 @@
 
 @interface _WKAuthenticatorAssertionResponse ()
 
-- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions authenticatorData:(NSData *)authenticatorData signature:(NSData *)signature userHandle:(NSData *)userHandle attachment:(_WKAuthenticatorAttachment)attachment;
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions authenticatorData:(NSData *)authenticatorData signature:(NSData *)signature userHandle:(NSData * _Nullable)userHandle attachment:(_WKAuthenticatorAttachment)attachment;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationAssertionResponse.h (290380 => 290381)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationAssertionResponse.h	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationAssertionResponse.h	2022-02-23 18:19:54 UTC (rev 290381)
@@ -35,7 +35,7 @@
 
 @property (nonatomic, readonly, copy) NSString *name;
 @property (nonatomic, readonly, copy) NSString *displayName;
-@property (nonatomic, readonly, copy) NSData *userHandle;
+@property (nonatomic, readonly, nullable, copy) NSData *userHandle;
 @property (nonatomic, readonly) BOOL synchronizable;
 @property (nonatomic, readonly, copy) NSString *group;
 @property (nonatomic, readonly, copy) NSData *credentialID;

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


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2022-02-23 18:19:54 UTC (rev 290381)
@@ -276,13 +276,6 @@
         }
         auto& username = it->second.getString();
 
-        it = responseMap.find(cbor::CBORValue(fido::kEntityIdMapKey));
-        if (it == responseMap.end() || !it->second.isByteString()) {
-            ASSERT_NOT_REACHED();
-            return nullptr;
-        }
-        auto& userHandle = it->second.getByteString();
-
         auto credential = adoptNS([[NSMutableDictionary alloc] initWithObjectsAndKeys:
             username, _WKLocalAuthenticatorCredentialNameKey,
             attributes[bridge_cast(kSecAttrApplicationLabel)], _WKLocalAuthenticatorCredentialIDKey,
@@ -289,9 +282,15 @@
             attributes[bridge_cast(kSecAttrLabel)], _WKLocalAuthenticatorCredentialRelyingPartyIDKey,
             attributes[bridge_cast(kSecAttrModificationDate)], _WKLocalAuthenticatorCredentialLastModificationDateKey,
             attributes[bridge_cast(kSecAttrCreationDate)], _WKLocalAuthenticatorCredentialCreationDateKey,
-            adoptNS([[NSData alloc] initWithBytes:userHandle.data() length:userHandle.size()]).get(), _WKLocalAuthenticatorCredentialUserHandleKey,
             nil
         ]);
+        it = responseMap.find(cbor::CBORValue(fido::kEntityIdMapKey));
+        if (it != responseMap.end() && it->second.isByteString()) {
+            auto& userHandle = it->second.getByteString();
+            [credential setObject:adoptNS([[NSData alloc] initWithBytes:userHandle.data() length:userHandle.size()]).get() forKey:_WKLocalAuthenticatorCredentialUserHandleKey];
+        } else
+            [credential setObject:[NSNull null] forKey:_WKLocalAuthenticatorCredentialUserHandleKey];
+
         updateCredentialIfNecessary(credential.get(), attributes);
 
         it = responseMap.find(cbor::CBORValue(fido::kDisplayNameMapKey));

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm (290380 => 290381)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2022-02-23 18:19:54 UTC (rev 290381)
@@ -154,12 +154,11 @@
         }
         auto& responseMap = decodedResponse->getMap();
 
+        RefPtr<ArrayBuffer> userHandle;
         auto it = responseMap.find(CBOR(fido::kEntityIdMapKey));
-        if (it == responseMap.end() || !it->second.isByteString()) {
-            ASSERT_NOT_REACHED();
-            return std::nullopt;
+        if (it != responseMap.end() && it->second.isByteString()) {
+            userHandle = toArrayBuffer(it->second.getByteString());
         }
-        auto& userHandle = it->second.getByteString();
 
         it = responseMap.find(CBOR(fido::kEntityNameMapKey));
         if (it == responseMap.end() || !it->second.isString()) {
@@ -168,7 +167,7 @@
         }
         auto& username = it->second.getString();
 
-        auto response = AuthenticatorAssertionResponse::create(toArrayBuffer(attributes[(id)kSecAttrApplicationLabel]), toArrayBuffer(userHandle), String(username), (__bridge SecAccessControlRef)attributes[(id)kSecAttrAccessControl], AuthenticatorAttachment::Platform);
+        auto response = AuthenticatorAssertionResponse::create(toArrayBuffer(attributes[(id)kSecAttrApplicationLabel]), WTFMove(userHandle), String(username), (__bridge SecAccessControlRef)attributes[(id)kSecAttrAccessControl], AuthenticatorAttachment::Platform);
 
         auto group = groupForAttributes(attributes);
         if (!group.isNull())

Modified: trunk/Tools/ChangeLog (290380 => 290381)


--- trunk/Tools/ChangeLog	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Tools/ChangeLog	2022-02-23 18:19:54 UTC (rev 290381)
@@ -1,3 +1,16 @@
+2022-02-23  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] userHandle not marked nullable in _WKWebAuthenticationAssertionResponse
+        https://bugs.webkit.org/show_bug.cgi?id=237043
+        rdar://89317740
+
+        Reviewed by Brent Fulgham.
+
+        Create tests to check for null userHandle.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
+        (TestWebKitAPI::TEST):
+
 2022-02-23  Philippe Normand  <pnorm...@igalia.com>
 
         [GStreamer] De-initialize GStreamer before terminating WebProcess

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm (290380 => 290381)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2022-02-23 18:14:59 UTC (rev 290380)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm	2022-02-23 18:19:54 UTC (rev 290381)
@@ -81,6 +81,7 @@
     "PH76c0+WFOzZKslPyyFse4goGIW2R7k9VHLPEZl5nfnBgEVFh5zev+/xpHQIvuq6"
     "RQ==";
 static String testUserEntityBundleBase64 = "omJpZEoAAQIDBAUGBwgJZG5hbWVkSm9obg=="; // { "id": h'00010203040506070809', "name": "John" }
+static String testUserEntityBundleNoUserHandleBase64 = "oWRuYW1lbE1DIE5vLUhhbmRsZQ=="; // {"name": "MC No-Handle"}
 static String webAuthenticationPanelSelectedCredentialName;
 static String testWebKitAPIAccessGroup = "com.apple.TestWebKitAPI";
 static String testWebKitAPIAlternateAccessGroup = "com.apple.TestWebKitAPIAlternate";
@@ -2128,6 +2129,34 @@
     Util::run(&webAuthenticationPanelRan);
 }
 
+TEST(WebAuthenticationPanel, GetAssertionNullUserHandle)
+{
+    reset();
+
+    ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "example.com", testUserEntityBundleNoUserHandleBase64));
+
+    uint8_t hash[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 };
+    NSData *nsHash = [NSData dataWithBytes:hash length:sizeof(hash)];
+
+    auto options = adoptNS([[_WKPublicKeyCredentialRequestOptions alloc] init]);
+    [options setRelyingPartyIdentifier:@"example.com"];
+
+    auto panel = adoptNS([[_WKWebAuthenticationPanel alloc] init]);
+    [panel setMockConfiguration:@{ }];
+    auto delegate = adoptNS([[TestWebAuthenticationPanelDelegate alloc] init]);
+    [panel setDelegate:delegate.get()];
+
+    [panel getAssertionWithClientDataHash:nsHash options:options.get() completionHandler:^(_WKAuthenticatorAssertionResponse *response, NSError *error) {
+        webAuthenticationPanelRan = true;
+        cleanUpKeychain("example.com");
+
+        EXPECT_NULL(error);
+
+        EXPECT_NULL(response.userHandle);
+    }];
+    Util::run(&webAuthenticationPanelRan);
+}
+
 TEST(WebAuthenticationPanel, GetAssertionCrossPlatform)
 {
     reset();
@@ -2185,6 +2214,24 @@
     cleanUpKeychain("example.com");
 }
 
+TEST(WebAuthenticationPanel, GetAllCredentialNullUserHandle)
+{
+    reset();
+
+    ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "example.com", testUserEntityBundleNoUserHandleBase64));
+
+    auto after = adoptNS([[NSDate alloc] init]);
+
+    auto *credentials = [_WKWebAuthenticationPanel getAllLocalAuthenticatorCredentialsWithAccessGroup:@"com.apple.TestWebKitAPI"];
+    EXPECT_NOT_NULL(credentials);
+    EXPECT_EQ([credentials count], 1lu);
+
+    EXPECT_NOT_NULL([credentials firstObject]);
+    EXPECT_EQ([credentials firstObject][_WKLocalAuthenticatorCredentialUserHandleKey], [NSNull null]);
+
+    cleanUpKeychain("example.com");
+}
+
 TEST(WebAuthenticationPanel, GetAllCredentialWithDisplayName)
 {
     reset();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to