Title: [276180] trunk
Revision
276180
Author
[email protected]
Date
2021-04-16 16:52:30 -0700 (Fri, 16 Apr 2021)

Log Message

Allow using the platform authenticator on non-Touch ID Macs according to Internal requirements
https://bugs.webkit.org/show_bug.cgi?id=224639
<rdar://74698346>

Reviewed by Daniel Bates.

Source/WebCore:

Covered by new tests within existing test files.

* testing/MockWebAuthenticationConfiguration.h:
* testing/MockWebAuthenticationConfiguration.idl:
Mock testing support.

Source/WebKit:

* UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
(WebKit::LocalAuthenticator::continueMakeCredentialAfterDecidePolicy):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
(WebKit::LocalAuthenticator::continueGetAssertionAfterResponseSelected):
(WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
Don't set the UserVerification bit if UserVerification is not done.

* UIProcess/WebAuthentication/Cocoa/LocalConnection.h:
* UIProcess/WebAuthentication/Cocoa/LocalConnection.mm:
(WebKit::LocalConnection::verifyUser):
Only check UserPresence on non-Touch ID Macs.

* UIProcess/WebAuthentication/Cocoa/LocalService.mm:
(WebKit::LocalService::isAvailable):
Make the platform authenticator available according to Internal requirements.

* UIProcess/WebAuthentication/Mock/MockLocalConnection.h:
* UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
(WebKit::MockLocalConnection::verifyUser):
Mock testing support.

* UIProcess/WebAuthentication/WebAuthenticationRequestData.cpp:
(WebKit::getUserVerificationRequirement):
* UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
Add a helper for extracting the UserVerification input.

LayoutTests:

* http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt:
* http/wpt/webauthn/public-key-credential-create-success-local.https.html:
* http/wpt/webauthn/public-key-credential-get-success-local.https-expected.txt:
* http/wpt/webauthn/public-key-credential-get-success-local.https.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (276179 => 276180)


--- trunk/LayoutTests/ChangeLog	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/LayoutTests/ChangeLog	2021-04-16 23:52:30 UTC (rev 276180)
@@ -1,3 +1,16 @@
+2021-04-16  Jiewen Tan  <[email protected]>
+
+        Allow using the platform authenticator on non-Touch ID Macs according to Internal requirements
+        https://bugs.webkit.org/show_bug.cgi?id=224639
+        <rdar://74698346>
+
+        Reviewed by Daniel Bates.
+
+        * http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-create-success-local.https.html:
+        * http/wpt/webauthn/public-key-credential-get-success-local.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-get-success-local.https.html:
+
 2021-04-16  Robert Jenner  <[email protected]>
 
         [ macOS Wk2 ] media/media-fragments/TC0051.html is flakey crashing

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt (276179 => 276180)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt	2021-04-16 23:52:30 UTC (rev 276180)
@@ -6,6 +6,7 @@
 CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
 CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
 CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
+CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
 
 PASS PublicKeyCredential's [[create]] with minimum options in a mock local authenticator.
 PASS PublicKeyCredential's [[create]] with authenticatorSelection { 'platform' } in a mock local authenticator.
@@ -15,4 +16,5 @@
 PASS PublicKeyCredential's [[create]] with direct attestation in a mock local authenticator.
 PASS PublicKeyCredential's [[create]] with duplicate credential in a mock local authenticator.
 PASS PublicKeyCredential's [[create]] with duplicate credential in a mock local authenticator. 2
+PASS PublicKeyCredential's [[create]] with user presence in a mock local authenticator.
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html (276179 => 276180)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html	2021-04-16 23:52:30 UTC (rev 276180)
@@ -5,7 +5,7 @@
 <script src=""
 <script src=""
 <script>
-    function checkResult(credential, credentialID, isNoneAttestation = true)
+    function checkResult(credential, credentialID, isNoneAttestation = true, isUV = true)
     {
         // Check keychain
         if (window.testRunner) {
@@ -29,7 +29,10 @@
         // Check authData
         const authData = decodeAuthData(attestationObject.authData);
         assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");
-        assert_equals(authData.flags, 69);
+        if (isUV)
+            assert_equals(authData.flags, 69);
+        else
+            assert_equals(authData.flags, 65);
         assert_equals(authData.counter, 0);
         if (isNoneAttestation)
             assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000");
@@ -344,4 +347,37 @@
             assert_false(testRunner.keyExistsInKeychain(testRpId, base64encode(anotherCredentialID)));
         });
     }, "PublicKeyCredential's [[create]] with duplicate credential in a mock local authenticator. 2");
