Changeset 264543 in webkit


Ignore:
Timestamp:
Jul 17, 2020 3:58:51 PM (4 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthn] Cache the PIN to improve NFC user experience
https://bugs.webkit.org/show_bug.cgi?id=213900
<rdar://problem/60073622>

Reviewed by Brent Fulgham.

Source/WebKit:

Cache the PIN to improve NFC user experience. Users might not hold the NFC key against the NFC scanner all the time
while entering the PIN. Therefore, we cache the PIN from the previous connection and immediately return the cached PIN to
the current connection such that users don't need to enter the PIN again.

The only downside for this optimization is that a wrong PIN could be used if the user switch to another authenticator for
the new connection. Given there is no UUID to identify a particular authenticator, there is nothing we can do to resolve the
issue. The probability of the issue, however, should be rare.

Covered by new API tests.

  • UIProcess/WebAuthentication/AuthenticatorManager.cpp:

(WebKit::AuthenticatorManager::authenticatorStatusUpdated):
(WebKit::AuthenticatorManager::requestPin):
Where the above logic is implemented.

  • UIProcess/WebAuthentication/Cocoa/NfcConnection.mm:

(WebKit::NfcConnection::transact const):
Adds a comment.

  • UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
  • UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:

(WebKit::WebAuthenticatorCoordinatorProxy::makeCredential):
(WebKit::WebAuthenticatorCoordinatorProxy::getAssertion):
Adds a field for the cached PIN.

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:

(TestWebKitAPI::TEST):

  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-nfc-pin-disconnect.html: Added.
Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r264529 r264543  
     12020-07-17  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cache the PIN to improve NFC user experience
     4        https://bugs.webkit.org/show_bug.cgi?id=213900
     5        <rdar://problem/60073622>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Cache the PIN to improve NFC user experience. Users might not hold the NFC key against the NFC scanner all the time
     10        while entering the PIN. Therefore, we cache the PIN from the previous connection and immediately return the cached PIN to
     11        the current connection such that users don't need to enter the PIN again.
     12
     13        The only downside for this optimization is that a wrong PIN could be used if the user switch to another authenticator for
     14        the new connection. Given there is no UUID to identify a particular authenticator, there is nothing we can do to resolve the
     15        issue. The probability of the issue, however, should be rare.
     16
     17        Covered by new API tests.
     18
     19        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
     20        (WebKit::AuthenticatorManager::authenticatorStatusUpdated):
     21        (WebKit::AuthenticatorManager::requestPin):
     22        Where the above logic is implemented.
     23
     24        * UIProcess/WebAuthentication/Cocoa/NfcConnection.mm:
     25        (WebKit::NfcConnection::transact const):
     26        Adds a comment.
     27
     28        * UIProcess/WebAuthentication/WebAuthenticationRequestData.h:
     29        * UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:
     30        (WebKit::WebAuthenticatorCoordinatorProxy::makeCredential):
     31        (WebKit::WebAuthenticatorCoordinatorProxy::getAssertion):
     32        Adds a field for the cached PIN.
     33
    1342020-07-17  Per Arne Vollan  <pvollan@apple.com>
    235
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp

    r263786 r264543  
    265265void AuthenticatorManager::authenticatorStatusUpdated(WebAuthenticationStatus status)
    266266{
     267    // Immediately invalidate the cache if the PIN is incorrect. A status update often means
     268    // an error. We don't really care what kind of error it really is.
     269    m_pendingRequestData.cachedPin = String();
     270
    267271    dispatchPanelClientCall([status] (const API::WebAuthenticationPanel& panel) {
    268272        panel.client().updatePanel(status);
     
    272276void AuthenticatorManager::requestPin(uint64_t retries, CompletionHandler<void(const WTF::String&)>&& completionHandler)
    273277{
    274     dispatchPanelClientCall([retries, completionHandler = WTFMove(completionHandler)] (const API::WebAuthenticationPanel& panel) mutable {
    275         panel.client().requestPin(retries, WTFMove(completionHandler));
     278    // Cache the PIN to improve NFC user experience so that a momentary movement of the NFC key away from the scanner doesn't
     279    // force the PIN entry to be re-entered.
     280    // We don't distinguish USB and NFC here becuase there is no harms to have this optimization for USB even though it is useless.
     281    if (!m_pendingRequestData.cachedPin.isNull()) {
     282        completionHandler(m_pendingRequestData.cachedPin);
     283        m_pendingRequestData.cachedPin = String();
     284        return;
     285    }
     286
     287    auto callback = [weakThis = makeWeakPtr(*this), this, completionHandler = WTFMove(completionHandler)] (const WTF::String& pin) mutable {
     288        if (!weakThis)
     289            return;
     290
     291        m_pendingRequestData.cachedPin = pin;
     292        completionHandler(pin);
     293    };
     294
     295    dispatchPanelClientCall([retries, callback = WTFMove(callback)] (const API::WebAuthenticationPanel& panel) mutable {
     296        panel.client().requestPin(retries, WTFMove(callback));
    276297    });
    277298}
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcConnection.mm

    r252297 r264543  
    9292{
    9393    Vector<uint8_t> response;
     94    // The method will return an empty NSData if the tag is disconnected.
    9495    auto *responseData = [m_session transceive:adoptNS([[NSData alloc] initWithBytes:data.data() length:data.size()]).get()];
    9596    response.append(reinterpret_cast<const uint8_t*>(responseData.bytes), responseData.length);
  • trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationRequestData.h

    r260983 r264543  
    5252    WebKit::FrameInfoData frameInfo;
    5353    bool processingUserGesture;
     54    String cachedPin; // Only used to improve NFC Client PIN experience.
    5455};
    5556
  • trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp

    r260983 r264543  
    5858void WebAuthenticatorCoordinatorProxy::makeCredential(FrameIdentifier frameId, FrameInfoData&& frameInfo, Vector<uint8_t>&& hash, PublicKeyCredentialCreationOptions&& options, bool processingUserGesture, RequestCompletionHandler&& handler)
    5959{
    60     handleRequest({ WTFMove(hash), WTFMove(options), makeWeakPtr(m_webPageProxy), WebAuthenticationPanelResult::Unavailable, nullptr, GlobalFrameIdentifier { m_webPageProxy.webPageID(), frameId }, WTFMove(frameInfo), processingUserGesture }, WTFMove(handler));
     60    handleRequest({ WTFMove(hash), WTFMove(options), makeWeakPtr(m_webPageProxy), WebAuthenticationPanelResult::Unavailable, nullptr, GlobalFrameIdentifier { m_webPageProxy.webPageID(), frameId }, WTFMove(frameInfo), processingUserGesture, String() }, WTFMove(handler));
    6161}
    6262
    6363void WebAuthenticatorCoordinatorProxy::getAssertion(FrameIdentifier frameId, FrameInfoData&& frameInfo, Vector<uint8_t>&& hash, PublicKeyCredentialRequestOptions&& options, bool processingUserGesture, RequestCompletionHandler&& handler)
    6464{
    65     handleRequest({ WTFMove(hash), WTFMove(options), makeWeakPtr(m_webPageProxy), WebAuthenticationPanelResult::Unavailable, nullptr, GlobalFrameIdentifier { m_webPageProxy.webPageID(), frameId }, WTFMove(frameInfo), processingUserGesture }, WTFMove(handler));
     65    handleRequest({ WTFMove(hash), WTFMove(options), makeWeakPtr(m_webPageProxy), WebAuthenticationPanelResult::Unavailable, nullptr, GlobalFrameIdentifier { m_webPageProxy.webPageID(), frameId }, WTFMove(frameInfo), processingUserGesture, String() }, WTFMove(handler));
    6666}
    6767
  • trunk/Tools/ChangeLog

    r264531 r264543  
     12020-07-17  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cache the PIN to improve NFC user experience
     4        https://bugs.webkit.org/show_bug.cgi?id=213900
     5        <rdar://problem/60073622>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     10        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
     11        (TestWebKitAPI::TEST):
     12        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-nfc-pin-disconnect.html: Added.
     13
    1142020-07-17  Wenson Hsieh  <wenson_hsieh@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r264315 r264543  
    374374                574F55D2204D47F0002948C6 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 574F55D0204D471C002948C6 /* Security.framework */; };
    375375                5751B28A249D5BC500664C2A /* web-authentication-make-credential-hid-pin-get-pin-token-fake-pin-invalid-error-retry.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5751B289249D5B9900664C2A /* web-authentication-make-credential-hid-pin-get-pin-token-fake-pin-invalid-error-retry.html */; };
     376                57537EE824BEA05F0048DBA5 /* web-authentication-get-assertion-nfc-pin-disconnect.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57537EE724BEA0190048DBA5 /* web-authentication-get-assertion-nfc-pin-disconnect.html */; };
    376377                5758597F23A2527A00C74572 /* CtapPinTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5758597E23A2527A00C74572 /* CtapPinTest.cpp */; };
    377378                5758598423C3C3A400C74572 /* web-authentication-make-credential-hid-pin-get-retries-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5758598323C3C36200C74572 /* web-authentication-make-credential-hid-pin-get-retries-error.html */; };
     
    16031604                                572CEF71240F874700C412A2 /* web-authentication-get-assertion-la.html in Copy Resources */,
    16041605                                579833922368FA37008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html in Copy Resources */,
     1606                                57537EE824BEA05F0048DBA5 /* web-authentication-get-assertion-nfc-pin-disconnect.html in Copy Resources */,
    16051607                                57663DEA234EA66D00E85E09 /* web-authentication-get-assertion-nfc.html in Copy Resources */,
    16061608                                577454D22359BB01008E1ED7 /* web-authentication-get-assertion-u2f-no-credentials.html in Copy Resources */,
     
    20772079                574F55D0204D471C002948C6 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
    20782080                5751B289249D5B9900664C2A /* web-authentication-make-credential-hid-pin-get-pin-token-fake-pin-invalid-error-retry.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid-pin-get-pin-token-fake-pin-invalid-error-retry.html"; sourceTree = "<group>"; };
     2081                57537EE724BEA0190048DBA5 /* web-authentication-get-assertion-nfc-pin-disconnect.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-nfc-pin-disconnect.html"; sourceTree = "<group>"; };
    20792082                5758597D23A2527A00C74572 /* CtapPinTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CtapPinTest.h; sourceTree = "<group>"; };
    20802083                5758597E23A2527A00C74572 /* CtapPinTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CtapPinTest.cpp; sourceTree = "<group>"; };
     
    37853788                                572CEF70240F86AE00C412A2 /* web-authentication-get-assertion-la.html */,
    37863789                                5798337B235EB65C008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html */,
     3790                                57537EE724BEA0190048DBA5 /* web-authentication-get-assertion-nfc-pin-disconnect.html */,
    37873791                                57663DE9234EA60B00E85E09 /* web-authentication-get-assertion-nfc.html */,
    37883792                                577454D12359BAD5008E1ED7 /* web-authentication-get-assertion-u2f-no-credentials.html */,
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm

    r263296 r264543  
    11591159}
    11601160
     1161#if HAVE(NEAR_FIELD)
     1162TEST(WebAuthenticationPanel, NfcPinCachedDisconnect)
     1163{
     1164    reset();
     1165    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-get-assertion-nfc-pin-disconnect" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     1166
     1167    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     1168    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
     1169
     1170    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
     1171    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
     1172    [webView setUIDelegate:delegate.get()];
     1173
     1174    webAuthenticationPanelPin = "1234";
     1175    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     1176    [webView waitForMessage:@"Succeeded!"];
     1177}
     1178#endif // HAVE(NEAR_FIELD)
     1179
    11611180TEST(WebAuthenticationPanel, MultipleAccountsNullDelegate)
    11621181{
Note: See TracChangeset for help on using the changeset viewer.