Title: [271221] trunk/Source/WebKit
Revision
271221
Author
[email protected]
Date
2021-01-06 17:50:34 -0800 (Wed, 06 Jan 2021)

Log Message

[WebAuthn] Adopt new UI for the Client PIN and dismiss flow
https://bugs.webkit.org/show_bug.cgi?id=219712
<rdar://problem/72154935>

Reviewed by Brent Fulgham.

Covered by manual tests.

This patch does the following few things:
1. It tweaks the WebAuthn process as a UI view service to be able to run NearField in the background.
2. It adopts new SPI for security keys' client pin support.
3. It adopts new SPI to dismiss the UI when necessary.

* Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
(NS_ERROR_ENUM):
Adds new SPI.

* Scripts/process-entitlements.sh:
Tweaks WebAuthn process for NFC.

* UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.h:
* UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.mm:
Paperwork.

* UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h:
* UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm:
(WebKit::AuthenticatorPresenterCoordinator::~AuthenticatorPresenterCoordinator):
(WebKit::AuthenticatorPresenterCoordinator::updatePresenter):
(WebKit::AuthenticatorPresenterCoordinator::requestPin):
(WebKit::AuthenticatorPresenterCoordinator::dimissPresenter):
(WebKit::AuthenticatorPresenterCoordinator::setPin):
Adopts new SPIs.

* UIProcess/WebAuthentication/Cocoa/NfcService.mm:
(WebKit::NfcService::platformStartDiscovery):
Tweaks NFC.

* UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm:
(-[WKASCAuthorizationPresenterDelegate authorizationPresenter:credentialRequestedForLoginChoice:authenticatedContext:completionHandler:]):
(-[WKASCAuthorizationPresenterDelegate authorizationPresenter:validateUserEnteredPIN:completionHandler:]):
Adopts new SPIs.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (271220 => 271221)


--- trunk/Source/WebKit/ChangeLog	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/ChangeLog	2021-01-07 01:50:34 UTC (rev 271221)
@@ -1,3 +1,47 @@
+2021-01-06  Jiewen Tan  <[email protected]>
+
+        [WebAuthn] Adopt new UI for the Client PIN and dismiss flow
+        https://bugs.webkit.org/show_bug.cgi?id=219712
+        <rdar://problem/72154935>
+
+        Reviewed by Brent Fulgham.
+
+        Covered by manual tests.
+
+        This patch does the following few things:
+        1. It tweaks the WebAuthn process as a UI view service to be able to run NearField in the background.
+        2. It adopts new SPI for security keys' client pin support.
+        3. It adopts new SPI to dismiss the UI when necessary.
+
+        * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
+        (NS_ERROR_ENUM):
+        Adds new SPI.
+
+        * Scripts/process-entitlements.sh:
+        Tweaks WebAuthn process for NFC.
+
+        * UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.h:
+        * UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.mm:
+        Paperwork.
+
+        * UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h:
+        * UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm:
+        (WebKit::AuthenticatorPresenterCoordinator::~AuthenticatorPresenterCoordinator):
+        (WebKit::AuthenticatorPresenterCoordinator::updatePresenter):
+        (WebKit::AuthenticatorPresenterCoordinator::requestPin):
+        (WebKit::AuthenticatorPresenterCoordinator::dimissPresenter):
+        (WebKit::AuthenticatorPresenterCoordinator::setPin):
+        Adopts new SPIs.
+
+        * UIProcess/WebAuthentication/Cocoa/NfcService.mm:
+        (WebKit::NfcService::platformStartDiscovery):
+        Tweaks NFC.
+
+        * UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm:
+        (-[WKASCAuthorizationPresenterDelegate authorizationPresenter:credentialRequestedForLoginChoice:authenticatedContext:completionHandler:]):
+        (-[WKASCAuthorizationPresenterDelegate authorizationPresenter:validateUserEnteredPIN:completionHandler:]):
+        Adopts new SPIs.
+
 2021-01-06  Jer Noble  <[email protected]>
 
         [Cocoa] Revert audioTimePitchAlgorithm to "TimeDomain" from "Spectral"

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


--- trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2021-01-07 01:50:34 UTC (rev 271221)
@@ -71,6 +71,8 @@
 
 - (void)presentAuthorizationWithContext:(ASCAuthorizationPresentationContext *)context completionHandler:(void (^)(id<ASCCredentialProtocol> _Nullable, NSError * _Nullable))completionHandler;
 - (void)updateInterfaceWithLoginChoices:(NSArray<id <ASCLoginChoiceProtocol>> *)loginChoices;
+- (void)presentPINEntryInterface;
+- (void)dismissWithError:(nullable NSError *)error;
 
 @property (nonatomic, weak) id <ASCAuthorizationPresenterDelegate> delegate;
 