+
+    promise_test(async t => {
+        const privateKeyBase64 = await generatePrivateKeyBase64();
+        const credentialID = await calculateCredentialID(privateKeyBase64);
+        const userhandleBase64 = generateUserhandleBase64();
+        if (window.internals)
+            internals.setMockWebAuthenticationConfiguration({
+                local: {
+                    userVerification: "presence",
+                    acceptAttestation: false,
+                    privateKeyBase64: privateKeyBase64,
+                }
+            });
+
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "localhost",
+                },
+                user: {
+                    name: userhandleBase64,
+                    id: Base64URL.parse(userhandleBase64),
+                    displayName: "Appleseed",
+                },
+                challenge: Base64URL.parse("MTIzNDU2"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+            }
+        };
+
+        return navigator.credentials.create(options).then(credential => {
+            checkResult(credential, credentialID, true, false);
+        });
+    }, "PublicKeyCredential's [[create]] with user presence in a mock local authenticator.");
 </script>

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https-expected.txt (276179 => 276180)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https-expected.txt	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https-expected.txt	2021-04-16 23:52:30 UTC (rev 276180)
@@ -1,6 +1,8 @@
 CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
 CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
+CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
 
 PASS PublicKeyCredential's [[get]] with minimum options in a mock local authenticator.
 PASS PublicKeyCredential's [[get]] with matched allow credentials in a mock local authenticator.
+PASS PublicKeyCredential's [[get]] with user presence in a mock local authenticator.
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https.html (276179 => 276180)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https.html	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https.html	2021-04-16 23:52:30 UTC (rev 276180)
@@ -4,7 +4,7 @@
 <script src=""
 <script src=""
 <script>
-    function checkResult(credential, credentialID, privateKeyBase64)
+    function checkResult(credential, credentialID, privateKeyBase64, isUV = true)
     {
         if (window.testRunner)
             testRunner.cleanUpKeychain(testRpId, base64encode(credentialID));
@@ -20,7 +20,10 @@
         // Check authData
         const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData));
         assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");
-        assert_equals(authData.flags, 5);
+        if (isUV)
+            assert_equals(authData.flags, 5);
+        else
+            assert_equals(authData.flags, 1);
         assert_equals(authData.counter, 0);
 
         // Check signature
@@ -80,4 +83,25 @@
             return checkResult(credential, credentialID, privateKeyBase64);
         });
     }, "PublicKeyCredential's [[get]] with matched allow credentials in a mock local authenticator.");
+
+    promise_test(async t => {
+        const privateKeyBase64 = await generatePrivateKeyBase64();
+        const credentialID = await calculateCredentialID(privateKeyBase64);
+        const credentialIDBase64 = base64encode(credentialID);
+        // Default mock configuration. Tests need to override if they need different configuration.
+        if (window.internals)
+            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "presence", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
+
+        const options = {
+            publicKey: {
+                challenge: Base64URL.parse("MTIzNDU2")
+            }
+        };
+
+        if (window.testRunner)
+            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
+        return navigator.credentials.get(options).then(credential => {
+            return checkResult(credential, credentialID, privateKeyBase64, false);
+        });
+    }, "PublicKeyCredential's [[get]] with user presence in a mock local authenticator.");
 </script>

Modified: trunk/Source/WebCore/ChangeLog (276179 => 276180)


