Title: [287116] trunk
Revision
287116
Author
j_pas...@apple.com
Date
2021-12-15 16:52:57 -0800 (Wed, 15 Dec 2021)

Log Message

[WebAuthn] Allow same-site, cross-origin iframe get()
https://bugs.webkit.org/show_bug.cgi?id=234309
rdar://problem/86486313

Reviewed by Brent Fulgham.

Source/WebCore:

The Web Authentication level 2 specifies a feature policy to allow get calls in
cross-origin i-frames. This patch implements this feature policy partially. Only
same-site, cross-origin i-frames are supported instead. This is for tracking prevention
purposes. https://w3c.github.io/webauthn/#sctn-iframe-guidance

This patch also starts passing ClientDataJSON hashes to ASC to avoid the situation
where WebKit includes crossOrigin or other fields in ClientDataJSON that ASC is
unaware of when generating ClientDataJSON.

Added layout test cases for same-site, cross-origin get calls.

* Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::create const):
(WebCore::doesHaveSameSiteAsAncestors):
(WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):
* Modules/webauthn/WebAuthenticationUtils.cpp:
(WebCore::buildClientDataJson):
* Modules/webauthn/WebAuthenticationUtils.h:
* html/FeaturePolicy.cpp:
(WebCore::policyTypeName):
(WebCore::FeaturePolicy::parse):
(WebCore::FeaturePolicy::allows const):
* html/FeaturePolicy.h:

Source/WebKit:

The Web Authentication level 2 specifies a feature policy to allow get calls in
cross-origin i-frames. This patch implements this feature policy partially. Only
same-site, cross-origin i-frames are supported instead. This is for tracking prevention
purposes. https://w3c.github.io/webauthn/#sctn-iframe-guidance

This patch also starts passing ClientDataJSON hashes to ASC to avoid the situation
where WebKit includes crossOrigin or other fields in ClientDataJSON that ASC is
unaware of when generating ClientDataJSON.

Added layout test cases for same-site, cross-origin get calls.

* Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
* UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(produceClientDataJson):
* UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
(WebKit::configureRegistrationRequestContext):
(WebKit::configurationAssertionRequestContext):
(WebKit::WebAuthenticatorCoordinatorProxy::contextForRequest):

LayoutTests:

Add layout test for WebAuthn get assertions on cross-site, same-sites i-frames with
publickey-credentials-get feature policy.

* http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt:
* http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html:
* http/wpt/webauthn/resources/util.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (287115 => 287116)


--- trunk/LayoutTests/ChangeLog	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/LayoutTests/ChangeLog	2021-12-16 00:52:57 UTC (rev 287116)
@@ -1,3 +1,18 @@
+2021-12-15  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] Allow same-site, cross-origin iframe get()
+        https://bugs.webkit.org/show_bug.cgi?id=234309
+        rdar://problem/86486313
+
+        Reviewed by Brent Fulgham.
+
+        Add layout test for WebAuthn get assertions on cross-site, same-sites i-frames with
+        publickey-credentials-get feature policy.
+
+        * http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html:
+        * http/wpt/webauthn/resources/util.js:
+
 2021-12-15  Ryan Haddad  <ryanhad...@apple.com>
 
         PCM: Remove old DB update and migration code, and add a unit test for destination token DB columns

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt (287115 => 287116)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt	2021-12-16 00:52:57 UTC (rev 287116)
@@ -2,4 +2,7 @@
 
 PASS Tests that a frame that doesn't share the same origin with all its ancestors could not access the API.
 PASS Tests that a frame that doesn't share the same origin with all its ancestors could not access the API. 2
+PASS Tests that a frame that is same-site, cross-origin without publickey-credentials-get feature policy cannot use get().
+PASS Tests that a frame that is same-site, cross-origin with publickey-credentials-get feature policy can use get().
+PASS Tests that a frame that is cross-origin, NOT same-site  with publickey-credentials-get feature policy cannot use get().
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html (287115 => 287116)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-same-origin-with-ancestors.https.html	2021-12-16 00:52:57 UTC (rev 287116)
@@ -22,6 +22,24 @@
                 assert_equals(message.data, "PASS.");
             });
         }, "Tests that a frame that doesn't share the same origin with all its ancestors could not access the API. 2");
+
+        promise_test(t => {
+            return withSameSiteIframe("samesite-iframe.html").then((message) => {
+                assert_equals(message.data, "Throw NotAllowedError: The origin of the document is not the same as its ancestors.");
+            });
+        }, "Tests that a frame that is same-site, cross-origin without publickey-credentials-get feature policy cannot use get().");
+
+        promise_test(t => {
+            return withSameSiteIframe("samesite-iframe.html", "publickey-credentials-get").then((message) => {
+                assert_equals(message.data, "PASS!");
+            });
+        }, "Tests that a frame that is same-site, cross-origin with publickey-credentials-get feature policy can use get().");
+
+        promise_test(t => {
+            return withCrossOriginIframe("samesite-iframe.html", "publickey-credentials-get").then((message) => {
+                assert_equals(message.data, "Throw NotAllowedError: The origin of the document is not the same as its ancestors.");
+            });
+        }, "Tests that a frame that is cross-origin, NOT same-site  with publickey-credentials-get feature policy cannot use get().");
     </script>
 </body>
 </html>

Added: trunk/LayoutTests/http/wpt/webauthn/resources/samesite-iframe.html (0 => 287116)