@@ -158,6 +160,23 @@
 
 @end
 
+extern NSErrorDomain const ASCAuthorizationErrorDomain;
+
+typedef NS_ERROR_ENUM(ASCAuthorizationErrorDomain, ASCAuthorizationError) {
+    ASCAuthorizationErrorUnknown,
+    ASCAuthorizationErrorFailed,
+    ASCAuthorizationErrorUserCanceled,
+    ASCAuthorizationErrorPINRequired,
+};
+
+extern NSString * const ASCPINValidationResultKey;
+
+typedef NS_ENUM(NSInteger, ASCPINValidationResult) {
+    ASCPINValidationResultPINBlocked,
+    ASCPINValidationResultPINAuthBlocked,
+    ASCPINValidationResultPINInvalid,
+};
+
 NS_ASSUME_NONNULL_END
 
 //#endif // USE(APPLE_INTERNAL_SDK)

Modified: trunk/Source/WebKit/Platform/spi/Cocoa/NearFieldSPI.h (271220 => 271221)


--- trunk/Source/WebKit/Platform/spi/Cocoa/NearFieldSPI.h	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/NearFieldSPI.h	2021-01-07 01:50:34 UTC (rev 271221)
@@ -104,7 +104,7 @@
 @end
 
 @interface NFHardwareManager : NSObject
-+ (instancetype)sharedHardwareManager;
++ (instancetype)sharedHardwareManagerWithNoUI;
 - (NSObject<NFSession> *)startReaderSession:(void(^)(NFReaderSession *session, NSError *error))theStartCallback;
 - (BOOL)areFeaturesSupported:(NFFeature)featureMask outError:(NSError**)outError;
 @end

Modified: trunk/Source/WebKit/Scripts/process-entitlements.sh (271220 => 271221)


--- trunk/Source/WebKit/Scripts/process-entitlements.sh	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/Scripts/process-entitlements.sh	2021-01-07 01:50:34 UTC (rev 271221)
@@ -243,6 +243,9 @@
 
     plistbuddy Add :com.apple.nfcd.hwmanager bool YES
     plistbuddy Add :com.apple.nfcd.session.reader.internal bool YES
+    # FIXME(rdar://problem/72646664): Find a better way to invoke NearField in the background.
+    plistbuddy Add :com.apple.internal.nfc.allow.backgrounded.session bool YES
+    plistbuddy Add :com.apple.UIKit.vends-view-services bool YES
 
     plistbuddy Add :keychain-access-groups array
     plistbuddy Add :keychain-access-groups:0 string com.apple.webkit.webauthn

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.h (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.h	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.h	2021-01-07 01:50:34 UTC (rev 271221)
@@ -38,4 +38,10 @@
 SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASCSecurityKeyPublicKeyCredentialLoginChoice);
 SOFT_LINK_CLASS_FOR_HEADER(WebKit, ASCAppleIDCredential);
 
+SOFT_LINK_CONSTANT_FOR_HEADER(WebKit, AuthenticationServicesCore, ASCAuthorizationErrorDomain, NSErrorDomain);
+#define ASCAuthorizationErrorDomain WebKit::get_AuthenticationServicesCore_ASCAuthorizationErrorDomain()
+
+SOFT_LINK_CONSTANT_FOR_HEADER(WebKit, AuthenticationServicesCore, ASCPINValidationResultKey, NSString*);
+#define ASCPINValidationResultKey WebKit::get_AuthenticationServicesCore_ASCPINValidationResultKey()
+
 #endif // HAVE(ASC_AUTH_UI)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.mm (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.mm	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticationServicesCoreSoftLink.mm	2021-01-07 01:50:34 UTC (rev 271221)
@@ -38,4 +38,7 @@
 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServicesCore, ASCSecurityKeyPublicKeyCredentialLoginChoice);
 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, AuthenticationServicesCore, ASCAppleIDCredential);
 
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebKit, AuthenticationServicesCore, ASCAuthorizationErrorDomain, NSErrorDomain);
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebKit, AuthenticationServicesCore, ASCPINValidationResultKey, NSString*);
+
 #endif // HAVE(ASC_AUTH_UI)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h	2021-01-07 01:50:34 UTC (rev 271221)
@@ -35,10 +35,12 @@
 #include <wtf/RetainPtr.h>
 #include <wtf/WeakPtr.h>
 
+OBJC_CLASS ASCAppleIDCredential;
 OBJC_CLASS ASCAuthorizationPresentationContext;
 OBJC_CLASS ASCAuthorizationPresenter;
 OBJC_CLASS ASCLoginChoiceProtocol;
 OBJC_CLASS LAContext;