--- trunk/Source/WebCore/ChangeLog	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebCore/ChangeLog	2021-04-16 23:52:30 UTC (rev 276180)
@@ -1,3 +1,17 @@
+2021-04-16  Jiewen Tan  <[email protected]>
+
+        Allow using the platform authenticator on non-Touch ID Macs according to Internal requirements
+        https://bugs.webkit.org/show_bug.cgi?id=224639
+        <rdar://74698346>
+
+        Reviewed by Daniel Bates.
+
+        Covered by new tests within existing test files.
+
+        * testing/MockWebAuthenticationConfiguration.h:
+        * testing/MockWebAuthenticationConfiguration.idl:
+        Mock testing support.
+
 2021-04-16  Peng Liu  <[email protected]>
 
         [GPUP] WebContent process should not create AVOutputContext instances when media in GPU Process is enabled

Modified: trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.h (276179 => 276180)


--- trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.h	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.h	2021-04-16 23:52:30 UTC (rev 276180)
@@ -64,7 +64,8 @@
     enum class UserVerification : uint8_t {
         No,
         Yes,
-        Cancel
+        Cancel,
+        Presence
     };
 
     struct LocalConfiguration {
@@ -308,7 +309,8 @@
         WebCore::MockWebAuthenticationConfiguration::UserVerification,
         WebCore::MockWebAuthenticationConfiguration::UserVerification::No,
         WebCore::MockWebAuthenticationConfiguration::UserVerification::Yes,
-        WebCore::MockWebAuthenticationConfiguration::UserVerification::Cancel
+        WebCore::MockWebAuthenticationConfiguration::UserVerification::Cancel,
+        WebCore::MockWebAuthenticationConfiguration::UserVerification::Presence
     >;
 };
 

Modified: trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.idl (276179 => 276180)


--- trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.idl	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.idl	2021-04-16 23:52:30 UTC (rev 276180)
@@ -64,7 +64,8 @@
 ] enum UserVerification {
     "no",
     "yes",
-    "cancel"
+    "cancel",
+    "presence"
 };
 
 [

Modified: trunk/Source/WebKit/ChangeLog (276179 => 276180)


--- trunk/Source/WebKit/ChangeLog	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/ChangeLog	2021-04-16 23:52:30 UTC (rev 276180)
@@ -1,3 +1,37 @@
+2021-04-16  Jiewen Tan  <[email protected]>
+
+        Allow using the platform authenticator on non-Touch ID Macs according to Internal requirements
+        https://bugs.webkit.org/show_bug.cgi?id=224639
+        <rdar://74698346>
+
+        Reviewed by Daniel Bates.
+
+        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
+        (WebKit::LocalAuthenticator::continueMakeCredentialAfterDecidePolicy):
+        (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
+        (WebKit::LocalAuthenticator::continueGetAssertionAfterResponseSelected):
+        (WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
+        Don't set the UserVerification bit if UserVerification is not done.
+
+        * UIProcess/WebAuthentication/Cocoa/LocalConnection.h:
+        * UIProcess/WebAuthentication/Cocoa/LocalConnection.mm:
+        (WebKit::LocalConnection::verifyUser):
+        Only check UserPresence on non-Touch ID Macs.
+
+        * UIProcess/WebAuthentication/Cocoa/LocalService.mm:
+        (WebKit::LocalService::isAvailable):
+        Make the platform authenticator available according to Internal requirements.
+
+        * UIProcess/WebAuthentication/Mock/MockLocalConnection.h:
+        * UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
+        (WebKit::MockLocalConnection::verifyUser):
+        Mock testing support.
+
+        * UIProcess/WebAuthentication/WebAuthenticationRequestData.cpp:
+        (WebKit::getUserVerificationRequirement):
+        * UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
+        Add a helper for extracting the UserVerification input.
+
 2021-04-16  Peng Liu  <[email protected]>
 
         [GPUP] WebContent process should not create AVOutputContext instances when media in GPU Process is enabled

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


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2021-04-16 23:52:30 UTC (rev 276180)
@@ -64,7 +64,9 @@
 
 // See https://www.w3.org/TR/webauthn/#flags.
 const uint8_t makeCredentialFlags = 0b01000101; // UP, UV and AT are set.
+const uint8_t otherMakeCredentialFlags = 0b01000001; // UP and AT are set.
 const uint8_t getAssertionFlags = 0b00000101; // UP and UV are set.
+const uint8_t otherGetAssertionFlags = 0b00000001; // UP is set.
 // Credential ID is currently SHA-1 of the corresponding public key.
 const uint16_t credentialIdLength = 20;
 const uint64_t counter = 0;
@@ -306,7 +308,7 @@
 
         weakThis->continueMakeCredentialAfterUserVerification(accessControl.get(), verification, context);
     };
-    m_connection->verifyUser(creationOptions.rp.id, getClientDataType(requestData().options), accessControlRef, WTFMove(callback));
+    m_connection->verifyUser(creationOptions.rp.id, getClientDataType(requestData().options), accessControlRef, getUserVerificationRequirement(requestData().options), WTFMove(callback));
 }
 
 void LocalAuthenticator::continueMakeCredentialAfterReceivingLAContext(LAContext *context)
@@ -425,12 +427,13 @@
         cosePublicKey = encodeES256PublicKeyAsCBOR(WTFMove(x), WTFMove(y));
     }
 
