Title: [249949] trunk/Source
Revision
249949
Author
jiewen_...@apple.com
Date
2019-09-17 01:17:17 -0700 (Tue, 17 Sep 2019)

Log Message

[WebAuthn] Use WebPreferences instead of RuntimeEnabledFeatures in UIProcess
https://bugs.webkit.org/show_bug.cgi?id=198176
<rdar://problem/55285709>

Reviewed by Youenn Fablet.

Source/WebCore:

No changes of behavior.

* Modules/webauthn/PublicKeyCredential.cpp:
(WebCore::PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable):
Resolves the promise with false immediately when the feature flag is false.

Source/WebKit:

This patch does the following two things:
1) It merges WebAuthenticationRequestData::creationOptions and requestOptions into a variant, and therefore
merges code paths that involve WebAuthenticationRequestData.
2) It teaches WebAuthenticationRequestData to store a WebPreferences such that AuthenticatorManager could utilize
runtime feature flags to turn features on or off.

* UIProcess/WebAuthentication/Authenticator.cpp:
(WebKit::Authenticator::handleRequest):
* UIProcess/WebAuthentication/AuthenticatorManager.cpp:
(WebKit::AuthenticatorManager::handleRequest):
(WebKit::AuthenticatorManager::clearState):
(WebKit::AuthenticatorManager::authenticatorAdded):
(WebKit::AuthenticatorManager::startDiscovery):
(WebKit::AuthenticatorManager::makeCredential): Deleted.
(WebKit::AuthenticatorManager::getAssertion): Deleted.
* UIProcess/WebAuthentication/AuthenticatorManager.h:
* UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
(WebKit::LocalAuthenticator::makeCredential):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterUserConsented):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested):
(WebKit::LocalAuthenticator::getAssertion):
(WebKit::LocalAuthenticator::continueGetAssertionAfterUserConsented):
* UIProcess/WebAuthentication/Cocoa/LocalService.mm:
(WebKit::LocalService::isAvailable):
Don't check RuntimeEnabledFeatures given it is for WebCore.
* UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
(): Deleted.
* UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:
(WebKit::WebAuthenticatorCoordinatorProxy::makeCredential):
(WebKit::WebAuthenticatorCoordinatorProxy::getAssertion):
(WebKit::WebAuthenticatorCoordinatorProxy::handleRequest):
* UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h:
* UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
(WebKit::CtapAuthenticator::makeCredential):
(WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived const):
(WebKit::CtapAuthenticator::getAssertion):
* UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp:
(WebKit::U2fAuthenticator::makeCredential):
(WebKit::U2fAuthenticator::checkExcludeList):
(WebKit::U2fAuthenticator::issueRegisterCommand):
(WebKit::U2fAuthenticator::getAssertion):
(WebKit::U2fAuthenticator::issueSignCommand):
(WebKit::U2fAuthenticator::continueRegisterCommandAfterResponseReceived):
(WebKit::U2fAuthenticator::continueSignCommandAfterResponseReceived):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (249948 => 249949)


--- trunk/Source/WebCore/ChangeLog	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebCore/ChangeLog	2019-09-17 08:17:17 UTC (rev 249949)
@@ -1,3 +1,17 @@
+2019-09-17  Jiewen Tan  <jiewen_...@apple.com>
+
+        [WebAuthn] Use WebPreferences instead of RuntimeEnabledFeatures in UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=198176
+        <rdar://problem/55285709>
+
+        Reviewed by Youenn Fablet.
+
+        No changes of behavior.
+
+        * Modules/webauthn/PublicKeyCredential.cpp:
+        (WebCore::PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable):
+        Resolves the promise with false immediately when the feature flag is false.
+
 2019-09-17  Rob Buis  <rb...@igalia.com>
 
         Access-Control-Expose-Headers parsed incorrectly

Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp (249948 => 249949)


--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -36,6 +36,7 @@
 #include "JSDOMPromiseDeferred.h"
 #include "Page.h"
 #include "PublicKeyCredentialData.h"