+OBJC_CLASS NSError;
 OBJC_CLASS WKASCAuthorizationPresenterDelegate;
 
 namespace WebKit {
@@ -50,7 +52,7 @@
     WTF_MAKE_NONCOPYABLE(AuthenticatorPresenterCoordinator);
 public:
     using TransportSet = HashSet<WebCore::AuthenticatorTransport, WTF::IntHash<WebCore::AuthenticatorTransport>, WTF::StrongEnumHashTraits<WebCore::AuthenticatorTransport>>;
-    using CredentialRequestHandler = Function<void()>;
+    using CredentialRequestHandler = Function<void(ASCAppleIDCredential *, NSError *)>;
 
     AuthenticatorPresenterCoordinator(const AuthenticatorManager&, const String& rpId, const TransportSet&, WebCore::ClientDataType);
     ~AuthenticatorPresenterCoordinator();
@@ -63,8 +65,8 @@
 
     void setCredentialRequestHandler(CredentialRequestHandler&& handler) { m_credentialRequestHandler = WTFMove(handler); }
     void setLAContext(LAContext *);
-
     void didSelectAssertionResponse(ASCLoginChoiceProtocol *, LAContext *);
+    void setPin(const String&);
 
 private:
     WeakPtr<AuthenticatorManager> m_manager;
@@ -79,6 +81,8 @@
 
     CompletionHandler<void(WebCore::AuthenticatorAssertionResponse*)> m_responseHandler;
     HashMap<ASCLoginChoiceProtocol *, RefPtr<WebCore::AuthenticatorAssertionResponse>> m_credentials;
+
+    CompletionHandler<void(const String&)> m_pinHandler;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm	2021-01-07 01:50:34 UTC (rev 271221)
@@ -86,16 +86,42 @@
         m_laContextHandler(nullptr);
     if (m_responseHandler)
         m_responseHandler(nullptr);
+    if (m_pinHandler)
+        m_pinHandler(String());
 }
 
-void AuthenticatorPresenterCoordinator::updatePresenter(WebAuthenticationStatus)
+void AuthenticatorPresenterCoordinator::updatePresenter(WebAuthenticationStatus status)
 {
-    // FIXME(219713): Adopt new UI for the update flow.
+#if HAVE(ASC_AUTH_UI)
+    switch (status) {
+    case WebAuthenticationStatus::PinBlocked: {
+        auto error = adoptNS([[NSError alloc] initWithDomain:ASCAuthorizationErrorDomain code:ASCAuthorizationErrorPINRequired userInfo:@{ ASCPINValidationResultKey: @(ASCPINValidationResultPINBlocked) }]);
+        m_credentialRequestHandler(nil, error.get());
+        break;
+    }
+    case WebAuthenticationStatus::PinAuthBlocked: {
+        auto error = adoptNS([[NSError alloc] initWithDomain:ASCAuthorizationErrorDomain code:ASCAuthorizationErrorPINRequired userInfo:@{ ASCPINValidationResultKey: @(ASCPINValidationResultPINAuthBlocked) }]);
+        m_credentialRequestHandler(nil, error.get());
+        break;
+    }
+    case WebAuthenticationStatus::PinInvalid: {
+        auto error = adoptNS([[NSError alloc] initWithDomain:ASCAuthorizationErrorDomain code:ASCAuthorizationErrorPINRequired userInfo:@{ ASCPINValidationResultKey: @(ASCPINValidationResultPINInvalid) }]);
+        m_credentialRequestHandler(nil, error.get());
+        break;
+    }
+    default:
+        // FIXME(219713): Adopt new UI for the update flow.
+        break;
+    }
+#endif // HAVE(ASC_AUTH_UI)
 }
 
-void AuthenticatorPresenterCoordinator::requestPin(uint64_t, CompletionHandler<void(const String&)>&&)
+void AuthenticatorPresenterCoordinator::requestPin(uint64_t, CompletionHandler<void(const String&)>&& completionHandler)
 {
-    // FIXME(219712): Adopt new UI for the Client PIN flow.
+#if HAVE(ASC_AUTH_UI)
+    m_pinHandler = WTFMove(completionHandler);
+    [m_presenter presentPINEntryInterface];
+#endif // HAVE(ASC_AUTH_UI)
 }
 
 void AuthenticatorPresenterCoordinator::selectAssertionResponse(Vector<Ref<AuthenticatorAssertionResponse>>&& responses, WebAuthenticationSource source, CompletionHandler<void(AuthenticatorAssertionResponse*)>&& completionHandler)