+    auto flags = verification == LocalConnection::UserVerification::Presence ? otherMakeCredentialFlags : makeCredentialFlags;
     // Step 12.
     // Skip Apple Attestation for none attestation.
     if (creationOptions.attestation == AttestationConveyancePreference::None) {
         deleteDuplicateCredential();
 
-        auto authData = buildAuthData(creationOptions.rp.id, makeCredentialFlags, counter, buildAttestedCredentialData(Vector<uint8_t>(aaguidLength, 0), credentialId, cosePublicKey));
+        auto authData = buildAuthData(creationOptions.rp.id, flags, counter, buildAttestedCredentialData(Vector<uint8_t>(aaguidLength, 0), credentialId, cosePublicKey));
         auto attestationObject = buildAttestationObject(WTFMove(authData), "", { }, AttestationConveyancePreference::None);
         receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject));
         return;
@@ -437,7 +440,7 @@
     }
 
     // Step 13. Apple Attestation
-    auto authData = buildAuthData(creationOptions.rp.id, makeCredentialFlags, counter, buildAttestedCredentialData(aaguidVector(), credentialId, cosePublicKey));
+    auto authData = buildAuthData(creationOptions.rp.id, flags, counter, buildAttestedCredentialData(aaguidVector(), credentialId, cosePublicKey));
     auto nsAuthData = toNSData(authData);
     auto callback = [credentialId = WTFMove(credentialId), authData = WTFMove(authData), weakThis = makeWeakPtr(*this)] (NSArray * _Nullable certificates, NSError * _Nullable error) mutable {
         ASSERT(RunLoop::isMain());
@@ -579,7 +582,7 @@
 
         weakThis->continueGetAssertionAfterUserVerification(WTFMove(response), verification, context);
     };
-    m_connection->verifyUser(requestOptions.rpId, getClientDataType(requestData().options), accessControlRef, WTFMove(callback));
+    m_connection->verifyUser(requestOptions.rpId, getClientDataType(requestData().options), accessControlRef, getUserVerificationRequirement(requestData().options), WTFMove(callback));
 }
 
 void LocalAuthenticator::continueGetAssertionAfterUserVerification(Ref<WebCore::AuthenticatorAssertionResponse>&& response, LocalConnection::UserVerification verification, LAContext *context)
@@ -593,7 +596,7 @@
 
     // Step 10.
     auto requestOptions = WTF::get<PublicKeyCredentialRequestOptions>(requestData().options);