--- trunk/LayoutTests/http/wpt/webauthn/resources/samesite-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/resources/samesite-iframe.html	2021-12-16 00:52:57 UTC (rev 287116)
@@ -0,0 +1,30 @@
+<script src=""
+<input type="text" id="input">
+<script>
+    const url = "" URL(window.location.href);
+    if (window.internals)
+        internals.setMockWebAuthenticationConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testAssertionMessageBase64] } });
+
+    function messageToTop(message) {
+        top.postMessage(message, "*");
+    }
+
+    const requestOptions = {
+        publicKey: {
+            challenge: asciiToUint8Array("123456"),
+            timeout: 100
+        }
+    };
+
+    if (window.internals)
+        internals.withUserGesture(() => { input.focus(); });
+
+    navigator.credentials.get(requestOptions).then(
+        function(value) {
+            messageToTop("PASS!");
+        },
+        function(exception) {
+            messageToTop("Throw " + exception.name + ": " + exception.message);
+      }
+    );
+</script>

Modified: trunk/LayoutTests/http/wpt/webauthn/resources/util.js (287115 => 287116)


--- trunk/LayoutTests/http/wpt/webauthn/resources/util.js	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/LayoutTests/http/wpt/webauthn/resources/util.js	2021-12-16 00:52:57 UTC (rev 287116)
@@ -304,7 +304,7 @@
     });
 }
 
-function withCrossOriginIframe(resourceFile)
+function withCrossOriginIframe(resourceFile, allow = "")
 {
     return new Promise((resolve) => {
         waitForLoad().then((message) => {
@@ -311,11 +311,26 @@
             resolve(message);
         });
         const frame = document.createElement("iframe");
+        frame.allow = allow;
         frame.src = "" + RESOURCES_DIR + resourceFile;
         document.body.appendChild(frame);
     });
 }
 
+function withSameSiteIframe(resourceFile, allow = "")
+{
+    return new Promise((resolve) => {
+        waitForLoad().then((message) => {
+            resolve(message);
+       });
+       const frame = document.createElement("iframe");
+       const host = get_host_info();
+       frame.allow = allow;
+       frame.src = "" + host.ORIGINAL_HOST + ":" + host.HTTPS_PORT2 + RESOURCES_DIR + resourceFile;
+       document.body.appendChild(frame);
+    });
+}
+
 function promiseRejects(test, expected, promise, description)
 {
     return promise.then(test.unreached_func("Should have rejected: " + description)).catch(function(e) {

Modified: trunk/Source/WebCore/ChangeLog (287115 => 287116)


--- trunk/Source/WebCore/ChangeLog	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/ChangeLog	2021-12-16 00:52:57 UTC (rev 287116)
@@ -1,3 +1,35 @@
+2021-12-15  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] Allow same-site, cross-origin iframe get()
+        https://bugs.webkit.org/show_bug.cgi?id=234309
+        rdar://problem/86486313
+
+        Reviewed by Brent Fulgham.
+
+        The Web Authentication level 2 specifies a feature policy to allow get calls in
+        cross-origin i-frames. This patch implements this feature policy partially. Only
+        same-site, cross-origin i-frames are supported instead. This is for tracking prevention
+        purposes. https://w3c.github.io/webauthn/#sctn-iframe-guidance
+
+        This patch also starts passing ClientDataJSON hashes to ASC to avoid the situation
+        where WebKit includes crossOrigin or other fields in ClientDataJSON that ASC is
+        unaware of when generating ClientDataJSON.
+
+        Added layout test cases for same-site, cross-origin get calls.
+
+        * Modules/webauthn/AuthenticatorCoordinator.cpp:
+        (WebCore::AuthenticatorCoordinator::create const):
+        (WebCore::doesHaveSameSiteAsAncestors):
+        (WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):
+        * Modules/webauthn/WebAuthenticationUtils.cpp:
+        (WebCore::buildClientDataJson):
+        * Modules/webauthn/WebAuthenticationUtils.h:
+        * html/FeaturePolicy.cpp:
+        (WebCore::policyTypeName):
+        (WebCore::FeaturePolicy::parse):
+        (WebCore::FeaturePolicy::allows const):
+        * html/FeaturePolicy.h:
+
 2021-12-15  Brent Fulgham  <bfulg...@apple.com>
 
         Clean-up: Adopt Page::forEachDocument in some missed spots

Modified: trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp (287115 => 287116)


--- trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp	2021-12-16 00:52:57 UTC (rev 287116)
@@ -37,6 +37,7 @@
 #include "JSDOMPromiseDeferred.h"
 #include "Page.h"
 #include "SecurityOrigin.h"
+#include "WebAuthenticationConstants.h"
 
 namespace WebCore {
 
@@ -45,19 +46,27 @@
 {
 }
 
-bool CredentialsContainer::doesHaveSameOriginAsItsAncestors()
+WebAuthn::Scope CredentialsContainer::scope()
 {
-    // The following implements https://w3c.github.io/webappsec-credential-management/#same-origin-with-its-ancestors
-    // as of 14 November 2017.
     if (!m_document)
-        return false;
+        return WebAuthn::Scope::CrossOrigin;
 
+    bool isSameOrigin = true;
+    bool isSameSite = true;
     auto& origin = m_document->securityOrigin();
+    auto& url = ""
     for (auto* document = m_document->parentDocument(); document; document = document->parentDocument()) {
+        if (!origin.isSameOriginDomain(document->securityOrigin()) && !areRegistrableDomainsEqual(url, document->url()))
+            isSameSite = false;
         if (!origin.isSameOriginAs(document->securityOrigin()))
-            return false;
+            isSameOrigin = false;
     }
-    return true;
+
+    if (isSameOrigin)
+        return WebAuthn::Scope::SameOrigin;
+    if (isSameSite)
+        return WebAuthn::Scope::SameSite;
+    return WebAuthn::Scope::CrossOrigin;
 }
 
 void CredentialsContainer::get(CredentialRequestOptions&& options, CredentialPromise&& promise)
@@ -89,7 +98,7 @@
         return;
     }
 
-    m_document->page()->authenticatorCoordinator().discoverFromExternalSource(*m_document, options.publicKey.value(), doesHaveSameOriginAsItsAncestors(), WTFMove(options.signal), WTFMove(promise));
+    m_document->page()->authenticatorCoordinator().discoverFromExternalSource(*m_document, options.publicKey.value(), scope(), WTFMove(options.signal), WTFMove(promise));
 }
 
 void CredentialsContainer::store(const BasicCredential&, CredentialPromise&& promise)
@@ -124,7 +133,7 @@
         return;
     }
 