+#include "RuntimeEnabledFeatures.h"
 #include <wtf/text/Base64.h>
 
 namespace WebCore {
@@ -73,6 +74,10 @@
 
 void PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable(Document& document, DOMPromiseDeferred<IDLBoolean>&& promise)
 {
+    if (!RuntimeEnabledFeatures::sharedFeatures().webAuthenticationLocalAuthenticatorEnabled()) {
+        promise.resolve(false);
+        return;
+    }
     document.page()->authenticatorCoordinator().isUserVerifyingPlatformAuthenticatorAvailable(WTFMove(promise));
 }
 

Modified: trunk/Source/WebKit/ChangeLog (249948 => 249949)


--- trunk/Source/WebKit/ChangeLog	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/ChangeLog	2019-09-17 08:17:17 UTC (rev 249949)
@@ -1,3 +1,56 @@
+2019-09-17  Jiewen Tan  <jiewen_...@apple.com>
+
+        [WebAuthn] Use WebPreferences instead of RuntimeEnabledFeatures in UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=198176
+        <rdar://problem/55285709>
+
+        Reviewed by Youenn Fablet.
+
+        This patch does the following two things:
+        1) It merges WebAuthenticationRequestData::creationOptions and requestOptions into a variant, and therefore
+        merges code paths that involve WebAuthenticationRequestData.
+        2) It teaches WebAuthenticationRequestData to store a WebPreferences such that AuthenticatorManager could utilize
+        runtime feature flags to turn features on or off.
+
+        * UIProcess/WebAuthentication/Authenticator.cpp:
+        (WebKit::Authenticator::handleRequest):
+        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
+        (WebKit::AuthenticatorManager::handleRequest):
+        (WebKit::AuthenticatorManager::clearState):
+        (WebKit::AuthenticatorManager::authenticatorAdded):
+        (WebKit::AuthenticatorManager::startDiscovery):
+        (WebKit::AuthenticatorManager::makeCredential): Deleted.
+        (WebKit::AuthenticatorManager::getAssertion): Deleted.
+        * UIProcess/WebAuthentication/AuthenticatorManager.h:
+        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
+        (WebKit::LocalAuthenticator::makeCredential):
+        (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserConsented):
+        (WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested):
+        (WebKit::LocalAuthenticator::getAssertion):
+        (WebKit::LocalAuthenticator::continueGetAssertionAfterUserConsented):
+        * UIProcess/WebAuthentication/Cocoa/LocalService.mm:
+        (WebKit::LocalService::isAvailable):
+        Don't check RuntimeEnabledFeatures given it is for WebCore.
+        * UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
+        (): Deleted.
+        * UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:
+        (WebKit::WebAuthenticatorCoordinatorProxy::makeCredential):
+        (WebKit::WebAuthenticatorCoordinatorProxy::getAssertion):
+        (WebKit::WebAuthenticatorCoordinatorProxy::handleRequest):
+        * UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h:
+        * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
+        (WebKit::CtapAuthenticator::makeCredential):
+        (WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived const):
+        (WebKit::CtapAuthenticator::getAssertion):
+        * UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp:
+        (WebKit::U2fAuthenticator::makeCredential):
+        (WebKit::U2fAuthenticator::checkExcludeList):
+        (WebKit::U2fAuthenticator::issueRegisterCommand):
+        (WebKit::U2fAuthenticator::getAssertion):
+        (WebKit::U2fAuthenticator::issueSignCommand):
+        (WebKit::U2fAuthenticator::continueRegisterCommandAfterResponseReceived):
+        (WebKit::U2fAuthenticator::continueSignCommandAfterResponseReceived):
+
 2019-09-17  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Keeps running obsolete WebProcess-es for too long

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.cpp (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -36,13 +36,13 @@
 {
     m_pendingRequestData = data;
     // Enforce asynchronous execution of makeCredential/getAssertion.
-    RunLoop::main().dispatch([weakThis = makeWeakPtr(*this)] {
+    RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), this] {
         if (!weakThis)
             return;
-        if (weakThis->m_pendingRequestData.isCreationRequest)
-            weakThis->makeCredential();
+        if (WTF::holds_alternative<WebCore::PublicKeyCredentialCreationOptions>(m_pendingRequestData.options))
+            makeCredential();
         else
-            weakThis->getAssertion();
+            getAssertion();
     });
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -28,6 +28,7 @@
 
 #if ENABLE(WEB_AUTHN)
 
+#include "WebPreferencesKeys.h"
 #include <WebCore/AuthenticatorTransport.h>
 #include <WebCore/PublicKeyCredentialCreationOptions.h>
 #include <wtf/MonotonicTime.h>
@@ -119,7 +120,7 @@
 {
 }
 
-void AuthenticatorManager::makeCredential(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions& options, Callback&& callback)
+void AuthenticatorManager::handleRequest(WebAuthenticationRequestData&& data, Callback&& callback)
 {
     using namespace AuthenticatorManagerInternal;
 
@@ -130,34 +131,19 @@
     clearState();
 
     // 1. Save request for async operations.
-    m_pendingRequestData = { hash, true, options, { } };
+    m_pendingRequestData = WTFMove(data);
     m_pendingCompletionHandler = WTFMove(callback);
-    initTimeOutTimer(options.timeout);
 
     // 2. Get available transports and start discovering authenticators on them.
-    startDiscovery(collectTransports(options.authenticatorSelection));
+    WTF::switchOn(m_pendingRequestData.options, [&](const PublicKeyCredentialCreationOptions& options) {
+        initTimeOutTimer(options.timeout);
+        startDiscovery(collectTransports(options.authenticatorSelection));
+    }, [&](const  PublicKeyCredentialRequestOptions& options) {
+        initTimeOutTimer(options.timeout);
+        startDiscovery(collectTransports(options.allowCredentials));
+    });
 }
 
-void AuthenticatorManager::getAssertion(const Vector<uint8_t>& hash, const PublicKeyCredentialRequestOptions& options, Callback&& callback)
-{
-    using namespace AuthenticatorManagerInternal;
-
-    if (m_pendingCompletionHandler) {
-        m_pendingCompletionHandler(ExceptionData { NotAllowedError, "This request has been cancelled by a new request."_s });
-        m_requestTimeOutTimer.stop();
-    }
-    clearState();
-
-    // 1. Save request for async operations.
-    m_pendingRequestData = { hash, false, { }, options };
-    m_pendingCompletionHandler = WTFMove(callback);
-    initTimeOutTimer(options.timeout);
-
-    // 2. Get available transports and start discovering authenticators on them.
-    ASSERT(m_services.isEmpty());
-    startDiscovery(collectTransports(options.allowCredentials));
-}
-
 void AuthenticatorManager::clearStateAsync()
 {
     RunLoop::main().dispatch([weakThis = makeWeakPtr(*this)] {
@@ -228,8 +214,10 @@
 {
     using namespace AuthenticatorManagerInternal;
 
-    ASSERT(m_services.isEmpty() && transports.size() <= maxTransportNumber);
+    ASSERT(m_services.isEmpty() && transports.size() <= maxTransportNumber && m_pendingRequestData.preferences);
     for (auto& transport : transports) {
+        if (transport == AuthenticatorTransport::Internal && !m_pendingRequestData.preferences->store().getBoolValueForKey(WebPreferencesKey::webAuthenticationLocalAuthenticatorEnabledKey()))
+            continue;
         auto service = createService(transport, *this);
         service->startDiscovery();
         m_services.append(WTFMove(service));

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h	2019-09-17 08:17:17 UTC (rev 249949)
@@ -54,8 +54,7 @@
     AuthenticatorManager();
     virtual ~AuthenticatorManager() = default;
 
-    void makeCredential(const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialCreationOptions&, Callback&&);
-    void getAssertion(const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialRequestOptions&, Callback&&);
+    void handleRequest(WebAuthenticationRequestData&&, Callback&&);
 
     virtual bool isMock() const { return false; }
 

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


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2019-09-17 08:17:17 UTC (rev 249949)
@@ -91,6 +91,7 @@
     using namespace LocalAuthenticatorInternal;
     ASSERT(m_state == State::Init);
     m_state = State::RequestReceived;
+    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
 
     // The following implements https://www.w3.org/TR/webauthn/#op-make-cred as of 5 December 2017.
     // Skip Step 4-5 as requireResidentKey and requireUserVerification are enforced.
@@ -98,7 +99,7 @@
     // Step 8 is implicitly captured by all UnknownError exception receiveResponds.
     // Step 2.
     bool canFullfillPubKeyCredParams = false;
-    for (auto& pubKeyCredParam : requestData().creationOptions.pubKeyCredParams) {
+    for (auto& pubKeyCredParam : creationOptions.pubKeyCredParams) {
         if (pubKeyCredParam.type == PublicKeyCredentialType::PublicKey && pubKeyCredParam.alg == COSE::ES256) {
             canFullfillPubKeyCredParams = true;
             break;
@@ -110,13 +111,13 @@
     }
 
     // Step 3.
-    HashSet<String> excludeCredentialIds = produceHashSet(requestData().creationOptions.excludeCredentials);
+    auto excludeCredentialIds = produceHashSet(creationOptions.excludeCredentials);
     if (!excludeCredentialIds.isEmpty()) {
         // Search Keychain for the RP ID.
         NSDictionary *query = @{
             (id)kSecClass: (id)kSecClassKey,
             (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
-            (id)kSecAttrLabel: requestData().creationOptions.rp.id,
+            (id)kSecAttrLabel: creationOptions.rp.id,
             (id)kSecReturnAttributes: @YES,
             (id)kSecMatchLimit: (id)kSecMatchLimitAll,
 #if HAVE(DATA_PROTECTION_KEYCHAIN)
@@ -154,7 +155,7 @@
         weakThis->continueMakeCredentialAfterUserConsented(consent);
     };
     m_connection->getUserConsent(
-        "allow " + requestData().creationOptions.rp.id + " to create a public key credential for " + requestData().creationOptions.user.name,
+        "allow " + creationOptions.rp.id + " to create a public key credential for " + creationOptions.user.name,
         WTFMove(callback));
 }
 
@@ -162,6 +163,7 @@
 {
     ASSERT(m_state == State::RequestReceived);
     m_state = State::UserConsented;
+    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
 
     if (consent == LocalConnection::UserConsent::No) {
         receiveRespond(ExceptionData { NotAllowedError, "Couldn't get user consent."_s });
@@ -173,8 +175,8 @@
     // Failures after this point could block users' accounts forever. Should we follow the spec?
     NSDictionary* deleteQuery = @{
         (id)kSecClass: (id)kSecClassKey,
-        (id)kSecAttrLabel: requestData().creationOptions.rp.id,
-        (id)kSecAttrApplicationTag: [NSData dataWithBytes:requestData().creationOptions.user.idVector.data() length:requestData().creationOptions.user.idVector.size()],
+        (id)kSecAttrLabel: creationOptions.rp.id,
+        (id)kSecAttrApplicationTag: [NSData dataWithBytes:creationOptions.user.idVector.data() length:creationOptions.user.idVector.size()],
 #if HAVE(DATA_PROTECTION_KEYCHAIN)
         (id)kSecUseDataProtectionKeychain: @YES
 #else
@@ -195,7 +197,7 @@
             return;
         weakThis->continueMakeCredentialAfterAttested(privateKey, certificates, error);
     };
-    m_connection->getAttestation(requestData().creationOptions.rp.id, requestData().creationOptions.user.name, requestData().hash, WTFMove(callback));
+    m_connection->getAttestation(creationOptions.rp.id, creationOptions.user.name, requestData().hash, WTFMove(callback));
 }
 
 void LocalAuthenticator::continueMakeCredentialAfterAttested(SecKeyRef privateKey, NSArray *certificates, NSError *error)
@@ -204,6 +206,7 @@
 
     ASSERT(m_state == State::UserConsented);
     m_state = State::Attested;
+    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
 
     if (error) {
         LOG_ERROR("Couldn't attest: %@", error);
@@ -229,7 +232,7 @@
     Vector<uint8_t> credentialId;
     {
         // -rk-ucrt is added by DeviceIdentity.Framework.
-        String label = makeString(requestData().creationOptions.user.name, "@", requestData().creationOptions.rp.id, "-rk-ucrt");
+        String label = makeString(creationOptions.user.name, "@", creationOptions.rp.id, "-rk-ucrt");
         NSDictionary *credentialIdQuery = @{
             (id)kSecClass: (id)kSecClassKey,
             (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
@@ -264,8 +267,8 @@
 #endif
         };
         NSDictionary *updateParams = @{
-            (id)kSecAttrLabel: requestData().creationOptions.rp.id,
-            (id)kSecAttrApplicationTag: [NSData dataWithBytes:requestData().creationOptions.user.idVector.data() length:requestData().creationOptions.user.idVector.size()],
+            (id)kSecAttrLabel: creationOptions.rp.id,
+            (id)kSecAttrApplicationTag: [NSData dataWithBytes:creationOptions.user.idVector.data() length:creationOptions.user.idVector.size()],
         };
         status = SecItemUpdate((__bridge CFDictionaryRef)updateQuery, (__bridge CFDictionaryRef)updateParams);
         if (status) {
@@ -308,7 +311,7 @@
     auto attestedCredentialData = buildAttestedCredentialData(Vector<uint8_t>(aaguidLength, 0), credentialId, cosePublicKey);
 
     // Step 12.
-    auto authData = buildAuthData(requestData().creationOptions.rp.id, makeCredentialFlags, counter, attestedCredentialData);
+    auto authData = buildAuthData(creationOptions.rp.id, makeCredentialFlags, counter, attestedCredentialData);
 
     // Step 13. Apple Attestation Cont'
     // Assemble the attestation object:
@@ -335,7 +338,7 @@
             cborArray.append(cbor::CBORValue(toVector((NSData *)adoptCF(SecCertificateCopyData((__bridge SecCertificateRef)certificates[i])).get())));
         attestationStatementMap[cbor::CBORValue("x5c")] = cbor::CBORValue(WTFMove(cborArray));
     }
-    auto attestationObject = buildAttestationObject(WTFMove(authData), "Apple", WTFMove(attestationStatementMap), requestData().creationOptions.attestation);
+    auto attestationObject = buildAttestationObject(WTFMove(authData), "Apple", WTFMove(attestationStatementMap), creationOptions.attestation);
 
     receiveRespond(PublicKeyCredentialData { ArrayBuffer::create(credentialId.data(), credentialId.size()), true, nullptr, ArrayBuffer::create(attestationObject.data(), attestationObject.size()), nullptr, nullptr, nullptr, WTF::nullopt });
 }
@@ -345,6 +348,7 @@
     using namespace LocalAuthenticatorInternal;
     ASSERT(m_state == State::Init);
     m_state = State::RequestReceived;
+    auto& requestOptions = WTF::get<PublicKeyCredentialRequestOptions>(requestData().options);
 
     // The following implements https://www.w3.org/TR/webauthn/#op-get-assertion as of 5 December 2017.
     // Skip Step 2 as requireUserVerification is enforced.
@@ -351,8 +355,8 @@
     // Skip Step 8 as extensions are not supported yet.
     // Step 12 is implicitly captured by all UnknownError exception callbacks.
     // Step 3-5. Unlike the spec, if an allow list is provided and there is no intersection between existing ones and the allow list, we always return NotAllowedError.
-    HashSet<String> allowCredentialIds = produceHashSet(requestData().requestOptions.allowCredentials);
-    if (!requestData().requestOptions.allowCredentials.isEmpty() && allowCredentialIds.isEmpty()) {
+    auto allowCredentialIds = produceHashSet(requestOptions.allowCredentials);
+    if (!requestOptions.allowCredentials.isEmpty() && allowCredentialIds.isEmpty()) {
         receiveRespond(ExceptionData { NotAllowedError, "No matched credentials are found in the platform attached authenticator."_s });
         return;
     }
@@ -361,7 +365,7 @@
     NSDictionary *query = @{
         (id)kSecClass: (id)kSecClassKey,
         (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
-        (id)kSecAttrLabel: requestData().requestOptions.rpId,
+        (id)kSecAttrLabel: requestOptions.rpId,
         (id)kSecReturnAttributes: @YES,
         (id)kSecMatchLimit: (id)kSecMatchLimitAll,
 #if HAVE(DATA_PROTECTION_KEYCHAIN)
@@ -380,7 +384,7 @@
     auto retainAttributesArray = adoptCF(attributesArrayRef);
 
     NSArray *intersectedCredentialsAttributes = nil;
-    if (requestData().requestOptions.allowCredentials.isEmpty())
+    if (requestOptions.allowCredentials.isEmpty())
         intersectedCredentialsAttributes = (NSArray *)attributesArrayRef;
     else {
         NSMutableArray *result = [NSMutableArray arrayWithCapacity:allowCredentialIds.size()];
@@ -416,7 +420,7 @@
     NSData *idData = selectedCredentialAttributes[(id)kSecAttrApplicationTag];
     StringView idStringView { static_cast<const UChar*>([idData bytes]), static_cast<unsigned>([idData length]) };
     m_connection->getUserConsent(
-        makeString("log into ", requestData().requestOptions.rpId, " with ", idStringView),
+        makeString("log into ", requestOptions.rpId, " with ", idStringView),
         (__bridge SecAccessControlRef)selectedCredentialAttributes[(id)kSecAttrAccessControl],
         WTFMove(callback));
 }
@@ -436,7 +440,7 @@
     // FIXME(183533): Due to the stated Keychain limitations, we can't save the counter value.
     // Therefore, it is always zero.
     uint32_t counter = 0;
-    auto authData = buildAuthData(requestData().requestOptions.rpId, getAssertionFlags, counter, { });
+    auto authData = buildAuthData(WTF::get<PublicKeyCredentialRequestOptions>(requestData().options).rpId, getAssertionFlags, counter, { });
 
     // Step 11.
     Vector<uint8_t> signature;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm	2019-09-17 08:17:17 UTC (rev 249949)
@@ -44,10 +44,6 @@
 // FIXME(rdar://problem/51048542)
 bool LocalService::isAvailable()
 {
-    // FIXME(198176)
-    if (!WebCore::RuntimeEnabledFeatures::sharedFeatures().webAuthenticationLocalAuthenticatorEnabled())
-        return false;
-
     auto context = adoptNS([allocLAContextInstance() init]);
     NSError *error = nil;
     if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h	2019-09-17 08:17:17 UTC (rev 249949)
@@ -27,8 +27,10 @@
 
 #if ENABLE(WEB_AUTHN)
 
+#include "WebPreferences.h"
 #include <WebCore/PublicKeyCredentialCreationOptions.h>
 #include <WebCore/PublicKeyCredentialRequestOptions.h>
+#include <wtf/Variant.h>
 #include <wtf/Vector.h>
 
 namespace WebKit {
@@ -35,10 +37,8 @@
 
 struct WebAuthenticationRequestData {
     Vector<uint8_t> hash;
-    // FIXME: Maybe we could make an ABC of Options and then use safe casting here.
-    bool isCreationRequest { true };
-    WebCore::PublicKeyCredentialCreationOptions creationOptions;
-    WebCore::PublicKeyCredentialRequestOptions requestOptions;
+    Variant<WebCore::PublicKeyCredentialCreationOptions, WebCore::PublicKeyCredentialRequestOptions> options;
+    RefPtr<WebPreferences> preferences;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -55,22 +55,16 @@
 
 void WebAuthenticatorCoordinatorProxy::makeCredential(uint64_t messageId, const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialCreationOptions& options)
 {
-    auto callback = [messageId, weakThis = makeWeakPtr(*this)] (Variant<WebCore::PublicKeyCredentialData, WebCore::ExceptionData>&& result) {
-        ASSERT(RunLoop::isMain());
-        if (!weakThis)
-            return;
-
-        WTF::switchOn(result, [&](const WebCore::PublicKeyCredentialData& data) {
-            weakThis->requestReply(messageId, data, { });
-        }, [&](const  WebCore::ExceptionData& exception) {
-            weakThis->requestReply(messageId, { }, exception);
-        });
-    };
-    m_webPageProxy.websiteDataStore().authenticatorManager().makeCredential(hash, options, WTFMove(callback));
+    handleRequest(messageId, { hash, options, m_webPageProxy.preferences().copy() });
 }
 
 void WebAuthenticatorCoordinatorProxy::getAssertion(uint64_t messageId, const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialRequestOptions& options)
 {
+    handleRequest(messageId, { hash, options, m_webPageProxy.preferences().copy() });
+}
+
+void WebAuthenticatorCoordinatorProxy::handleRequest(uint64_t messageId, WebAuthenticationRequestData&& data)
+{
     auto callback = [messageId, weakThis = makeWeakPtr(*this)] (Variant<WebCore::PublicKeyCredentialData, WebCore::ExceptionData>&& result) {
         ASSERT(RunLoop::isMain());
         if (!weakThis)
@@ -82,7 +76,7 @@
             weakThis->requestReply(messageId, { }, exception);
         });
     };
-    m_webPageProxy.websiteDataStore().authenticatorManager().getAssertion(hash, options, WTFMove(callback));
+    m_webPageProxy.websiteDataStore().authenticatorManager().handleRequest(WTFMove(data), WTFMove(callback));
 }
 
 void WebAuthenticatorCoordinatorProxy::isUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h	2019-09-17 08:17:17 UTC (rev 249949)
@@ -43,6 +43,8 @@
 
 class WebPageProxy;
 
+struct WebAuthenticationRequestData;
+
 class WebAuthenticatorCoordinatorProxy : private IPC::MessageReceiver, public CanMakeWeakPtr<WebAuthenticatorCoordinatorProxy> {
     WTF_MAKE_FAST_ALLOCATED;
     WTF_MAKE_NONCOPYABLE(WebAuthenticatorCoordinatorProxy);
@@ -62,6 +64,8 @@
     // Senders.
     void requestReply(uint64_t messageId, const WebCore::PublicKeyCredentialData&, const WebCore::ExceptionData&);
 
+    void handleRequest(uint64_t messageId, WebAuthenticationRequestData&&);
+
     WebPageProxy& m_webPageProxy;
 };
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -52,7 +52,7 @@
 void CtapAuthenticator::makeCredential()
 {
     ASSERT(!m_isDowngraded);
-    auto cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, requestData().creationOptions, m_info.options().userVerificationAvailability());
+    auto cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, WTF::get<PublicKeyCredentialCreationOptions>(requestData().options), m_info.options().userVerificationAvailability());
     m_driver->transact(WTFMove(cborCmd), [weakThis = makeWeakPtr(*this)](Vector<uint8_t>&& data) {
         ASSERT(RunLoop::isMain());
         if (!weakThis)
@@ -63,7 +63,7 @@
 
 void CtapAuthenticator::continueMakeCredentialAfterResponseReceived(Vector<uint8_t>&& data) const
 {
-    auto response = readCTAPMakeCredentialResponse(data, requestData().creationOptions.attestation);
+    auto response = readCTAPMakeCredentialResponse(data, WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation);
     if (!response) {
         auto error = getResponseCode(data);
         if (error == CtapDeviceResponseCode::kCtap2ErrCredentialExcluded)
@@ -78,7 +78,7 @@
 void CtapAuthenticator::getAssertion()
 {
     ASSERT(!m_isDowngraded);
-    auto cborCmd = encodeGetAssertionRequestAsCBOR(requestData().hash, requestData().requestOptions, m_info.options().userVerificationAvailability());
+    auto cborCmd = encodeGetAssertionRequestAsCBOR(requestData().hash, WTF::get<PublicKeyCredentialRequestOptions>(requestData().options), m_info.options().userVerificationAvailability());
     m_driver->transact(WTFMove(cborCmd), [weakThis = makeWeakPtr(*this)](Vector<uint8_t>&& data) {
         ASSERT(RunLoop::isMain());
         if (!weakThis)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp (249948 => 249949)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp	2019-09-17 08:14:29 UTC (rev 249948)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp	2019-09-17 08:17:17 UTC (rev 249949)
@@ -55,11 +55,12 @@
 
 void U2fAuthenticator::makeCredential()
 {
-    if (!isConvertibleToU2fRegisterCommand(requestData().creationOptions)) {
+    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
+    if (!isConvertibleToU2fRegisterCommand(creationOptions)) {
         receiveRespond(ExceptionData { NotSupportedError, "Cannot convert the request to U2F command."_s });
         return;
     }
-    if (!requestData().creationOptions.excludeCredentials.isEmpty()) {
+    if (!creationOptions.excludeCredentials.isEmpty()) {
         ASSERT(!m_nextListIndex);
         checkExcludeList(m_nextListIndex++);
         return;
@@ -69,11 +70,12 @@
 
 void U2fAuthenticator::checkExcludeList(size_t index)
 {
-    if (index >= requestData().creationOptions.excludeCredentials.size()) {
+    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
+    if (index >= creationOptions.excludeCredentials.size()) {
         issueRegisterCommand();
         return;
     }
-    auto u2fCmd = convertToU2fCheckOnlySignCommand(requestData().hash, requestData().creationOptions, requestData().creationOptions.excludeCredentials[index]);
+    auto u2fCmd = convertToU2fCheckOnlySignCommand(requestData().hash, creationOptions, creationOptions.excludeCredentials[index]);
     ASSERT(u2fCmd);
     issueNewCommand(WTFMove(*u2fCmd), CommandType::CheckOnlyCommand);
 }
@@ -80,7 +82,7 @@
 
 void U2fAuthenticator::issueRegisterCommand()
 {
-    auto u2fCmd = convertToU2fRegisterCommand(requestData().hash, requestData().creationOptions);
+    auto u2fCmd = convertToU2fRegisterCommand(requestData().hash, WTF::get<PublicKeyCredentialCreationOptions>(requestData().options));
     ASSERT(u2fCmd);
     issueNewCommand(WTFMove(*u2fCmd), CommandType::RegisterCommand);
 }
@@ -87,7 +89,7 @@
 
 void U2fAuthenticator::getAssertion()
 {
-    if (!isConvertibleToU2fSignCommand(requestData().requestOptions)) {
+    if (!isConvertibleToU2fSignCommand(WTF::get<PublicKeyCredentialRequestOptions>(requestData().options))) {
         receiveRespond(ExceptionData { NotSupportedError, "Cannot convert the request to U2F command."_s });
         return;
     }
@@ -97,11 +99,12 @@
 
 void U2fAuthenticator::issueSignCommand(size_t index)
 {
-    if (index >= requestData().requestOptions.allowCredentials.size()) {
+    auto& requestOptions = WTF::get<PublicKeyCredentialRequestOptions>(requestData().options);
+    if (index >= requestOptions.allowCredentials.size()) {
         receiveRespond(ExceptionData { NotAllowedError, "No credentials from the allowCredentials list is found in the authenticator."_s });
         return;
     }
-    auto u2fCmd = convertToU2fSignCommand(requestData().hash, requestData().requestOptions, requestData().requestOptions.allowCredentials[index].idVector, m_isAppId);
+    auto u2fCmd = convertToU2fSignCommand(requestData().hash, requestOptions, requestOptions.allowCredentials[index].idVector, m_isAppId);
     ASSERT(u2fCmd);
     issueNewCommand(WTFMove(*u2fCmd), CommandType::SignCommand);
 }
@@ -152,7 +155,7 @@
 {
     switch (apduResponse.status()) {
     case ApduResponse::Status::SW_NO_ERROR: {
-        auto response = readU2fRegisterResponse(requestData().creationOptions.rp.id, apduResponse.data(), requestData().creationOptions.attestation);
+        auto response = readU2fRegisterResponse(WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).rp.id, apduResponse.data(), WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation);
         if (!response) {
             receiveRespond(ExceptionData { UnknownError, "Couldn't parse the U2F register response."_s });
             return;
@@ -198,14 +201,15 @@
 
 void U2fAuthenticator::continueSignCommandAfterResponseReceived(ApduResponse&& apduResponse)
 {
+    auto& requestOptions = WTF::get<PublicKeyCredentialRequestOptions>(requestData().options);
     switch (apduResponse.status()) {
     case ApduResponse::Status::SW_NO_ERROR: {
         Optional<PublicKeyCredentialData> response;
         if (m_isAppId) {
-            ASSERT(requestData().requestOptions.extensions && !requestData().requestOptions.extensions->appid.isNull());
-            response = readU2fSignResponse(requestData().requestOptions.extensions->appid, requestData().requestOptions.allowCredentials[m_nextListIndex - 1].idVector, apduResponse.data());
+            ASSERT(requestOptions.extensions && !requestOptions.extensions->appid.isNull());
+            response = readU2fSignResponse(requestOptions.extensions->appid, requestOptions.allowCredentials[m_nextListIndex - 1].idVector, apduResponse.data());
         } else
-            response = readU2fSignResponse(requestData().requestOptions.rpId, requestData().requestOptions.allowCredentials[m_nextListIndex - 1].idVector, apduResponse.data());
+            response = readU2fSignResponse(requestOptions.rpId, requestOptions.allowCredentials[m_nextListIndex - 1].idVector, apduResponse.data());
         if (!response) {
             receiveRespond(ExceptionData { UnknownError, "Couldn't parse the U2F sign response."_s });
             return;
@@ -221,7 +225,7 @@
         m_retryTimer.startOneShot(Seconds::fromMilliseconds(retryTimeOutValueMs));
         return;
     case ApduResponse::Status::SW_WRONG_DATA:
-        if (requestData().requestOptions.extensions && !requestData().requestOptions.extensions->appid.isNull()) {
+        if (requestOptions.extensions && !requestOptions.extensions->appid.isNull()) {
             if (!m_isAppId) {
                 m_isAppId = true;
                 issueSignCommand(m_nextListIndex - 1);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to