-    auto authData = buildAuthData(requestOptions.rpId, getAssertionFlags, counter, { });
+    auto authData = buildAuthData(requestOptions.rpId, verification == LocalConnection::UserVerification::Presence ? otherGetAssertionFlags : getAssertionFlags, counter, { });
 
     // Step 11.
     RetainPtr<CFDataRef> signature;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.h (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.h	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.h	2021-04-16 23:52:30 UTC (rev 276180)
@@ -38,6 +38,7 @@
 namespace WebCore {
 class AuthenticatorAssertionResponse;
 enum class ClientDataType : bool;
+enum class UserVerificationRequirement;
 }
 
 namespace WebKit {
@@ -54,7 +55,8 @@
     enum class UserVerification : uint8_t {
         No,
         Yes,
-        Cancel
+        Cancel,
+        Presence
     };
 
     using AttestationCallback = CompletionHandler<void(NSArray *, NSError *)>;
@@ -64,7 +66,7 @@
     virtual ~LocalConnection();
 
     // Overrided by MockLocalConnection.
-    virtual void verifyUser(const String& rpId, WebCore::ClientDataType, SecAccessControlRef, UserVerificationCallback&&);
+    virtual void verifyUser(const String& rpId, WebCore::ClientDataType, SecAccessControlRef, WebCore::UserVerificationRequirement, UserVerificationCallback&&);
     virtual void verifyUser(SecAccessControlRef, LAContext *, CompletionHandler<void(UserVerification)>&&);
     virtual RetainPtr<SecKeyRef> createCredentialPrivateKey(LAContext *, SecAccessControlRef, const String& secAttrLabel, NSData *secAttrApplicationTag) const;
     virtual void getAttestation(SecKeyRef, NSData *authData, NSData *hash, AttestationCallback&&) const;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm	2021-04-16 23:52:30 UTC (rev 276180)
@@ -29,6 +29,7 @@
 #if ENABLE(WEB_AUTHN)
 
 #import <WebCore/LocalizedStrings.h>
+#import <WebCore/UserVerificationRequirement.h>
 #import <WebCore/WebAuthenticationConstants.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/RunLoop.h>
@@ -60,7 +61,7 @@
     [m_context invalidate];
 }
 
-void LocalConnection::verifyUser(const String& rpId, ClientDataType type, SecAccessControlRef accessControl, UserVerificationCallback&& completionHandler)
+void LocalConnection::verifyUser(const String& rpId, ClientDataType type, SecAccessControlRef accessControl, UserVerificationRequirement uv, UserVerificationCallback&& completionHandler)
 {
     String title = genericTouchIDPromptTitle();
 #if PLATFORM(MAC)
@@ -84,7 +85,7 @@
         [options setObject:@NO forKey:@(LAOptionFallbackVisible)];
     }
 
-    auto reply = makeBlockPtr([context = m_context, completionHandler = WTFMove(completionHandler)] (NSDictionary *, NSError *error) mutable {
+    auto reply = makeBlockPtr([context = m_context, completionHandler = WTFMove(completionHandler)] (NSDictionary *information, NSError *error) mutable {
         UserVerification verification = UserVerification::Yes;
         if (error) {
             LOG_ERROR("Couldn't authenticate with biometrics: %@", error);
@@ -92,6 +93,8 @@
             if (error.code == LAErrorUserCancel)
                 verification = UserVerification::Cancel;
         }
+        if (information[@"UserPresence"])
+            verification = UserVerification::Presence;
 
         // This block can be executed in another thread.
         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), verification, context = WTFMove(context)] () mutable {
@@ -101,9 +104,14 @@
 
 #if USE(APPLE_INTERNAL_SDK)
     // Depending on certain internal requirements, accessControl might not require user verifications.
-    // Hence, here introduces a quirk to force the compatible mode to always require user verifications.
+    // Hence, here introduces a quirk to force the compatible mode to require user verifications if necessary.
     if (shouldUseAlternateAttributes()) {
-        [m_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication options:options.get() reply:reply.get()];
+        if (uv == UserVerificationRequirement::Required || [m_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
+            [m_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication options:options.get() reply:reply.get()];
+            return;
+        }
+
+        reply(@{ @"UserPresence": @YES }, nullptr);
         return;
     }
 #endif

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


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm	2021-04-16 23:52:30 UTC (rev 276180)
@@ -34,6 +34,12 @@
 #import "AppAttestInternalSoftLink.h"
 #import "LocalAuthenticationSoftLink.h"
 
+#if USE(APPLE_INTERNAL_SDK)
+#import <WebKitAdditions/LocalServiceAdditions.h>
+#else
+#define LOCAL_SERVICE_ADDITIONS
+#endif
+
 namespace WebKit {
 
 LocalService::LocalService(Observer& observer)
@@ -43,6 +49,8 @@
 
 bool LocalService::isAvailable()
 {
+LOCAL_SERVICE_ADDITIONS
+
     auto context = adoptNS([allocLAContextInstance() init]);
     NSError *error = nil;
     auto result = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h	2021-04-16 23:52:30 UTC (rev 276180)
@@ -37,7 +37,7 @@
     explicit MockLocalConnection(const WebCore::MockWebAuthenticationConfiguration&);
 
 private:
-    void verifyUser(const String&, WebCore::ClientDataType, SecAccessControlRef, UserVerificationCallback&&) final;
+    void verifyUser(const String&, WebCore::ClientDataType, SecAccessControlRef, WebCore::UserVerificationRequirement,  UserVerificationCallback&&) final;
     void verifyUser(SecAccessControlRef, LAContext *, CompletionHandler<void(UserVerification)>&&) final;
     RetainPtr<SecKeyRef> createCredentialPrivateKey(LAContext *, SecAccessControlRef, const String& secAttrLabel, NSData *secAttrApplicationTag) const final;
     void getAttestation(SecKeyRef, NSData *authData, NSData *hash, AttestationCallback&&) const final;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm	2021-04-16 23:52:30 UTC (rev 276180)
@@ -46,7 +46,7 @@
 {
 }
 
-void MockLocalConnection::verifyUser(const String&, ClientDataType, SecAccessControlRef, UserVerificationCallback&& callback)
+void MockLocalConnection::verifyUser(const String&, ClientDataType, SecAccessControlRef, WebCore::UserVerificationRequirement, UserVerificationCallback&& callback)
 {
     // Mock async operations.
     RunLoop::main().dispatch([configuration = m_configuration, callback = WTFMove(callback)]() mutable {
@@ -61,6 +61,10 @@
             break;
         case MockWebAuthenticationConfiguration::UserVerification::Cancel:
             userVerification = UserVerification::Cancel;
+            break;
+        case MockWebAuthenticationConfiguration::UserVerification::Presence:
+            userVerification = UserVerification::Presence;
+            break;
         }
 
         callback(userVerification, adoptNS([allocLAContextInstance() init]).get());
@@ -82,6 +86,10 @@
             break;
         case MockWebAuthenticationConfiguration::UserVerification::Cancel:
             userVerification = UserVerification::Cancel;
+            break;
+        case MockWebAuthenticationConfiguration::UserVerification::Presence:
+            userVerification = UserVerification::Presence;
+            break;
         }
 
         callback(userVerification);

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.cpp (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.cpp	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.cpp	2021-04-16 23:52:30 UTC (rev 276180)
@@ -28,6 +28,8 @@
 
 #if ENABLE(WEB_AUTHN)
 
+#import <WebCore/UserVerificationRequirement.h>
+
 namespace WebKit {
 using namespace WebCore;
 
@@ -38,6 +40,17 @@
     return ClientDataType::Get;
 }
 
+UserVerificationRequirement getUserVerificationRequirement(const Variant<PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions>& options)
+{
+    if (WTF::holds_alternative<PublicKeyCredentialCreationOptions>(options)) {
+        if (auto authenticatorSelection = WTF::get<PublicKeyCredentialCreationOptions>(options).authenticatorSelection)
+            return authenticatorSelection->userVerification;
+        return UserVerificationRequirement::Preferred;
+    }
+
+    return WTF::get<PublicKeyCredentialRequestOptions>(options).userVerification;
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h (276179 => 276180)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h	2021-04-16 23:32:49 UTC (rev 276179)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h	2021-04-16 23:52:30 UTC (rev 276180)
@@ -59,6 +59,7 @@
 };
 
 WebCore::ClientDataType getClientDataType(const Variant<WebCore::PublicKeyCredentialCreationOptions, WebCore::PublicKeyCredentialRequestOptions>&);
+WebCore::UserVerificationRequirement getUserVerificationRequirement(const Variant<WebCore::PublicKeyCredentialCreationOptions, WebCore::PublicKeyCredentialRequestOptions>&);
 
 } // namespace WebKit
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to