-    m_document->page()->authenticatorCoordinator().create(*m_document, options.publicKey.value(), doesHaveSameOriginAsItsAncestors(), WTFMove(options.signal), WTFMove(promise));
+    m_document->page()->authenticatorCoordinator().create(*m_document, options.publicKey.value(), scope(), WTFMove(options.signal), WTFMove(promise));
 }
 
 void CredentialsContainer::preventSilentAccess(DOMPromiseDeferred<void>&& promise) const

Modified: trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h (287115 => 287116)


--- trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -32,6 +32,10 @@
 #include <wtf/RefCounted.h>
 #include <wtf/WeakPtr.h>
 
+namespace WebAuthn {
+enum class Scope;
+}
+
 namespace WebCore {
 
 class Document;
@@ -54,7 +58,7 @@
 private:
     CredentialsContainer(WeakPtr<Document>&&);
 
-    bool doesHaveSameOriginAsItsAncestors();
+    WebAuthn::Scope scope();
 
     WeakPtr<Document> m_document;
 };

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp (287115 => 287116)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2021-12-16 00:52:57 UTC (rev 287116)
@@ -34,6 +34,7 @@
 #include "AuthenticatorCoordinatorClient.h"
 #include "AuthenticatorResponseData.h"
 #include "Document.h"
+#include "FeaturePolicy.h"
 #include "JSBasicCredential.h"
 #include "JSDOMPromiseDeferred.h"
 #include "PublicKeyCredential.h"
@@ -104,7 +105,7 @@
     m_client = WTFMove(client);
 }
 