@@ -156,11 +182,16 @@
 
 void AuthenticatorPresenterCoordinator::dimissPresenter(WebAuthenticationResult result)
 {
+#if HAVE(ASC_AUTH_UI)
     if (result == WebAuthenticationResult::Succeeded && m_credentialRequestHandler) {
-        m_credentialRequestHandler();
+        // FIXME(219767): Replace the ASCAppleIDCredential with the upcoming WebAuthn credentials one.
+        // This is just a place holder to tell the UI that the ceremony succeeds.
+        m_credentialRequestHandler(adoptNS([WebKit::allocASCAppleIDCredentialInstance() initWithUser:@"" identityToken:adoptNS([[NSData alloc] init]).get()]).get(), nil);
         return;
     }
-    // FIXME(219716): Adopt new UI for the dismiss flow.
+
+    [m_presenter dismissWithError:nil];
+#endif // HAVE(ASC_AUTH_UI)
 }
 
 void AuthenticatorPresenterCoordinator::setLAContext(LAContext *context)
@@ -185,6 +216,11 @@
     m_responseHandler(response.get());
 }
 
+void AuthenticatorPresenterCoordinator::setPin(const String& pin)
+{
+    m_pinHandler(pin);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.mm (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.mm	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.mm	2021-01-07 01:50:34 UTC (rev 271221)
@@ -52,7 +52,7 @@
 bool NfcService::isAvailable()
 {
 #if HAVE(NEAR_FIELD)
-    return [[getNFHardwareManagerClass() sharedHardwareManager] areFeaturesSupported:NFFeatureReaderMode outError:nil];
+    return [[getNFHardwareManagerClass() sharedHardwareManagerWithNoUI] areFeaturesSupported:NFFeatureReaderMode outError:nil];
 #else
     return false;
 #endif
@@ -118,7 +118,7 @@
             m_connection = NfcConnection::create(WTFMove(session), *this);
         });
     });
-    [[getNFHardwareManagerClass() sharedHardwareManager] startReaderSession:callback.get()];
+    [[getNFHardwareManagerClass() sharedHardwareManagerWithNoUI] startReaderSession:callback.get()];
 #endif // HAVE(NEAR_FIELD)
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm (271220 => 271221)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm	2021-01-07 00:49:55 UTC (rev 271220)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm	2021-01-07 01:50:34 UTC (rev 271221)
@@ -47,10 +47,8 @@
 
 - (void)authorizationPresenter:(ASCAuthorizationPresenter *)presenter credentialRequestedForLoginChoice:(id <ASCLoginChoiceProtocol>)loginChoice authenticatedContext:(nullable LAContext *)context completionHandler:(void (^)(id <ASCCredentialProtocol> _Nullable credential, NSError * _Nullable error))completionHandler
 {
-    auto requestHandler = [completionHandler = makeBlockPtr(completionHandler)] {
-        // FIXME(219767): Replace the ASCAppleIDCredential with the upcoming WebAuthn credentials one.
-        // This is just a place holder to tell the UI that the ceremony succeeds.
-        completionHandler(adoptNS([WebKit::allocASCAppleIDCredentialInstance() initWithUser:@"" identityToken:adoptNS([[NSData alloc] init]).get()]).get(), nil);
+    auto requestHandler = [completionHandler = makeBlockPtr(completionHandler)] (ASCAppleIDCredential *credential, NSError *error) {
+        completionHandler(credential, error);
     };
     [self dispatchCoordinatorCallback:[requestHandler = WTFMove(requestHandler)] (WebKit::AuthenticatorPresenterCoordinator& coordinator) mutable {
         coordinator.setCredentialRequestHandler(WTFMove(requestHandler));
@@ -87,7 +85,17 @@
 
 - (void)authorizationPresenter:(ASCAuthorizationPresenter *)presenter validateUserEnteredPIN:(NSString *)pin completionHandler:(void (^)(id <ASCCredentialProtocol> credential, NSError *error))completionHandler
 {
-    // FIXME(219712): Adopt new UI for the Client PIN flow.
+    auto requestHandler = [completionHandler = makeBlockPtr(completionHandler)] (ASCAppleIDCredential *credential, NSError *error) {
+        completionHandler(credential, error);
+    };
+    [self dispatchCoordinatorCallback:[requestHandler = WTFMove(requestHandler)] (WebKit::AuthenticatorPresenterCoordinator& coordinator) mutable {
+        coordinator.setCredentialRequestHandler(WTFMove(requestHandler));
+    }];
+
+    String pinString = pin;
+    [self dispatchCoordinatorCallback:[pinString = WTFMove(pinString)] (WebKit::AuthenticatorPresenterCoordinator& coordinator) mutable {
+        coordinator.setPin(pinString);
+    }];
 }
 
 - (void)dispatchCoordinatorCallback:(Function<void(WebKit::AuthenticatorPresenterCoordinator&)>&&)callback
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to