-void AuthenticatorCoordinator::create(const Document& document, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const
+void AuthenticatorCoordinator::create(const Document& document, const PublicKeyCredentialCreationOptions& options, WebAuthn::Scope scope, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const
 {
     using namespace AuthenticatorCoordinatorInternal;
 
@@ -114,7 +115,7 @@
     // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017.
     // Step 1, 3, 16 are handled by the caller.
     // Step 2.
-    if (!sameOriginWithAncestors) {
+    if (scope != WebAuthn::Scope::SameOrigin) {
         promise.reject(Exception { NotAllowedError, "The origin of the document is not the same as its ancestors."_s });
         return;
     }
@@ -148,7 +149,7 @@
     options.extensions = AuthenticationExtensionsClientInputs { String(), processGoogleLegacyAppIdSupportExtension(options.extensions, options.rp.id) };
 
     // Step 13-15.
-    auto clientDataJson = buildClientDataJson(ClientDataType::Create, options.challenge, callerOrigin);
+    auto clientDataJson = buildClientDataJson(ClientDataType::Create, options.challenge, callerOrigin, scope);
     auto clientDataJsonHash = buildClientDataJsonHash(clientDataJson);
 
     // Step 4, 17-21.
@@ -175,7 +176,7 @@
     m_client->makeCredential(*frame, callerOrigin, clientDataJsonHash, options, WTFMove(callback));
 }
 
-void AuthenticatorCoordinator::discoverFromExternalSource(const Document& document, const PublicKeyCredentialRequestOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const
+void AuthenticatorCoordinator::discoverFromExternalSource(const Document& document, const PublicKeyCredentialRequestOptions& options, WebAuthn::Scope scope, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const
 {
     using namespace AuthenticatorCoordinatorInternal;
 
@@ -185,7 +186,8 @@
     // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017.
     // Step 1, 3, 13 are handled by the caller.
     // Step 2.
-    if (!sameOriginWithAncestors) {
+    // This implements https://www.w3.org/TR/webauthn-2/#sctn-permissions-policy except only same-site, cross-origin is permitted.
+    if (scope != WebAuthn::Scope::SameOrigin && !(scope == WebAuthn::Scope::SameSite && isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::PublickeyCredentialsGetRule, document, LogFeaturePolicyFailure::No))) {
         promise.reject(Exception { NotAllowedError, "The origin of the document is not the same as its ancestors."_s });
         return;
     }
@@ -219,7 +221,7 @@
     }
 
     // Step 10-12.
-    auto clientDataJson = buildClientDataJson(ClientDataType::Get, options.challenge, callerOrigin);
+    auto clientDataJson = buildClientDataJson(ClientDataType::Get, options.challenge, callerOrigin, scope);
     auto clientDataJsonHash = buildClientDataJsonHash(clientDataJson);
 
     // Step 4, 14-19.

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.h (287115 => 287116)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -31,6 +31,10 @@
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 
+namespace WebAuthn {
+enum class Scope;
+}
+
 namespace WebCore {
 
 class AbortSignal;
@@ -53,8 +57,8 @@
     WEBCORE_EXPORT void setClient(std::unique_ptr<AuthenticatorCoordinatorClient>&&);
 
     // The following methods implement static methods of PublicKeyCredential.
-    void create(const Document&, const PublicKeyCredentialCreationOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, CredentialPromise&&) const;
-    void discoverFromExternalSource(const Document&, const PublicKeyCredentialRequestOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, CredentialPromise&&) const;
+    void create(const Document&, const PublicKeyCredentialCreationOptions&, WebAuthn::Scope, RefPtr<AbortSignal>&&, CredentialPromise&&) const;
+    void discoverFromExternalSource(const Document&, const PublicKeyCredentialRequestOptions&, WebAuthn::Scope, RefPtr<AbortSignal>&&, CredentialPromise&&) const;
     void isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&&) const;
 
     void resetUserGestureRequirement();

Modified: trunk/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h (287115 => 287116)


--- trunk/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -80,3 +80,13 @@
 const char LocalAuthenticatiorAccessGroup[] = "com.apple.webkit.webauthn";
 
 } // namespace WebCore
+
+namespace WebAuthn {
+
+enum class Scope {
+    CrossOrigin,
+    SameOrigin,
+    SameSite
+};
+
+} // namespace WebAuthn

Modified: trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp (287115 => 287116)


--- trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp	2021-12-16 00:52:57 UTC (rev 287116)
@@ -134,7 +134,7 @@
 }
 
 // FIXME(181948): Add token binding ID.
-Ref<ArrayBuffer> buildClientDataJson(ClientDataType type, const BufferSource& challenge, const SecurityOrigin& origin)
+Ref<ArrayBuffer> buildClientDataJson(ClientDataType type, const BufferSource& challenge, const SecurityOrigin& origin, WebAuthn::Scope scope)
 {
     auto object = JSON::Object::create();
     switch (type) {
@@ -147,6 +147,8 @@
     }
     object->setString("challenge"_s, base64URLEncodeToString(challenge.data(), challenge.length()));
     object->setString("origin"_s, origin.toRawString());
+    if (scope != WebAuthn::Scope::SameOrigin)
+        object->setBoolean("crossOrigin"_s, scope != WebAuthn::Scope::SameOrigin);
 
     auto utf8JSONString = object->toJSONString().utf8();
 

Modified: trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h (287115 => 287116)


--- trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -52,7 +52,7 @@
 // https://www.w3.org/TR/webauthn/#attestation-object
 WEBCORE_EXPORT Vector<uint8_t> buildAttestationObject(Vector<uint8_t>&& authData, String&& format, cbor::CBORValue::MapValue&& statementMap, const AttestationConveyancePreference&);
 
-WEBCORE_EXPORT Ref<ArrayBuffer> buildClientDataJson(ClientDataType /*type*/, const BufferSource& challenge, const SecurityOrigin& /*origin*/);
+WEBCORE_EXPORT Ref<ArrayBuffer> buildClientDataJson(ClientDataType /*type*/, const BufferSource& challenge, const SecurityOrigin& /*origin*/, WebAuthn::Scope);
 
 WEBCORE_EXPORT Vector<uint8_t> buildClientDataJsonHash(const ArrayBuffer& clientDataJson);
 

Modified: trunk/Source/WebCore/html/FeaturePolicy.cpp (287115 => 287116)


--- trunk/Source/WebCore/html/FeaturePolicy.cpp	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/html/FeaturePolicy.cpp	2021-12-16 00:52:57 UTC (rev 287116)
@@ -67,6 +67,10 @@
     case FeaturePolicy::Type::Magnetometer:
         return "Magnetometer";
 #endif
+#if ENABLE(WEB_AUTHN)
+    case FeaturePolicy::Type::PublickeyCredentialsGetRule:
+        return "PublickeyCredentialsGet";
+#endif
 #if ENABLE(WEBXR)
     case FeaturePolicy::Type::XRSpatialTracking:
         return "XRSpatialTracking";
@@ -184,6 +188,9 @@
     bool isAccelerometerInitialized = false;
     bool isMagnetometerInitialized = false;
 #endif
+#if ENABLE(WEB_AUTHN)
+    bool isPublickeyCredentialsGetInitialized = false;
+#endif
 #if ENABLE(WEBXR)
     bool isXRSpatialTrackingInitialized = false;
 #endif
@@ -251,6 +258,13 @@
             continue;
         }
 #endif
+#if ENABLE(WEB_AUTHN)
+        if (item.startsWith("publickey-credentials-get")) {
+            isPublickeyCredentialsGetInitialized = true;
+            updateList(document, policy.m_publickeyCredentialsGetRule, item.substring(26));
+            continue;
+        }
+#endif
 #if ENABLE(WEBXR)
         if (item.startsWith("xr-spatial-tracking")) {
             isXRSpatialTrackingInitialized = true;
@@ -283,6 +297,10 @@
     if (!isMagnetometerInitialized)
         policy.m_magnetometerRule.allowedList.add(document.securityOrigin().data());
 #endif
+#if ENABLE(WEB_AUTHN)
+    if (!isPublickeyCredentialsGetInitialized)
+        policy.m_publickeyCredentialsGetRule.allowedList.add(document.securityOrigin().data());
+#endif
 #if ENABLE(WEBXR)
     if (!isXRSpatialTrackingInitialized)
         policy.m_xrSpatialTrackingRule.allowedList.add(document.securityOrigin().data());
@@ -338,6 +356,10 @@
     case Type::Magnetometer:
         return isAllowedByFeaturePolicy(m_magnetometerRule, origin);
 #endif
+#if ENABLE(WEB_AUTHN)
+    case Type::PublickeyCredentialsGetRule:
+        return isAllowedByFeaturePolicy(m_publickeyCredentialsGetRule, origin);
+#endif
 #if ENABLE(WEBXR)
     case Type::XRSpatialTracking:
         return isAllowedByFeaturePolicy(m_xrSpatialTrackingRule, origin);

Modified: trunk/Source/WebCore/html/FeaturePolicy.h (287115 => 287116)


--- trunk/Source/WebCore/html/FeaturePolicy.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebCore/html/FeaturePolicy.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -53,6 +53,9 @@
         Accelerometer,
         Magnetometer,
 #endif
+#if ENABLE(WEB_AUTHN)
+        PublickeyCredentialsGetRule,
+#endif
 #if ENABLE(WEBXR)
         XRSpatialTracking,
 #endif
@@ -81,6 +84,9 @@
     AllowRule m_accelerometerRule;
     AllowRule m_magnetometerRule;
 #endif
+#if ENABLE(WEB_AUTHN)
+    AllowRule m_publickeyCredentialsGetRule;
+#endif
 #if ENABLE(WEBXR)
     AllowRule m_xrSpatialTrackingRule;
 #endif

Modified: trunk/Source/WebKit/ChangeLog (287115 => 287116)


--- trunk/Source/WebKit/ChangeLog	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebKit/ChangeLog	2021-12-16 00:52:57 UTC (rev 287116)
@@ -1,3 +1,30 @@
+2021-12-15  J Pascoe  <j_pas...@apple.com>
+
+        [WebAuthn] Allow same-site, cross-origin iframe get()
+        https://bugs.webkit.org/show_bug.cgi?id=234309
+        rdar://problem/86486313
+
+        Reviewed by Brent Fulgham.
+
+        The Web Authentication level 2 specifies a feature policy to allow get calls in
+        cross-origin i-frames. This patch implements this feature policy partially. Only
+        same-site, cross-origin i-frames are supported instead. This is for tracking prevention
+        purposes. https://w3c.github.io/webauthn/#sctn-iframe-guidance
+
+        This patch also starts passing ClientDataJSON hashes to ASC to avoid the situation
+        where WebKit includes crossOrigin or other fields in ClientDataJSON that ASC is
+        unaware of when generating ClientDataJSON.
+
+        Added layout test cases for same-site, cross-origin get calls.
+
+        * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
+        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
+        (produceClientDataJson):
+        * UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
+        (WebKit::configureRegistrationRequestContext):
+        (WebKit::configurationAssertionRequestContext):
+        (WebKit::WebAuthenticatorCoordinatorProxy::contextForRequest):
+
 2021-12-15  Alex Christensen  <achristen...@webkit.org>
 
         Remove ProxyServer

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


--- trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2021-12-16 00:52:57 UTC (rev 287116)
@@ -25,10 +25,7 @@
 
 #pragma once
 
-#if HAVE(UNIFIED_ASC_AUTH_UI)
-#import <AuthenticationServicesCore/AuthenticationServicesCore.h>
-#import <AuthenticationServicesCore/AuthenticationServicesCorePrivate.h>
-#elif HAVE(ASC_AUTH_UI)
+#if HAVE(ASC_AUTH_UI) || HAVE(UNIFIED_ASC_AUTH_UI)
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -71,6 +68,14 @@
 
 @end
 
+@interface ASCAuthorizationRemotePresenter : NSObject
+
+#if TARGET_OS_OSX
+- (void)presentWithWindow:(NSWindow *)window daemonEndpoint:(NSXPCListenerEndpoint *)daemonEndpoint completionHandler:(void (^)(id <ASCCredentialProtocol>, NSError *))completionHandler;
+#endif
+
+@end
+
 @class ASCCredentialRequestContext;
 
 extern NSString * const ASCAuthorizationPresentationContextDataKey;
@@ -105,16 +110,65 @@
     ASCSecurityKeyPublicKeyCredentialKindAssertionPlaceholder,
 };
 
+@class ASCPublicKeyCredentialDescriptor;
+
+@interface ASCPublicKeyCredentialDescriptor : NSObject <NSSecureCoding>
+
+- (instancetype)initWithCredentialID:(NSData *)credentialID transports:(nullable NSArray<NSString *> *)allowedTransports;
+
+@property (nonatomic, readonly) NSData *credentialID;
+@property (nonatomic, nullable, readonly) NSArray<NSString *> *transports;
+
+@end
+
+@class ASCPublicKeyCredentialDescriptor;
+
+typedef NS_ENUM(NSUInteger, ASCPublicKeyCredentialKind) {
+    ASCPublicKeyCredentialKindPlatform = 1,
+    ASCPublicKeyCredentialKindSecurityKey,
+};
+
+@interface ASCPublicKeyCredentialAssertionOptions : NSObject <NSSecureCoding>
+
+- (instancetype)initWithKind:(ASCPublicKeyCredentialKind)credentialKind relyingPartyIdentifier:(NSString *)relyingPartyIdentifier challenge:(NSData *)challenge userVerificationPreference:(nullable NSString *)userVerificationPreference allowedCredentials:(nullable NSArray<ASCPublicKeyCredentialDescriptor *> *)allowedCredentials;
+
+- (instancetype)initWithKind:(ASCPublicKeyCredentialKind)credentialKind relyingPartyIdentifier:(NSString *)relyingPartyIdentifier clientDataHash:(NSData *)clientDataHash userVerificationPreference:(nullable NSString *)userVerificationPreference allowedCredentials:(nullable NSArray<ASCPublicKeyCredentialDescriptor *> *)allowedCredentials;
+
+@property (nonatomic, readonly) ASCPublicKeyCredentialKind credentialKind;
+@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
+@property (nonatomic, nullable, copy, readonly) NSData *challenge;
+// If clientDataHash is null, then gets generated from challenge and relyingPartyIdentifier.
+@property (nonatomic, nullable, copy) NSData *clientDataHash;
+@property (nonatomic, nullable, readonly, copy) NSString *userVerificationPreference;
+
+@property (nonatomic, nullable, readonly, copy) NSArray<ASCPublicKeyCredentialDescriptor *> *allowedCredentials;
+
+@end
+
+
+typedef NS_OPTIONS(NSUInteger, ASCCredentialRequestTypes) {
+    ASCCredentialRequestTypeNone = 0,
+    ASCCredentialRequestTypePassword = 1 << 0,
+    ASCCredentialRequestTypeAppleID = 1 << 1,
+    ASCCredentialRequestTypePlatformPublicKeyRegistration = 1 << 2,
+    ASCCredentialRequestTypePlatformPublicKeyAssertion = 1 << 3,
+    ASCCredentialRequestTypeSecurityKeyPublicKeyRegistration = 1 << 4,
+    ASCCredentialRequestTypeSecurityKeyPublicKeyAssertion = 1 << 5,
+};
+
 @interface ASCPublicKeyCredentialCreationOptions : NSObject <NSSecureCoding>
 
-@property (nonatomic, copy) NSData *challenge;
+@property (nonatomic, nullable, copy) NSData *challenge;
+@property (nonatomic, nullable, copy) NSData *clientDataHash;
 @property (nonatomic, copy) NSString *relyingPartyIdentifier;
 @property (nonatomic, copy) NSString *userName;
 @property (nonatomic, copy) NSData *userIdentifier;
 @property (nonatomic, copy) NSString *userDisplayName;
 @property (nonatomic, copy) NSArray<NSNumber *> *supportedAlgorithmIdentifiers;
+@property (nonatomic, nullable, copy) NSString *userVerificationPreference;
 
 @property (nonatomic) BOOL shouldRequireResidentKey;
+@property (nonatomic, copy) NSArray<ASCPublicKeyCredentialDescriptor *> *excludedCredentials;
 
 @end
 
@@ -149,10 +203,115 @@
 
 @end
 
+@interface ASCCredentialRequestContext : NSObject <NSSecureCoding>
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+- (instancetype)initWithRequestTypes:(ASCCredentialRequestTypes)requestTypes;
+
+@property (nonatomic, readonly) NSUInteger requestTypes;
+@property (nonatomic, nullable, copy) NSString *relyingPartyIdentifier;
+
+@property (nonatomic, nullable, copy) ASCPublicKeyCredentialCreationOptions *platformKeyCredentialCreationOptions;
+@property (nonatomic, nullable, copy) ASCPublicKeyCredentialCreationOptions *securityKeyCredentialCreationOptions;
+
+@property (nonatomic, nullable, copy) ASCPublicKeyCredentialAssertionOptions *platformKeyCredentialAssertionOptions;
+@property (nonatomic, nullable, copy) ASCPublicKeyCredentialAssertionOptions *securityKeyCredentialAssertionOptions;
+
+@end
+
 @protocol ASCCredentialProtocol <NSObject, NSSecureCoding>
 
 @end
 
+@class _WKAuthenticatorAttestationResponse;
+
+@interface ASCPlatformPublicKeyCredentialRegistration : NSObject <ASCCredentialProtocol>
+
+- (instancetype)initWithRelyingPartyIdentifier:(NSString *)relyingPartyIdentifier attestationObject:(NSData *)attestationObject rawClientDataJSON:(NSData *)rawClientDataJSON credentialID:(NSData *)credentialID;
+
+- (instancetype)initWithRelyingPartyIdentifier:(NSString *)relyingPartyIdentifier authenticatorAttestationResponse:(_WKAuthenticatorAttestationResponse *)attestationResponse rawClientDataJSON:(NSData *)rawClientDataJSON;
+
+@property (nonatomic, copy, readonly) NSData *credentialID;
+@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
+@property (nonatomic, copy, readonly) NSData *attestationObject;
+@property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
+
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+@interface ASCSecurityKeyPublicKeyCredentialRegistration : NSObject <ASCCredentialProtocol>
+
+- (instancetype)initWithRelyingPartyIdentifier:(NSString *)relyingPartyIdentifier authenticatorAttestationResponse:(_WKAuthenticatorAttestationResponse *)attestationResponse;
+
+@property (nonatomic, copy, readonly) NSData *credentialID;
+@property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
+@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
+@property (nonatomic, copy, readonly) NSData *attestationObject;
+
+@end
+
+@class _WKAuthenticatorAssertionResponse;
+
+@interface ASCPlatformPublicKeyCredentialAssertion : NSObject <ASCCredentialProtocol>
+
+- (instancetype)initWithRelyingPartyIdentifier:(NSString *)relyingPartyIdentifier authenticatorAssertionResponse:(_WKAuthenticatorAssertionResponse *)assertionResponse;
+
+@property (nonatomic, copy, readonly) NSData *credentialID;
+@property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
+@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
+@property (nonatomic, copy, readonly) NSData *authenticatorData;
+@property (nonatomic, copy, readonly) NSData *signature;
+@property (nonatomic, copy, readonly, nullable) NSData *userHandle;
+
+@end
+
+@interface ASCSecurityKeyPublicKeyCredentialAssertion : NSObject <ASCCredentialProtocol>
+
+- (instancetype)initWithRelyingPartyIdentifier:(NSString *)relyingPartyIdentifier authenticatorAssertionResponse:(_WKAuthenticatorAssertionResponse *)assertionResponse;
+
+@property (nonatomic, copy, readonly) NSData *credentialID;
+@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
+@property (nonatomic, copy, readonly) NSData *authenticatorData;
+@property (nonatomic, copy, readonly) NSData *signature;
+@property (nonatomic, copy, readonly, nullable) NSData *userHandle;
+@property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
+
+@end
+
+@protocol ASCAgentProtocol <NSObject>
+
+#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
+- (void)performAuthorizationRequestsForContext:(ASCCredentialRequestContext *)context withCompletionHandler:(void (^)(id <ASCCredentialProtocol> _Nullable credential, NSError * _Nullable error))completionHandler;
+#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST
+- (void)performAuthorizationRequestsForContext:(ASCCredentialRequestContext *)context withClearanceHandler:(void (^)(NSXPCListenerEndpoint * _Nullable daemonEndpoint, NSError * _Nullable error))clearanceHandler;
+
+- (void)beginAuthorizationForApplicationIdentifier:(NSString *)applicationIdentifier fromEndpoint:(NSXPCListenerEndpoint *)listenerEndpoint;
+
+- (void)userSelectedLoginChoice:(id <ASCLoginChoiceProtocol>)loginChoice authenticatedContext:(LAContext *)context completionHandler:(void (^)(id <ASCCredentialProtocol> _Nullable, NSError * _Nullable))completionHandler;
+
+- (void)requestCompletedWithCredential:(nullable id<ASCCredentialProtocol>)credential error:(nullable NSError *)error;
+#endif
+
+@end
+
+@interface ASCAgentProxy : NSObject <ASCAgentProtocol>
+
+- (instancetype)init;
+
+#if TARGET_OS_OSX
+- (instancetype)initWithEndpoint:(NSXPCListenerEndpoint *)endpoint;
+#endif
+
+- (void)invalidate;
+
+- (void)reconnectIfNecessary;
+
+@end
+
 // FIXME(219767): Remove ASCAppleIDCredential.
 @interface ASCAppleIDCredential : NSObject <ASCCredentialProtocol>
 

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


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2021-12-16 00:52:57 UTC (rev 287116)
@@ -87,7 +87,7 @@
     auto challengeBuffer = ArrayBuffer::tryCreate(reinterpret_cast<const uint8_t*>(challenge.bytes), challenge.length);
     auto securityOrigin = WebCore::SecurityOrigin::createFromString(origin);
 
-    auto clientDataJson = buildClientDataJson(clientDataType, WebCore::BufferSource(challengeBuffer), securityOrigin);
+    auto clientDataJson = buildClientDataJson(clientDataType, WebCore::BufferSource(challengeBuffer), securityOrigin, WebAuthn::Scope::SameOrigin);
     return adoptNS([[NSData alloc] initWithBytes:clientDataJson->data() length:clientDataJson->byteLength()]);
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm (287115 => 287116)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2021-12-16 00:51:44 UTC (rev 287115)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2021-12-16 00:52:57 UTC (rev 287116)
@@ -50,6 +50,11 @@
     return ArrayBuffer::create(reinterpret_cast<const uint8_t*>(data.bytes), data.length);
 }
 
+static inline RetainPtr<NSData> toNSData(const Vector<uint8_t>& data)
+{
+    return adoptNS([[NSData alloc] initWithBytes:data.data() length:data.size()]);
+}
+
 static inline RetainPtr<NSString> toNSString(UserVerificationRequirement userVerificationRequirement)
 {
     switch (userVerificationRequirement) {
@@ -145,7 +150,7 @@
     return adoptNS([allocASCPublicKeyCredentialDescriptorInstance() initWithCredentialID:WebCore::toNSData(descriptor.id).get() transports:transports.get()]);
 }
 
-static RetainPtr<ASCCredentialRequestContext> configureRegistrationRequestContext(const PublicKeyCredentialCreationOptions& options)
+static RetainPtr<ASCCredentialRequestContext> configureRegistrationRequestContext(const PublicKeyCredentialCreationOptions& options, Vector<uint8_t> hash)
 {
     ASCCredentialRequestTypes requestTypes = ASCCredentialRequestTypePlatformPublicKeyRegistration | ASCCredentialRequestTypeSecurityKeyPublicKeyRegistration;
 
@@ -169,7 +174,10 @@
 
     auto credentialCreationOptions = adoptNS([allocASCPublicKeyCredentialCreationOptionsInstance() init]);
 
-    [credentialCreationOptions setChallenge:WebCore::toNSData(options.challenge).get()];
+    if ([credentialCreationOptions respondsToSelector:@selector(setClientDataHash:)])
+        [credentialCreationOptions setClientDataHash:toNSData(hash).get()];
+    else
+        [credentialCreationOptions setChallenge:WebCore::toNSData(options.challenge).get()];
     [credentialCreationOptions setRelyingPartyIdentifier:options.rp.id];
     [credentialCreationOptions setUserName:options.user.name];
     [credentialCreationOptions setUserIdentifier:WebCore::toNSData(options.user.id).get()];
@@ -202,7 +210,7 @@
     return requestContext;
 }
 
-static RetainPtr<ASCCredentialRequestContext> configurationAssertionRequestContext(const PublicKeyCredentialRequestOptions& options)
+static RetainPtr<ASCCredentialRequestContext> configurationAssertionRequestContext(const PublicKeyCredentialRequestOptions& options, Vector<uint8_t> hash)
 {
     ASCCredentialRequestTypes requestTypes = ASCCredentialRequestTypePlatformPublicKeyAssertion | ASCCredentialRequestTypeSecurityKeyPublicKeyAssertion;
 
@@ -227,13 +235,30 @@
     auto requestContext = adoptNS([allocASCCredentialRequestContextInstance() initWithRequestTypes:requestTypes]);
     [requestContext setRelyingPartyIdentifier:options.rpId];
 
-    auto challenge = WebCore::toNSData(options.challenge);
+    if (requestTypes & ASCCredentialRequestTypePlatformPublicKeyAssertion) {
+        auto assertionOptions = adoptNS(allocASCPublicKeyCredentialAssertionOptionsInstance());
+        if ([assertionOptions respondsToSelector:@selector(initWithKind:relyingPartyIdentifier:clientDataHash:userVerificationPreference:allowedCredentials:)]) {
+            auto nsHash = toNSData(hash);
+            [assertionOptions initWithKind:ASCPublicKeyCredentialKindPlatform relyingPartyIdentifier:options.rpId clientDataHash:nsHash.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()];
+        } else {
+            auto challenge = WebCore::toNSData(options.challenge);
+            [assertionOptions initWithKind:ASCPublicKeyCredentialKindPlatform relyingPartyIdentifier:options.rpId challenge:challenge.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()];
+        }
 
-    if (requestTypes & ASCCredentialRequestTypePlatformPublicKeyAssertion)
-        [requestContext setPlatformKeyCredentialAssertionOptions:[allocASCPublicKeyCredentialAssertionOptionsInstance() initWithKind:ASCPublicKeyCredentialKindPlatform relyingPartyIdentifier:options.rpId challenge:challenge.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()]];
+        [requestContext setPlatformKeyCredentialAssertionOptions:assertionOptions.get()];
+    }
 
-    if (requestTypes & ASCCredentialRequestTypeSecurityKeyPublicKeyAssertion)
-        [requestContext setSecurityKeyCredentialAssertionOptions:[allocASCPublicKeyCredentialAssertionOptionsInstance() initWithKind:ASCPublicKeyCredentialKindSecurityKey relyingPartyIdentifier:options.rpId challenge:challenge.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()]];
+    if (requestTypes & ASCCredentialRequestTypeSecurityKeyPublicKeyAssertion) {
+        auto assertionOptions = adoptNS(allocASCPublicKeyCredentialAssertionOptionsInstance());
+        if ([assertionOptions respondsToSelector:@selector(initWithKind:relyingPartyIdentifier:clientDataHash:userVerificationPreference:allowedCredentials:)]) {
+            auto nsHash = toNSData(hash);
+            [assertionOptions initWithKind:ASCPublicKeyCredentialKindSecurityKey relyingPartyIdentifier:options.rpId clientDataHash:nsHash.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()];
+        } else {
+            auto challenge = WebCore::toNSData(options.challenge);
+            [assertionOptions initWithKind:ASCPublicKeyCredentialKindSecurityKey relyingPartyIdentifier:options.rpId challenge:challenge.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()];
+        }
+        [requestContext setSecurityKeyCredentialAssertionOptions:assertionOptions.get()];
+    }
 
     return requestContext;
 }
@@ -242,9 +267,9 @@
 {
     RetainPtr<ASCCredentialRequestContext> result;
     WTF::switchOn(requestData.options, [&](const PublicKeyCredentialCreationOptions& options) {
-        result = configureRegistrationRequestContext(options);
+        result = configureRegistrationRequestContext(options, requestData.hash);
     }, [&](const PublicKeyCredentialRequestOptions& options) {
-        result = configurationAssertionRequestContext(options);
+        result = configurationAssertionRequestContext(options, requestData.hash);
     });
     return result;
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to