Changeset 238166 in webkit


Ignore:
Timestamp:
Nov 13, 2018 10:54:32 PM (5 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthN] Support CTAP HID authenticators on macOS
https://bugs.webkit.org/show_bug.cgi?id=188623
<rdar://problem/43353777>

Reviewed by Brent Fulgham and Chris Dumez.

Source/WebCore:

This patch removes AuthenticatorCoordinatorClient::~AuthenticatorCoordinatorClient to ignore
any incompleted CompletionHandlers as calling them in destructors could cause unexpected cyclic
dependency. Also, it adds a hack to temporarily deal with nullable userhandle.

Tests: http/wpt/webauthn/ctap-hid-failure.https.html

http/wpt/webauthn/ctap-hid-success.https.html
http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https.html
http/wpt/webauthn/public-key-credential-create-failure-hid.https.html
http/wpt/webauthn/public-key-credential-create-success-hid.https.html
http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https.html
http/wpt/webauthn/public-key-credential-get-failure-hid.https.html
http/wpt/webauthn/public-key-credential-get-success-hid.https.html

  • Modules/webauthn/AuthenticatorCoordinatorClient.cpp:

(WebCore::AuthenticatorCoordinatorClient::~AuthenticatorCoordinatorClient): Deleted.

  • Modules/webauthn/AuthenticatorCoordinatorClient.h:
  • Modules/webauthn/PublicKeyCredentialCreationOptions.h:
  • Modules/webauthn/fido/DeviceResponseConverter.cpp:

(fido::readCTAPGetAssertionResponse):

  • Modules/webauthn/fido/FidoConstants.h:

Source/WebKit:

This patch introduces a primitive support of CTAP HID authenticators for WebAuthN in macOS.
It involves low level HID device management&communication, high level CTAP HID authenticator
management&communication, and mock testing. The above three aspects will be covered in details:
1) Low level HID device management&communication: HidService&HidConnection
It relies on IOHIDManager to discover appropriate hid devices by passing a matching dictionary:
{ PrimaryUsagePage: 0xf1d0, PrimaryUsage: 0x01}. For communication, it utilizes HID reports.
To send a report, it calls IOHIDDeviceSetReport since the async version is not implemented.
To recieve a report, it calls IOHIDDeviceRegisterInputReportCallback to asynchronously wait
for incoming reports.
Here is the corresponding reference:
https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html#//apple_ref/doc/uid/TP40000970-CH214-SW2
2) High level CTAP HID authenticator management&communication: HidService&CtapHidDriver
Whenever an appropriate hid device is discovered by IOHIDManager, an AuthenticatorGetInfo command
is sent to the device to determine properties of the authenticator, says, which version of protocol
it supports, i.e. CTAP or U2F. So far, we only support CTAP authenticators. Once the authenticator
is determined to support CTAP, we then instantiate CtapHidAuthenticator which will then take care
of even higher level WebAuthN requests&responses.
Binaries are constructed and packaged according to the CTAP HID porotocol. CtapHidDriver takes care
of concurrency and channels, i.e. allocating channel and establishing the actual request/response
transaction. At the meantime, CtapHidDriver::Worker is then responsible for each single transaction.
Here is the corresponding reference:
https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#usb.
3) Mock Testing: MockHidService & MockHidConnection
A CTAP hid authenticator is simulated within MockHidConnection with options of specifying specific
error scenarios and of course could take care of successful cases. Four stages are presented in the
simulated authenticator to reflect: a) allocating channel for AuthenticatorGetInfo, b) sending
AuthenticatorGetInfo, c) allocating channel for actual request, and d) sending the actual request.

Besides implementing the above, it also does a few other things:
1) Make AuthenticatorManager::clearState asynchronous to avoid cyclic dependency:
Authenticator::returnResponse => AuthenticatorManager::respondReceived => AuthenticatorManager::clearState
=> Authenticator::~Authenticator.
2) Reorganize unified build sources to make it clear that which files are .mm and which are .cpp.
3) Import LocalAuthentication.framework in LocalAuthenticationSoftLink instead of being scattered.

  • Sources.txt:
  • SourcesCocoa.txt:
  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
  • UIProcess/API/C/WKWebsiteDataStoreRef.cpp:

(WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):

  • UIProcess/WebAuthentication/AuthenticatorManager.cpp:

(WebKit::AuthenticatorManagerInternal::collectTransports):
(WebKit::AuthenticatorManager::clearStateAsync):
(WebKit::AuthenticatorManager::respondReceived):
(WebKit::AuthenticatorManager::initTimeOutTimer):

  • UIProcess/WebAuthentication/AuthenticatorManager.h:
  • UIProcess/WebAuthentication/AuthenticatorTransportService.cpp:

(WebKit::AuthenticatorTransportService::create):
(WebKit::AuthenticatorTransportService::createMock):
(WebKit::AuthenticatorTransportService::startDiscovery):
(WebKit::AuthenticatorTransportService::startDiscovery const): Deleted.

  • UIProcess/WebAuthentication/AuthenticatorTransportService.h:
  • UIProcess/WebAuthentication/Cocoa/HidConnection.h: Copied from Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.h.
  • UIProcess/WebAuthentication/Cocoa/HidConnection.mm: Added.

(WebKit::reportReceived):
(WebKit::HidConnection::HidConnection):
(WebKit::HidConnection::~HidConnection):
(WebKit::HidConnection::initialize):
(WebKit::HidConnection::terminate):
(WebKit::HidConnection::send):
(WebKit::HidConnection::registerDataReceivedCallback):
(WebKit::HidConnection::unregisterDataReceivedCallback):
(WebKit::HidConnection::receiveReport):
(WebKit::HidConnection::consumeReports):
(WebKit::HidConnection::registerDataReceivedCallbackInternal):

  • UIProcess/WebAuthentication/Cocoa/HidService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.h.
  • UIProcess/WebAuthentication/Cocoa/HidService.mm: Added.

(WebKit::deviceAddedCallback):
(WebKit::deviceRemovedCallback):
(WebKit::HidService::HidService):
(WebKit::HidService::~HidService):
(WebKit::HidService::startDiscoveryInternal):
(WebKit::HidService::platformStartDiscovery):
(WebKit::HidService::createHidConnection const):
(WebKit::HidService::deviceAdded):
(WebKit::HidService::continueAddDeviceAfterGetInfo):

  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticationSoftLink.h:
  • UIProcess/WebAuthentication/Cocoa/LocalConnection.mm:
  • UIProcess/WebAuthentication/Cocoa/LocalService.h:
  • UIProcess/WebAuthentication/Cocoa/LocalService.mm:

(WebKit::LocalService::startDiscoveryInternal):
(WebKit::LocalService::startDiscoveryInternal const): Deleted.

  • UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:

(WebKit::MockAuthenticatorManager::respondReceivedInternal):

  • UIProcess/WebAuthentication/Mock/MockHidConnection.cpp: Added.

(WebKit::MockHidConnection::MockHidConnection):
(WebKit::MockHidConnection::initialize):
(WebKit::MockHidConnection::terminate):
(WebKit::MockHidConnection::send):
(WebKit::MockHidConnection::registerDataReceivedCallbackInternal):
(WebKit::MockHidConnection::assembleRequest):
(WebKit::MockHidConnection::parseRequest):
(WebKit::MockHidConnection::feedReports):
(WebKit::MockHidConnection::stagesMatch const):
(WebKit::MockHidConnection::shouldContinueFeedReports):
(WebKit::MockHidConnection::continueFeedReports):

  • UIProcess/WebAuthentication/Mock/MockHidConnection.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h.
  • UIProcess/WebAuthentication/Mock/MockHidService.cpp: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalService.cpp.

(WebKit::MockHidService::MockHidService):
(WebKit::MockHidService::platformStartDiscovery):
(WebKit::MockHidService::createHidConnection const):

  • UIProcess/WebAuthentication/Mock/MockHidService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h.
  • UIProcess/WebAuthentication/Mock/MockLocalConnection.h:
  • UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
  • UIProcess/WebAuthentication/Mock/MockLocalService.mm: Renamed from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalService.cpp.

(WebKit::MockLocalService::MockLocalService):
(WebKit::MockLocalService::platformStartDiscovery const):
(WebKit::MockLocalService::createLocalConnection const):

  • UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:
  • UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp: Added.

(WebKit::CtapHidAuthenticator::CtapHidAuthenticator):
(WebKit::CtapHidAuthenticator::makeCredential):
(WebKit::CtapHidAuthenticator::continueMakeCredentialAfterResponseReceived const):
(WebKit::CtapHidAuthenticator::getAssertion):
(WebKit::CtapHidAuthenticator::continueGetAssertionAfterResponseReceived const):

  • UIProcess/WebAuthentication/fido/CtapHidAuthenticator.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.h.
  • UIProcess/WebAuthentication/fido/CtapHidDriver.cpp: Added.

(WebKit::CtapHidDriver::Worker::Worker):
(WebKit::CtapHidDriver::Worker::~Worker):
(WebKit::CtapHidDriver::Worker::transact):
(WebKit::CtapHidDriver::Worker::write):
(WebKit::CtapHidDriver::Worker::read):
(WebKit::CtapHidDriver::Worker::returnMessage):
(WebKit::CtapHidDriver::CtapHidDriver):
(WebKit::CtapHidDriver::transact):
(WebKit::CtapHidDriver::continueAfterChannelAllocated):
(WebKit::CtapHidDriver::continueAfterResponseReceived):
(WebKit::CtapHidDriver::returnResponse):

  • UIProcess/WebAuthentication/fido/CtapHidDriver.h: Added.
  • UIProcess/mac/WebDataListSuggestionsDropdownMac.mm:
  • WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
  • WebKit.xcodeproj/project.pbxproj:

Tools:

This patch adds support for the mock testing and entitlements to allow minibrowser to talk
to hid devices.

  • MiniBrowser/MiniBrowser.entitlements:
  • WebKitTestRunner/InjectedBundle/TestRunner.cpp:

(WTR::TestRunner::setWebAuthenticationMockConfiguration):

LayoutTests:

  • http/wpt/webauthn/ctap-hid-failure.https-expected.txt: Added.
  • http/wpt/webauthn/ctap-hid-failure.https.html: Added.
  • http/wpt/webauthn/ctap-hid-success.https-expected.txt: Added.
  • http/wpt/webauthn/ctap-hid-success.https.html: Added.
  • http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https.html: Added.
  • http/wpt/webauthn/public-key-credential-create-failure-hid.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-create-failure-hid.https.html: Added.
  • http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-create-success-hid.https.html: Added.
  • http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https.html: Added.
  • http/wpt/webauthn/public-key-credential-get-failure-hid.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-get-failure-hid.https.html: Added.
  • http/wpt/webauthn/public-key-credential-get-success-hid.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-get-success-hid.https.html: Added.
  • http/wpt/webauthn/resources/util.js:
  • platform/ios-wk2/TestExpectations:
Location:
trunk
Files:
24 added
31 edited
5 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r238155 r238166  
     12018-11-13  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Support CTAP HID authenticators on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=188623
     5        <rdar://problem/43353777>
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        * http/wpt/webauthn/ctap-hid-failure.https-expected.txt: Added.
     10        * http/wpt/webauthn/ctap-hid-failure.https.html: Added.
     11        * http/wpt/webauthn/ctap-hid-success.https-expected.txt: Added.
     12        * http/wpt/webauthn/ctap-hid-success.https.html: Added.
     13        * http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https-expected.txt: Added.
     14        * http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https.html: Added.
     15        * http/wpt/webauthn/public-key-credential-create-failure-hid.https-expected.txt: Added.
     16        * http/wpt/webauthn/public-key-credential-create-failure-hid.https.html: Added.
     17        * http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt: Added.
     18        * http/wpt/webauthn/public-key-credential-create-success-hid.https.html: Added.
     19        * http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https-expected.txt: Added.
     20        * http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https.html: Added.
     21        * http/wpt/webauthn/public-key-credential-get-failure-hid.https-expected.txt: Added.
     22        * http/wpt/webauthn/public-key-credential-get-failure-hid.https.html: Added.
     23        * http/wpt/webauthn/public-key-credential-get-success-hid.https-expected.txt: Added.
     24        * http/wpt/webauthn/public-key-credential-get-success-hid.https.html: Added.
     25        * http/wpt/webauthn/resources/util.js:
     26        * platform/ios-wk2/TestExpectations:
     27
    1282018-11-13  Timothy Hatcher  <timothy@apple.com>
    229
  • trunk/LayoutTests/http/wpt/webauthn/resources/util.js

    r236842 r238166  
    3434    "W+4hJ4CeJjySXTgq6IEHn/yWab4CMQCm5NnK6SOSK+AqWum9lL87W3E6AA1f2TvJ" +
    3535    "/hgok/34jr93nhS87tOQNdxDS8zyiqw=";
     36const testDummyMessagePayloadBase64 =
     37    "/////wYAEQABAgMEBQYHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
     38    "AAAAAAAAAAAAAAAAAAAAAAAAAAEQADoAAQIDBAUGBwECAwQAAAAAAAAAAAAAAAAA" +
     39    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMEAAAAAAAAAAAAAAAA" +
     40    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
     41const testCreationMessageBase64 =
     42    "AKMBZnBhY2tlZAJYxEbMf7lnnVWy25CS4cjZ5eHQK3WA8LSBLHcJYuHkj1rYQQAA" +
     43    "AE74oBHzjApNFYAGFxEfntx9AEAoCK3O6P5OyXN6V/f+9nAga0NA2Cgp4V3mgSJ5" +
     44    "jOHLMDrmxp/S0rbD+aihru1C0aAN3BkiM6GNy5nSlDVqOgTgpQECAyYgASFYIEFb" +
     45    "he3RkNud6sgyraBGjlh1pzTlCZehQlL/b18HZ6WGIlggJgfUd/en9p5AIqMQbUni" +
     46    "nEeXdFLkvW0/zV5BpEjjNxADo2NhbGcmY3NpZ1hHMEUCIQDKg+ZBmEBtf0lWq4Re" +
     47    "dH4/i/LOYqOR4uR2NAj2zQmw9QIgbTXb4hvFbj4T27bv/rGrc+y+0puoYOBkBk9P" +
     48    "mCewWlNjeDVjgVkCwjCCAr4wggGmoAMCAQICBHSG/cIwDQYJKoZIhvcNAQELBQAw" +
     49    "LjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEw" +
     50    "IBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNF" +
     51    "MRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0" +
     52    "ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDE5NTUwMDM4" +
     53    "NDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVXfOt9yR9MXXv/ZzE8xpOh466" +
     54    "4YEJVmFQ+ziLLl9lJ79XQJqlgaUNCsUvGERcChNUihNTyKTlmnBOUjvATevto2ww" +
     55    "ajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLl" +
     56    "HAIBAQQEAwIFIDAhBgsrBgEEAYLlHAEBBAQSBBD4oBHzjApNFYAGFxEfntx9MAwG" +
     57    "A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADFcSIDmmlJ+OGaJvWn9Cqhv" +
     58    "SeueToVFQVVvqtALOgCKHdwB+Wx29mg2GpHiMsgQp5xjB0ybbnpG6x212FxESJ+G" +
     59    "inZD0ipchi7APwPlhIvjgH16zVX44a4e4hOsc6tLIOP71SaMsHuHgCcdH0vg5d2s" +
     60    "c006WJe9TXO6fzV+ogjJnYpNKQLmCXoAXE3JBNwKGBIOCvfQDPyWmiiG5bGxYfPt" +
     61    "y8Z3pnjX+1MDnM2hhr40ulMxlSNDnX/ZSnDyMGIbk8TOQmjTF02UO8auP8k3wt5D" +
     62    "1rROIRU9+FCSX5WQYi68RuDrGMZB8P5+byoJqbKQdxn2LmE1oZAyohPAmLcoPO4=";
     63const testHidCredentialIdBase64 =
     64    "KAitzuj-Tslzelf3_vZwIGtDQNgoKeFd5oEieYzhyzA65saf0tK2w_mooa7tQtGg" +
     65    "DdwZIjOhjcuZ0pQ1ajoE4A";
     66const testAssertionMessageBase64 =
     67    "AKMBomJpZFhAKAitzuj+Tslzelf3/vZwIGtDQNgoKeFd5oEieYzhyzA65saf0tK2" +
     68    "w/mooa7tQtGgDdwZIjOhjcuZ0pQ1ajoE4GR0eXBlanB1YmxpYy1rZXkCWCVGzH+5" +
     69    "Z51VstuQkuHI2eXh0Ct1gPC0gSx3CWLh5I9a2AEAAABQA1hHMEUCIQCSFTuuBWgB" +
     70    "4/F0VB7DlUVM09IHPmxe1MzHUwRoCRZbCAIgGKov6xoAx2MEf6/6qNs8OutzhP2C" +
     71    "QoJ1L7Fe64G9uBc=";
    3672
    3773const RESOURCES_DIR = "/WebKit/webauthn/resources/";
     
    99135}
    100136
    101 function decodeAuthData(authDataUint8Array)
     137function decodeAuthData(authDataUint8Array, littleEndian = true)
    102138{
    103139    let authDataObject = { };
     
    123159    if (pos + size > authDataUint8Array.byteLength)
    124160        return { };
    125     authDataObject.counter = new Uint32Array(authDataUint8Array.slice(pos, pos + size))[0];
     161    if (littleEndian)
     162        authDataObject.counter = new Uint32Array(authDataUint8Array.slice(pos, pos + size))[0];
     163    else
     164        authDataObject.counter = (authDataUint8Array[pos] << 24) + (authDataUint8Array[pos + 1] << 16) + (authDataUint8Array[pos + 2] << 8) + authDataUint8Array[pos + 3];
    126165    pos = pos + size;
    127166
     
    140179    if (pos + size > authDataUint8Array.byteLength)
    141180        return { };
    142     // Little Endian
    143     authDataObject.l = new Uint16Array(authDataUint8Array.slice(pos, pos + size))[0];
     181    if (littleEndian)
     182        authDataObject.l = new Uint16Array(authDataUint8Array.slice(pos, pos + size))[0];
     183    else
     184        authDataObject.l = (authDataUint8Array[pos] << 8) + authDataUint8Array[pos + 1];
    144185    pos = pos + size;
    145186
  • trunk/LayoutTests/platform/ios-wk2/TestExpectations

    r238042 r238166  
    13101310webkit.org/b/189641 [ Debug ] webgl/2.0.0/conformance/attribs/gl-vertexattribpointer.html [ Slow ]
    13111311
     1312# Skip WebAuthN tests for hid authenticators
     1313http/wpt/webauthn/ctap-hid-failure.https.html [ Skip ]
     1314http/wpt/webauthn/ctap-hid-success.https.html [ Skip ]
     1315http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https.html [ Skip ]
     1316http/wpt/webauthn/public-key-credential-create-failure-hid.https.html [ Skip ]
     1317http/wpt/webauthn/public-key-credential-create-success-hid.https.html [ Skip ]
     1318http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https.html [ Skip ]
     1319http/wpt/webauthn/public-key-credential-get-failure-hid.https.html [ Skip ]
     1320http/wpt/webauthn/public-key-credential-get-success-hid.https.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r238159 r238166  
     12018-11-13  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Support CTAP HID authenticators on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=188623
     5        <rdar://problem/43353777>
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        This patch removes AuthenticatorCoordinatorClient::~AuthenticatorCoordinatorClient to ignore
     10        any incompleted CompletionHandlers as calling them in destructors could cause unexpected cyclic
     11        dependency. Also, it adds a hack to temporarily deal with nullable userhandle.
     12
     13        Tests: http/wpt/webauthn/ctap-hid-failure.https.html
     14               http/wpt/webauthn/ctap-hid-success.https.html
     15               http/wpt/webauthn/public-key-credential-create-failure-hid-silent.https.html
     16               http/wpt/webauthn/public-key-credential-create-failure-hid.https.html
     17               http/wpt/webauthn/public-key-credential-create-success-hid.https.html
     18               http/wpt/webauthn/public-key-credential-get-failure-hid-silent.https.html
     19               http/wpt/webauthn/public-key-credential-get-failure-hid.https.html
     20               http/wpt/webauthn/public-key-credential-get-success-hid.https.html
     21
     22        * Modules/webauthn/AuthenticatorCoordinatorClient.cpp:
     23        (WebCore::AuthenticatorCoordinatorClient::~AuthenticatorCoordinatorClient): Deleted.
     24        * Modules/webauthn/AuthenticatorCoordinatorClient.h:
     25        * Modules/webauthn/PublicKeyCredentialCreationOptions.h:
     26        * Modules/webauthn/fido/DeviceResponseConverter.cpp:
     27        (fido::readCTAPGetAssertionResponse):
     28        * Modules/webauthn/fido/FidoConstants.h:
     29
    1302018-11-13  Ross Kirsling  <ross.kirsling@sony.com>
    231
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinatorClient.cpp

    r235888 r238166  
    3333namespace WebCore {
    3434
    35 AuthenticatorCoordinatorClient::~AuthenticatorCoordinatorClient()
    36 {
    37     // Just to call handlers to avoid any assertion failures.
    38     if (m_pendingCompletionHandler)
    39         m_pendingCompletionHandler({ }, { NotAllowedError, "Operation timed out."_s });
    40     for (auto itr = m_pendingQueryCompletionHandlers.begin(); itr !=  m_pendingQueryCompletionHandlers.end(); ++itr)
    41         itr->value(false);
    42 }
    43 
    4435void AuthenticatorCoordinatorClient::requestReply(const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception)
    4536{
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinatorClient.h

    r235888 r238166  
    4949public:
    5050    AuthenticatorCoordinatorClient() = default;
    51     virtual ~AuthenticatorCoordinatorClient();
     51    virtual ~AuthenticatorCoordinatorClient() = default;
    5252
    5353    // Senders.
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h

    r237983 r238166  
    6767
    6868    struct AuthenticatorSelectionCriteria {
    69         std::optional<AuthenticatorAttachment> authenticatorAttachment;
     69        // FIXME(191522)
     70        AuthenticatorAttachment authenticatorAttachment { AuthenticatorAttachment::CrossPlatform };
    7071        bool requireResidentKey { false };
    7172        UserVerificationRequirement userVerification { UserVerificationRequirement::Preferred };
     
    117118    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria result;
    118119
    119     std::optional<std::optional<AuthenticatorAttachment>> authenticatorAttachment;
     120    std::optional<AuthenticatorAttachment> authenticatorAttachment;
    120121    decoder >> authenticatorAttachment;
    121122    if (!authenticatorAttachment)
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp

    r237983 r238166  
    159159    auto& signature = it->second.getByteString();
    160160
    161     RefPtr<ArrayBuffer> userHandle;
    162     {
    163         it = responseMap.find(CBOR(4));
    164         if (it == responseMap.end() || !it->second.isMap())
    165             return std::nullopt;
     161    // FIXME(191521): Properly handle null userHandle.
     162    RefPtr<ArrayBuffer> userHandle = ArrayBuffer::create(1, 1);
     163    it = responseMap.find(CBOR(4));
     164    if (it != responseMap.end() && it->second.isMap()) {
    166165        auto& user = it->second.getMap();
    167166        auto itr = user.find(CBOR(kEntityIdMapKey));
  • trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.h

    r237983 r238166  
    160160const size_t kHidInitPacketDataSize = kHidMaxPacketSize - kHidInitPacketHeaderSize;
    161161const size_t kHidContinuationPacketDataSize = kHidMaxPacketSize - kHidContinuationPacketHeader;
     162const size_t kHidInitResponseSize = 17;
    162163
    163164const uint8_t kHidMaxLockSeconds = 10;
     
    165166// Messages are limited to an initiation packet and 128 continuation packets.
    166167const size_t kHidMaxMessageSize = 7609;
     168
     169// CTAP/U2F devices only provide a single report so specify a report ID of 0 here.
     170const uint8_t kHidReportId = 0x00;
    167171
    168172// Authenticator API commands supported by CTAP devices, as specified in
     
    194198const char kU2fVersion[] = "U2F_V2";
    195199
     200// CTAPHID Usage Page and Usage
     201// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#hid-report-descriptor-and-device-discovery
     202const uint32_t kCTAPHIDUsagePage = 0xF1D0;
     203const uint32_t kCTAPHIDUsage = 0x01;
     204
    196205} // namespace fido
    197206
  • trunk/Source/WebKit/ChangeLog

    r238161 r238166  
     12018-11-13  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Support CTAP HID authenticators on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=188623
     5        <rdar://problem/43353777>
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        This patch introduces a primitive support of CTAP HID authenticators for WebAuthN in macOS.
     10        It involves low level HID device management&communication, high level CTAP HID authenticator
     11        management&communication, and mock testing. The above three aspects will be covered in details:
     12        1) Low level HID device management&communication: HidService&HidConnection
     13        It relies on IOHIDManager to discover appropriate hid devices by passing a matching dictionary:
     14        { PrimaryUsagePage: 0xf1d0, PrimaryUsage: 0x01}. For communication, it utilizes HID reports.
     15        To send a report, it calls IOHIDDeviceSetReport since the async version is not implemented.
     16        To recieve a report, it calls IOHIDDeviceRegisterInputReportCallback to asynchronously wait
     17        for incoming reports.
     18        Here is the corresponding reference:
     19        https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html#//apple_ref/doc/uid/TP40000970-CH214-SW2
     20        2) High level CTAP HID authenticator management&communication: HidService&CtapHidDriver
     21        Whenever an appropriate hid device is discovered by IOHIDManager, an AuthenticatorGetInfo command
     22        is sent to the device to determine properties of the authenticator, says, which version of protocol
     23        it supports, i.e. CTAP or U2F. So far, we only support CTAP authenticators. Once the authenticator
     24        is determined to support CTAP, we then instantiate CtapHidAuthenticator which will then take care
     25        of even higher level WebAuthN requests&responses.
     26        Binaries are constructed and packaged according to the CTAP HID porotocol. CtapHidDriver takes care
     27        of concurrency and channels, i.e. allocating channel and establishing the actual request/response
     28        transaction. At the meantime, CtapHidDriver::Worker is then responsible for each single transaction.
     29        Here is the corresponding reference:
     30        https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#usb.
     31        3) Mock Testing: MockHidService & MockHidConnection
     32        A CTAP hid authenticator is simulated within MockHidConnection with options of specifying specific
     33        error scenarios and of course could take care of successful cases. Four stages are presented in the
     34        simulated authenticator to reflect: a) allocating channel for AuthenticatorGetInfo, b) sending
     35        AuthenticatorGetInfo, c) allocating channel for actual request, and d) sending the actual request.
     36
     37        Besides implementing the above, it also does a few other things:
     38        1) Make AuthenticatorManager::clearState asynchronous to avoid cyclic dependency:
     39        Authenticator::returnResponse => AuthenticatorManager::respondReceived => AuthenticatorManager::clearState
     40        => Authenticator::~Authenticator.
     41        2) Reorganize unified build sources to make it clear that which files are .mm and which are .cpp.
     42        3) Import LocalAuthentication.framework in LocalAuthenticationSoftLink instead of being scattered.
     43
     44        * Sources.txt:
     45        * SourcesCocoa.txt:
     46        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
     47        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
     48        (WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):
     49        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
     50        (WebKit::AuthenticatorManagerInternal::collectTransports):
     51        (WebKit::AuthenticatorManager::clearStateAsync):
     52        (WebKit::AuthenticatorManager::respondReceived):
     53        (WebKit::AuthenticatorManager::initTimeOutTimer):
     54        * UIProcess/WebAuthentication/AuthenticatorManager.h:
     55        * UIProcess/WebAuthentication/AuthenticatorTransportService.cpp:
     56        (WebKit::AuthenticatorTransportService::create):
     57        (WebKit::AuthenticatorTransportService::createMock):
     58        (WebKit::AuthenticatorTransportService::startDiscovery):
     59        (WebKit::AuthenticatorTransportService::startDiscovery const): Deleted.
     60        * UIProcess/WebAuthentication/AuthenticatorTransportService.h:
     61        * UIProcess/WebAuthentication/Cocoa/HidConnection.h: Copied from Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.h.
     62        * UIProcess/WebAuthentication/Cocoa/HidConnection.mm: Added.
     63        (WebKit::reportReceived):
     64        (WebKit::HidConnection::HidConnection):
     65        (WebKit::HidConnection::~HidConnection):
     66        (WebKit::HidConnection::initialize):
     67        (WebKit::HidConnection::terminate):
     68        (WebKit::HidConnection::send):
     69        (WebKit::HidConnection::registerDataReceivedCallback):
     70        (WebKit::HidConnection::unregisterDataReceivedCallback):
     71        (WebKit::HidConnection::receiveReport):
     72        (WebKit::HidConnection::consumeReports):
     73        (WebKit::HidConnection::registerDataReceivedCallbackInternal):
     74        * UIProcess/WebAuthentication/Cocoa/HidService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.h.
     75        * UIProcess/WebAuthentication/Cocoa/HidService.mm: Added.
     76        (WebKit::deviceAddedCallback):
     77        (WebKit::deviceRemovedCallback):
     78        (WebKit::HidService::HidService):
     79        (WebKit::HidService::~HidService):
     80        (WebKit::HidService::startDiscoveryInternal):
     81        (WebKit::HidService::platformStartDiscovery):
     82        (WebKit::HidService::createHidConnection const):
     83        (WebKit::HidService::deviceAdded):
     84        (WebKit::HidService::continueAddDeviceAfterGetInfo):
     85        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticationSoftLink.h:
     86        * UIProcess/WebAuthentication/Cocoa/LocalConnection.mm:
     87        * UIProcess/WebAuthentication/Cocoa/LocalService.h:
     88        * UIProcess/WebAuthentication/Cocoa/LocalService.mm:
     89        (WebKit::LocalService::startDiscoveryInternal):
     90        (WebKit::LocalService::startDiscoveryInternal const): Deleted.
     91        * UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:
     92        (WebKit::MockAuthenticatorManager::respondReceivedInternal):
     93        * UIProcess/WebAuthentication/Mock/MockHidConnection.cpp: Added.
     94        (WebKit::MockHidConnection::MockHidConnection):
     95        (WebKit::MockHidConnection::initialize):
     96        (WebKit::MockHidConnection::terminate):
     97        (WebKit::MockHidConnection::send):
     98        (WebKit::MockHidConnection::registerDataReceivedCallbackInternal):
     99        (WebKit::MockHidConnection::assembleRequest):
     100        (WebKit::MockHidConnection::parseRequest):
     101        (WebKit::MockHidConnection::feedReports):
     102        (WebKit::MockHidConnection::stagesMatch const):
     103        (WebKit::MockHidConnection::shouldContinueFeedReports):
     104        (WebKit::MockHidConnection::continueFeedReports):
     105        * UIProcess/WebAuthentication/Mock/MockHidConnection.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h.
     106        * UIProcess/WebAuthentication/Mock/MockHidService.cpp: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalService.cpp.
     107        (WebKit::MockHidService::MockHidService):
     108        (WebKit::MockHidService::platformStartDiscovery):
     109        (WebKit::MockHidService::createHidConnection const):
     110        * UIProcess/WebAuthentication/Mock/MockHidService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h.
     111        * UIProcess/WebAuthentication/Mock/MockLocalConnection.h:
     112        * UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
     113        * UIProcess/WebAuthentication/Mock/MockLocalService.mm: Renamed from Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalService.cpp.
     114        (WebKit::MockLocalService::MockLocalService):
     115        (WebKit::MockLocalService::platformStartDiscovery const):
     116        (WebKit::MockLocalService::createLocalConnection const):
     117        * UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:
     118        * UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp: Added.
     119        (WebKit::CtapHidAuthenticator::CtapHidAuthenticator):
     120        (WebKit::CtapHidAuthenticator::makeCredential):
     121        (WebKit::CtapHidAuthenticator::continueMakeCredentialAfterResponseReceived const):
     122        (WebKit::CtapHidAuthenticator::getAssertion):
     123        (WebKit::CtapHidAuthenticator::continueGetAssertionAfterResponseReceived const):
     124        * UIProcess/WebAuthentication/fido/CtapHidAuthenticator.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.h.
     125        * UIProcess/WebAuthentication/fido/CtapHidDriver.cpp: Added.
     126        (WebKit::CtapHidDriver::Worker::Worker):
     127        (WebKit::CtapHidDriver::Worker::~Worker):
     128        (WebKit::CtapHidDriver::Worker::transact):
     129        (WebKit::CtapHidDriver::Worker::write):
     130        (WebKit::CtapHidDriver::Worker::read):
     131        (WebKit::CtapHidDriver::Worker::returnMessage):
     132        (WebKit::CtapHidDriver::CtapHidDriver):
     133        (WebKit::CtapHidDriver::transact):
     134        (WebKit::CtapHidDriver::continueAfterChannelAllocated):
     135        (WebKit::CtapHidDriver::continueAfterResponseReceived):
     136        (WebKit::CtapHidDriver::returnResponse):
     137        * UIProcess/WebAuthentication/fido/CtapHidDriver.h: Added.
     138        * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm:
     139        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
     140        * WebKit.xcodeproj/project.pbxproj:
     141
    11422018-11-13  Ross Kirsling  <ross.kirsling@sony.com>
    2143
  • trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h

    r237410 r238166  
    5757        virtual void didDestroyGLContext() = 0;
    5858
    59         virtual void resize(const IntSize&) = 0;
     59        virtual void resize(const WebCore::IntSize&) = 0;
    6060        virtual void willRenderFrame() = 0;
    6161        virtual void didRenderFrame() = 0;
  • trunk/Source/WebKit/Sources.txt

    r237205 r238166  
    385385UIProcess/UserContent/WebUserContentControllerProxy.cpp
    386386
     387UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp
     388UIProcess/WebAuthentication/Mock/MockHidConnection.cpp
     389UIProcess/WebAuthentication/Mock/MockHidService.cpp
     390
     391UIProcess/WebAuthentication/AuthenticatorManager.cpp
     392UIProcess/WebAuthentication/AuthenticatorTransportService.cpp
     393UIProcess/WebAuthentication/Authenticator.cpp
     394UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp
     395
    387396UIProcess/WebStorage/LocalStorageDatabase.cpp
    388397UIProcess/WebStorage/LocalStorageDatabaseTracker.cpp
     
    494503
    495504WebProcess/UserContent/WebUserContentController.cpp
     505
     506WebProcess/WebAuthentication/WebAuthenticatorCoordinator.cpp
    496507
    497508WebProcess/WebCoreSupport/SessionStateConversion.cpp
  • trunk/Source/WebKit/SourcesCocoa.txt

    r238108 r238166  
    452452UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
    453453
     454UIProcess/WebAuthentication/Cocoa/HidConnection.mm
     455UIProcess/WebAuthentication/Cocoa/HidService.mm
    454456UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm
    455457UIProcess/WebAuthentication/Cocoa/LocalConnection.mm
    456458UIProcess/WebAuthentication/Cocoa/LocalService.mm
    457459
    458 UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp
    459460UIProcess/WebAuthentication/Mock/MockLocalConnection.mm
    460 UIProcess/WebAuthentication/Mock/MockLocalService.cpp
    461 
    462 UIProcess/WebAuthentication/AuthenticatorManager.cpp
    463 UIProcess/WebAuthentication/AuthenticatorTransportService.cpp
    464 UIProcess/WebAuthentication/Authenticator.cpp
    465 UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp
     461UIProcess/WebAuthentication/Mock/MockLocalService.mm
    466462
    467463UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
     
    518514WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm
    519515
    520 WebProcess/WebAuthentication/WebAuthenticatorCoordinator.cpp
    521 
    522516WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp
    523517WebProcess/WebCoreSupport/WebPasteboardOverrides.cpp
  • trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp

    r238125 r238166  
    582582    MockWebAuthenticationConfiguration configuration;
    583583
    584     auto silentFailureRef = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("SilentFailure")).get()));
    585     if (silentFailureRef)
     584    if (auto silentFailureRef = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("SilentFailure")).get())))
    586585        configuration.silentFailure = WKBooleanGetValue(silentFailureRef);
    587586
    588     auto localRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Local")).get()));
    589     if (localRef) {
     587    if (auto localRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Local")).get()))) {
    590588        MockWebAuthenticationConfiguration::Local local;
    591589        local.acceptAuthentication = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("AcceptAuthentication")).get())));
     
    599597    }
    600598
     599    if (auto hidRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Hid")).get()))) {
     600        MockWebAuthenticationConfiguration::Hid hid;
     601
     602        auto stage = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("Stage")).get())))->string();
     603        if (stage == "info")
     604            hid.stage = MockWebAuthenticationConfiguration::Hid::Stage::Info;
     605        if (stage == "request")
     606            hid.stage = MockWebAuthenticationConfiguration::Hid::Stage::Request;
     607
     608        auto subStage = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("SubStage")).get())))->string();
     609        if (subStage == "init")
     610            hid.subStage = MockWebAuthenticationConfiguration::Hid::SubStage::Init;
     611        if (subStage == "msg")
     612            hid.subStage = MockWebAuthenticationConfiguration::Hid::SubStage::Msg;
     613
     614
     615        auto error = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("Error")).get())))->string();
     616        if (error == "success")
     617            hid.error = MockWebAuthenticationConfiguration::Hid::Error::Success;
     618        if (error == "data-not-sent")
     619            hid.error = MockWebAuthenticationConfiguration::Hid::Error::DataNotSent;
     620        if (error == "empty-report")
     621            hid.error = MockWebAuthenticationConfiguration::Hid::Error::EmptyReport;
     622        if (error == "wrong-channel-id")
     623            hid.error = MockWebAuthenticationConfiguration::Hid::Error::WrongChannelId;
     624        if (error == "malicious-payload")
     625            hid.error = MockWebAuthenticationConfiguration::Hid::Error::MaliciousPayload;
     626        if (error == "unsupported-options")
     627            hid.error = MockWebAuthenticationConfiguration::Hid::Error::UnsupportedOptions;
     628
     629        if (auto payloadBase64 = static_cast<WKStringRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("PayloadBase64")).get())))
     630            hid.payloadBase64 = WebKit::toImpl(payloadBase64)->string();
     631
     632        if (auto keepAlive = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("KeepAlive")).get())))
     633            hid.keepAlive = WKBooleanGetValue(keepAlive);
     634
     635        if (auto fastDataArrival = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("FastDataArrival")).get())))
     636            hid.fastDataArrival = WKBooleanGetValue(fastDataArrival);
     637
     638        if (auto continueAfterErrorData = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(hidRef, adoptWK(WKStringCreateWithUTF8CString("ContinueAfterErrorData")).get())))
     639            hid.continueAfterErrorData = WKBooleanGetValue(continueAfterErrorData);
     640
     641        configuration.hid = WTFMove(hid);
     642    }
     643
    601644    WebKit::toImpl(dataStoreRef)->websiteDataStore().setMockWebAuthenticationConfiguration(WTFMove(configuration));
    602645#endif
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp

    r236842 r238166  
    3131#include <WebCore/AuthenticatorTransport.h>
    3232#include <WebCore/PublicKeyCredentialCreationOptions.h>
    33 #include <wtf/RunLoop.h>
    3433
    3534namespace WebKit {
     
    3837namespace AuthenticatorManagerInternal {
    3938
     39#if PLATFORM(MAC)
     40const size_t maxTransportNumber = 2;
     41#else
    4042const size_t maxTransportNumber = 1;
     43#endif
     44
    4145// Suggested by WebAuthN spec as of 7 August 2018.
    4246const unsigned maxTimeOutValue = 120000;
    4347
    44 // FIXME(188623, 188624, 188625): Support USB, NFC and BLE authenticators.
     48// FIXME(188624, 188625): Support NFC and BLE authenticators.
    4549static AuthenticatorManager::TransportSet collectTransports(const std::optional<PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria>& authenticatorSelection)
    4650{
     
    4953        auto addResult = result.add(AuthenticatorTransport::Internal);
    5054        ASSERT_UNUSED(addResult, addResult.isNewEntry);
     55#if PLATFORM(MAC)
     56        addResult = result.add(AuthenticatorTransport::Usb);
     57        ASSERT_UNUSED(addResult, addResult.isNewEntry);
     58#endif
    5159        return result;
    5260    }
     
    5765        return result;
    5866    }
    59     if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform)
    60         return result;
     67    if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform) {
     68#if PLATFORM(MAC)
     69        auto addResult = result.add(AuthenticatorTransport::Usb);
     70        ASSERT_UNUSED(addResult, addResult.isNewEntry);
     71#endif
     72        return result;
     73    }
    6174
    6275    ASSERT_NOT_REACHED();
     
    6477}
    6578
    66 // FIXME(188623, 188624, 188625): Support USB, NFC and BLE authenticators.
     79// FIXME(188624, 188625): Support NFC and BLE authenticators.
    6780// The goal is to find a union of different transports from allowCredentials.
    6881// If it is not specified or any of its credentials doesn't specify its own. We should discover all.
     
    7588        auto addResult = result.add(AuthenticatorTransport::Internal);
    7689        ASSERT_UNUSED(addResult, addResult.isNewEntry);
     90#if PLATFORM(MAC)
     91        addResult = result.add(AuthenticatorTransport::Usb);
     92        ASSERT_UNUSED(addResult, addResult.isNewEntry);
     93#endif
    7794        return result;
    7895    }
     
    8198        if (allowCredential.transports.isEmpty()) {
    8299            result.add(AuthenticatorTransport::Internal);
     100#if PLATFORM(MAC)
     101            result.add(AuthenticatorTransport::Usb);
    83102            return result;
     103#endif
    84104        }
    85105        if (!result.contains(AuthenticatorTransport::Internal) && allowCredential.transports.contains(AuthenticatorTransport::Internal))
    86106            result.add(AuthenticatorTransport::Internal);
     107#if PLATFORM(MAC)
     108        if (!result.contains(AuthenticatorTransport::Usb) && allowCredential.transports.contains(AuthenticatorTransport::Usb))
     109            result.add(AuthenticatorTransport::Usb);
     110#endif
    87111        if (result.size() >= maxTransportNumber)
    88112            return result;
     
    94118
    95119} // namespace AuthenticatorManagerInternal
     120
     121AuthenticatorManager::AuthenticatorManager()
     122    : m_requestTimeOutTimer(RunLoop::main(), this, &AuthenticatorManager::timeOutTimerFired)
     123{
     124}
    96125
    97126void AuthenticatorManager::makeCredential(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions& options, Callback&& callback)
     
    132161}
    133162
    134 void AuthenticatorManager::clearState()
    135 {
    136     m_pendingRequestData = { };
    137     ASSERT(!m_pendingCompletionHandler);
    138     m_services.clear();
    139     m_authenticators.clear();
     163void AuthenticatorManager::clearStateAsync()
     164{
     165    RunLoop::main().dispatch([weakThis = makeWeakPtr(*this)] {
     166        if (!weakThis)
     167            return;
     168        weakThis->m_pendingRequestData = { };
     169        ASSERT(!weakThis->m_pendingCompletionHandler);
     170        weakThis->m_services.clear();
     171        weakThis->m_authenticators.clear();
     172    });
    140173}
    141174
     
    152185{
    153186    ASSERT(RunLoop::isMain());
    154     ASSERT(m_requestTimeOutTimer);
    155     if (!m_requestTimeOutTimer->isActive())
     187    if (!m_requestTimeOutTimer.isActive())
    156188        return;
    157189
     
    159191    if (WTF::holds_alternative<PublicKeyCredentialData>(respond)) {
    160192        m_pendingCompletionHandler(WTFMove(respond));
    161         clearState();
    162         m_requestTimeOutTimer->stop();
     193        clearStateAsync();
     194        m_requestTimeOutTimer.stop();
    163195        return;
    164196    }
     
    192224
    193225    unsigned timeOutInMsValue = std::min(maxTimeOutValue, timeOutInMs.value_or(maxTimeOutValue));
    194 
    195     m_requestTimeOutTimer = std::make_unique<Timer>([context = this]() mutable {
    196         context->m_pendingCompletionHandler((ExceptionData { NotAllowedError, "Operation timed out."_s }));
    197         context->clearState();
    198     });
    199     m_requestTimeOutTimer->startOneShot(Seconds::fromMilliseconds(timeOutInMsValue));
     226    m_requestTimeOutTimer.startOneShot(Seconds::fromMilliseconds(timeOutInMsValue));
     227}
     228
     229void AuthenticatorManager::timeOutTimerFired()
     230{
     231    m_pendingCompletionHandler((ExceptionData { NotAllowedError, "Operation timed out."_s }));
     232    clearStateAsync();
    200233}
    201234
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h

    r236842 r238166  
    3333#include <WebCore/ExceptionData.h>
    3434#include <WebCore/PublicKeyCredentialData.h>
    35 #include <WebCore/Timer.h>
    3635#include <wtf/CompletionHandler.h>
    3736#include <wtf/HashSet.h>
    3837#include <wtf/Noncopyable.h>
     38#include <wtf/RunLoop.h>
    3939#include <wtf/Vector.h>
    4040
     
    4949    using TransportSet = HashSet<WebCore::AuthenticatorTransport, WTF::IntHash<WebCore::AuthenticatorTransport>, WTF::StrongEnumHashTraits<WebCore::AuthenticatorTransport>>;
    5050
    51     AuthenticatorManager() = default;
     51    using AuthenticatorTransportService::Observer::weakPtrFactory;
     52
     53    AuthenticatorManager();
    5254    virtual ~AuthenticatorManager() = default;
    5355
     
    5961protected:
    6062    Callback& pendingCompletionHandler() { return m_pendingCompletionHandler; }
    61     WebCore::Timer* requestTimeOutTimer() { return m_requestTimeOutTimer.get(); }
    62     void clearState();
     63    RunLoop::Timer<AuthenticatorManager>& requestTimeOutTimer() { return m_requestTimeOutTimer; }
     64    void clearStateAsync(); // To void cyclic dependence.
    6365
    6466private:
     
    7678    void startDiscovery(const TransportSet&);
    7779    void initTimeOutTimer(const std::optional<unsigned>& timeOutInMs);
     80    void timeOutTimerFired();
    7881
    7982    // Request: We only allow one request per time.
    8083    WebAuthenticationRequestData m_pendingRequestData;
    8184    Callback m_pendingCompletionHandler;
    82     std::unique_ptr<WebCore::Timer> m_requestTimeOutTimer;
     85    RunLoop::Timer<AuthenticatorManager> m_requestTimeOutTimer;
    8386
    8487    Vector<UniqueRef<AuthenticatorTransportService>> m_services;
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.cpp

    r236481 r238166  
    2929#if ENABLE(WEB_AUTHN)
    3030
     31#include "HidService.h"
    3132#include "LocalService.h"
     33#include "MockHidService.h"
    3234#include "MockLocalService.h"
    3335#include <wtf/RunLoop.h>
     
    3739UniqueRef<AuthenticatorTransportService> AuthenticatorTransportService::create(WebCore::AuthenticatorTransport transport, Observer& observer)
    3840{
    39     ASSERT(transport == WebCore::AuthenticatorTransport::Internal);
    40     return makeUniqueRef<LocalService>(observer);
     41    switch (transport) {
     42    case WebCore::AuthenticatorTransport::Internal:
     43        return makeUniqueRef<LocalService>(observer);
     44#if PLATFORM(MAC)
     45    case WebCore::AuthenticatorTransport::Usb:
     46        return makeUniqueRef<HidService>(observer);
     47#endif
     48    default:
     49        ASSERT_NOT_REACHED();
     50        return makeUniqueRef<LocalService>(observer);
     51    }
    4152}
    4253
    4354UniqueRef<AuthenticatorTransportService> AuthenticatorTransportService::createMock(WebCore::AuthenticatorTransport transport, Observer& observer, const MockWebAuthenticationConfiguration& configuration)
    4455{
    45     ASSERT(transport == WebCore::AuthenticatorTransport::Internal);
    46     return makeUniqueRef<MockLocalService>(observer, configuration);
     56    switch (transport) {
     57    case WebCore::AuthenticatorTransport::Internal:
     58        return makeUniqueRef<MockLocalService>(observer, configuration);
     59#if PLATFORM(MAC)
     60    case WebCore::AuthenticatorTransport::Usb:
     61        return makeUniqueRef<MockHidService>(observer, configuration);
     62#endif
     63    default:
     64        ASSERT_NOT_REACHED();
     65        return makeUniqueRef<MockLocalService>(observer, configuration);
     66    }
    4767}
    4868
     
    5272}
    5373
    54 void AuthenticatorTransportService::startDiscovery() const
     74void AuthenticatorTransportService::startDiscovery()
    5575{
    5676    // Enforce asynchronous execution of makeCredential.
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.h

    r236481 r238166  
    5555
    5656    // This operation is guaranteed to execute asynchronously.
    57     void startDiscovery() const;
     57    void startDiscovery();
    5858
    5959protected:
     
    6363
    6464private:
    65     virtual void startDiscoveryInternal() const = 0;
     65    virtual void startDiscoveryInternal() = 0;
    6666
    6767    WeakPtr<Observer> m_observer;
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidConnection.h

    r238165 r238166  
    2626#pragma once
    2727
    28 #if ENABLE(WEB_AUTHN)
     28#if ENABLE(WEB_AUTHN) && PLATFORM(MAC)
    2929
    30 #include <WebCore/AuthenticatorTransport.h>
    31 #include <wtf/UniqueRef.h>
    32 #include <wtf/WeakPtr.h>
     30#include <IOKit/hid/IOHIDDevice.h>
     31#include <wtf/CompletionHandler.h>
     32#include <wtf/Deque.h>
     33#include <wtf/Forward.h>
     34#include <wtf/Function.h>
     35#include <wtf/Noncopyable.h>
     36#include <wtf/RetainPtr.h>
    3337
    3438namespace WebKit {
    3539
    36 class Authenticator;
    37 
    38 struct MockWebAuthenticationConfiguration;
    39 
    40 class AuthenticatorTransportService : public CanMakeWeakPtr<AuthenticatorTransportService> {
     40class HidConnection {
    4141    WTF_MAKE_FAST_ALLOCATED;
    42     WTF_MAKE_NONCOPYABLE(AuthenticatorTransportService);
     42    WTF_MAKE_NONCOPYABLE(HidConnection);
    4343public:
    44     class Observer : public CanMakeWeakPtr<Observer> {
    45     public:
    46         virtual ~Observer() = default;
    47 
    48         virtual void authenticatorAdded(Ref<Authenticator>&&) = 0;
     44    enum class DataSent {
     45        No,
     46        Yes
    4947    };
    5048
    51     static UniqueRef<AuthenticatorTransportService> create(WebCore::AuthenticatorTransport, Observer&);
    52     static UniqueRef<AuthenticatorTransportService> createMock(WebCore::AuthenticatorTransport, Observer&, const MockWebAuthenticationConfiguration&);
     49    using DataSentCallback = CompletionHandler<void(DataSent)>;
     50    using DataReceivedCallback = Function<void(Vector<uint8_t>&&)>;
    5351
    54     virtual ~AuthenticatorTransportService() = default;
     52    explicit HidConnection(IOHIDDeviceRef);
     53    virtual ~HidConnection();
    5554
    56     // This operation is guaranteed to execute asynchronously.
    57     void startDiscovery() const;
     55    // Overrided by MockHidConnection.
     56    virtual void initialize();
     57    virtual void terminate();
     58    // Caller should send data again after callback is invoked to control flow.
     59    virtual void send(Vector<uint8_t>&& data, DataSentCallback&&);
     60    void registerDataReceivedCallback(DataReceivedCallback&&);
     61    void unregisterDataReceivedCallback();
     62
     63    void receiveReport(Vector<uint8_t>&&);
    5864
    5965protected:
    60     explicit AuthenticatorTransportService(Observer&);
    61 
    62     Observer* observer() const { return m_observer.get(); }
     66    bool m_initialized { false };
     67    bool m_terminated { false };
    6368
    6469private:
    65     virtual void startDiscoveryInternal() const = 0;
     70    void consumeReports();
    6671
    67     WeakPtr<Observer> m_observer;
     72    // Overrided by MockHidConnection.
     73    virtual void registerDataReceivedCallbackInternal();
     74
     75    RetainPtr<IOHIDDeviceRef> m_device;
     76    Vector<uint8_t> m_inputBuffer;
     77    // Could queue data requested by other applications.
     78    Deque<Vector<uint8_t>> m_inputReports;
     79    DataReceivedCallback m_inputCallback;
    6880};
    6981
    7082} // namespace WebKit
    7183
    72 #endif // ENABLE(WEB_AUTHN)
     84#endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h

    r238165 r238166  
    2626#pragma once
    2727
    28 #if ENABLE(WEB_AUTHN)
     28#if ENABLE(WEB_AUTHN) && PLATFORM(MAC)
    2929
    3030#include "AuthenticatorTransportService.h"
     31#include <IOKit/hid/IOHIDManager.h>
     32#include <wtf/UniqueRef.h>
    3133
    3234namespace WebKit {
    3335
    34 class LocalConnection;
     36class CtapHidDriver;
     37class HidConnection;
    3538
    36 class LocalService : public AuthenticatorTransportService {
     39class HidService : public AuthenticatorTransportService {
    3740public:
    38     explicit LocalService(Observer&);
     41    explicit HidService(Observer&);
     42    ~HidService();
    3943
    40     static bool isAvailable();
     44    void deviceAdded(IOHIDDeviceRef);
    4145
    4246private:
    43     void startDiscoveryInternal() const final;
    44     // Overrided by MockLocalService.
    45     virtual bool platformStartDiscovery() const;
    46     virtual UniqueRef<LocalConnection> createLocalConnection() const;
     47    void startDiscoveryInternal() final;
     48
     49    // Overrided by MockHidService.
     50    virtual void platformStartDiscovery();
     51    virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const;
     52
     53    void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info);
     54
     55    RetainPtr<IOHIDManagerRef> m_manager;
     56    // Keeping drivers alive when they are initializing authenticators.
     57    HashSet<std::unique_ptr<CtapHidDriver>> m_drivers;
    4758};
    4859
    4960} // namespace WebKit
    5061
    51 #endif // ENABLE(WEB_AUTHN)
     62#endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticationSoftLink.h

    r236481 r238166  
    2626#pragma once
    2727
     28#import <LocalAuthentication/LocalAuthentication.h>
    2829#import <wtf/SoftLinking.h>
    2930
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm

    r237266 r238166  
    3030
    3131#import "DeviceIdentitySPI.h"
    32 #import <LocalAuthentication/LocalAuthentication.h>
    3332#import <WebCore/ExceptionData.h>
    3433#import <wtf/BlockPtr.h>
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.h

    r236481 r238166  
    4141
    4242private:
    43     void startDiscoveryInternal() const final;
     43    void startDiscoveryInternal() final;
    4444    // Overrided by MockLocalService.
    4545    virtual bool platformStartDiscovery() const;
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm

    r237266 r238166  
    5757}
    5858
    59 void LocalService::startDiscoveryInternal() const
     59void LocalService::startDiscoveryInternal()
    6060{
    61     if (!platformStartDiscovery())
     61    if (!platformStartDiscovery() || !observer())
    6262        return;
    63 
    64     if (observer())
    65         observer()->authenticatorAdded(LocalAuthenticator::create(createLocalConnection()));
     63    observer()->authenticatorAdded(LocalAuthenticator::create(createLocalConnection()));
    6664}
    6765
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp

    r236842 r238166  
    4747
    4848    pendingCompletionHandler()(WTFMove(respond));
    49     clearState();
    50     requestTimeOutTimer()->stop();
     49    clearStateAsync();
     50    requestTimeOutTimer().stop();
    5151}
    5252
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockHidService.cpp

    r238165 r238166  
    2525
    2626#include "config.h"
    27 #include "MockLocalService.h"
     27#include "MockHidService.h"
    2828
    29 #if ENABLE(WEB_AUTHN)
     29#if ENABLE(WEB_AUTHN) && PLATFORM(MAC)
    3030
    31 #import "LocalAuthenticator.h"
    32 #import "MockLocalConnection.h"
    33 #import <wtf/RunLoop.h>
     31#include "MockHidConnection.h"
     32#include <wtf/RunLoop.h>
    3433
    3534namespace WebKit {
    3635
    37 MockLocalService::MockLocalService(Observer& observer, const MockWebAuthenticationConfiguration& configuration)
    38     : LocalService(observer)
     36MockHidService::MockHidService(Observer& observer, const MockWebAuthenticationConfiguration& configuration)
     37    : HidService(observer)
    3938    , m_configuration(configuration)
    4039{
    4140}
    4241
    43 bool MockLocalService::platformStartDiscovery() const
     42void MockHidService::platformStartDiscovery()
    4443{
    45     return !!m_configuration.local;
     44    if (!!m_configuration.hid)
     45        deviceAdded(nullptr);
    4646}
    4747
    48 UniqueRef<LocalConnection> MockLocalService::createLocalConnection() const
     48UniqueRef<HidConnection> MockHidService::createHidConnection(IOHIDDeviceRef device) const
    4949{
    50     return makeUniqueRef<MockLocalConnection>(m_configuration);
     50    return makeUniqueRef<MockHidConnection>(device, m_configuration);
    5151}
    5252
    5353} // namespace WebKit
    5454
    55 #endif // ENABLE(WEB_AUTHN)
     55#endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockHidService.h

    r238165 r238166  
    2626#pragma once
    2727
    28 #if ENABLE(WEB_AUTHN)
     28#if ENABLE(WEB_AUTHN) && PLATFORM(MAC)
    2929
    30 #include "AuthenticatorTransportService.h"
     30#include "HidService.h"
     31#include "MockWebAuthenticationConfiguration.h"
    3132
    3233namespace WebKit {
    3334
    34 class LocalConnection;
     35struct MockWebAuthenticationConfiguration;
    3536
    36 class LocalService : public AuthenticatorTransportService {
     37class MockHidService final : public HidService {
    3738public:
    38     explicit LocalService(Observer&);
    39 
    40     static bool isAvailable();
     39    MockHidService(Observer&, const MockWebAuthenticationConfiguration&);
    4140
    4241private:
    43     void startDiscoveryInternal() const final;
    44     // Overrided by MockLocalService.
    45     virtual bool platformStartDiscovery() const;
    46     virtual UniqueRef<LocalConnection> createLocalConnection() const;
     42    void platformStartDiscovery() final;
     43    UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const final;
     44
     45    MockWebAuthenticationConfiguration m_configuration;
    4746};
    4847
    4948} // namespace WebKit
    5049
    51 #endif // ENABLE(WEB_AUTHN)
     50#endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h

    r236481 r238166  
    3737    explicit MockLocalConnection(const MockWebAuthenticationConfiguration&);
    3838
     39private:
    3940    void getUserConsent(const String& reason, UserConsentCallback&&) const final;
    4041    void getUserConsent(const String& reason, SecAccessControlRef, UserConsentContextCallback&&) const final;
    4142    void getAttestation(const String& rpId, const String& username, const Vector<uint8_t>& hash, AttestationCallback&&) const final;
    4243
    43 private:
    4444    MockWebAuthenticationConfiguration m_configuration;
    4545};
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalService.mm

    r238165 r238166  
    2424 */
    2525
    26 #include "config.h"
    27 #include "MockLocalService.h"
     26#import "config.h"
     27#import "MockLocalService.h"
    2828
    2929#if ENABLE(WEB_AUTHN)
    3030
    31 #import "LocalAuthenticator.h"
    3231#import "MockLocalConnection.h"
    3332#import <wtf/RunLoop.h>
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h

    r236842 r238166  
    2828#if ENABLE(WEB_AUTHN)
    2929
     30#include <wtf/text/WTFString.h>
     31
    3032namespace WebKit {
    3133
     
    3941    };
    4042
     43    struct Hid {
     44        enum class Stage : bool {
     45            Info,
     46            Request
     47        };
     48
     49        enum class SubStage : bool {
     50            Init,
     51            Msg
     52        };
     53
     54        enum class Error : uint8_t {
     55            Success,
     56            DataNotSent,
     57            EmptyReport,
     58            WrongChannelId,
     59            MaliciousPayload,
     60            UnsupportedOptions
     61        };
     62
     63        String payloadBase64;
     64        Stage stage { Stage::Info };
     65        SubStage subStage { SubStage::Init };
     66        Error error { Error::Success };
     67        bool keepAlive { false };
     68        bool fastDataArrival { false };
     69        bool continueAfterErrorData { false };
     70    };
     71
    4172    bool silentFailure { false };
    4273    std::optional<Local> local;
     74    std::optional<Hid> hid;
    4375};
    4476
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidAuthenticator.h

    r238165 r238166  
    2626#pragma once
    2727
    28 #if ENABLE(WEB_AUTHN)
     28#if ENABLE(WEB_AUTHN) && PLATFORM(MAC)
    2929
    30 #include "AuthenticatorTransportService.h"
     30#include "Authenticator.h"
     31#include <WebCore/AuthenticatorGetInfoResponse.h>
    3132
    3233namespace WebKit {
    3334
    34 class LocalConnection;
     35class CtapHidDriver;
    3536
    36 class LocalService : public AuthenticatorTransportService {
     37class CtapHidAuthenticator final : public Authenticator {
    3738public:
    38     explicit LocalService(Observer&);
    39 
    40     static bool isAvailable();
     39    // FIXME(191526): Should store AuthenticatorSupportedOptions::UserVerificationAvailability.
     40    static Ref<CtapHidAuthenticator> create(std::unique_ptr<CtapHidDriver>&& driver, fido::AuthenticatorGetInfoResponse&& info)
     41    {
     42        return adoptRef(*new CtapHidAuthenticator(WTFMove(driver), WTFMove(info)));
     43    }
    4144
    4245private:
    43     void startDiscoveryInternal() const final;
    44     // Overrided by MockLocalService.
    45     virtual bool platformStartDiscovery() const;
    46     virtual UniqueRef<LocalConnection> createLocalConnection() const;
     46    explicit CtapHidAuthenticator(std::unique_ptr<CtapHidDriver>&&, fido::AuthenticatorGetInfoResponse&&);
     47
     48    void makeCredential() final;
     49    void continueMakeCredentialAfterResponseReceived(Vector<uint8_t>&&) const;
     50    void getAssertion() final;
     51    void continueGetAssertionAfterResponseReceived(Vector<uint8_t>&&) const;
     52
     53    std::unique_ptr<CtapHidDriver> m_driver;
     54    fido::AuthenticatorGetInfoResponse m_info;
    4755};
    4856
    4957} // namespace WebKit
    5058
    51 #endif // ENABLE(WEB_AUTHN)
     59#endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)
  • trunk/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm

    r237307 r238166  
    2929#if ENABLE(DATALIST_ELEMENT) && USE(APPKIT)
    3030
     31#import "WebPageProxy.h"
    3132#import <WebCore/IntRect.h>
    3233#import <pal/spi/cocoa/NSColorSPI.h>
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r238108 r238166  
    10191019                53DEA3661DDE423100E82648 /* json.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 53DEA3651DDE422E00E82648 /* json.hpp */; };
    10201020                570AB8F320AE3BD700B8BE87 /* SecKeyProxyStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 570AB8F220AE3BD700B8BE87 /* SecKeyProxyStore.h */; };
     1021                57597EB921811D9A0037F924 /* CtapHidDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 57597EB721811D9A0037F924 /* CtapHidDriver.h */; };
     1022                57597EBD218184900037F924 /* CtapHidAuthenticator.h in Headers */ = {isa = PBXBuildFile; fileRef = 57597EBB2181848F0037F924 /* CtapHidAuthenticator.h */; };
     1023                57597EBE218184900037F924 /* CtapHidAuthenticator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57597EBC2181848F0037F924 /* CtapHidAuthenticator.cpp */; };
     1024                57597EC121818BE20037F924 /* CtapHidDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57597EC021818BE20037F924 /* CtapHidDriver.cpp */; };
     1025                5772F206217DBD6A0056BF2C /* HidService.h in Headers */ = {isa = PBXBuildFile; fileRef = 5772F204217DBD6A0056BF2C /* HidService.h */; };
    10211026                578DC2982155A0020074E815 /* LocalAuthenticationSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 578DC2972155A0010074E815 /* LocalAuthenticationSoftLink.h */; };
     1027                57AC8F50217FEED90055438C /* HidConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 57AC8F4E217FEED90055438C /* HidConnection.h */; };
    10221028                57B4B46020B504AC00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B4B45E20B504AB00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h */; };
    10231029                57DCED6E2142EE5E0016B847 /* WebAuthenticatorCoordinatorMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57DCED6B2142EAE20016B847 /* WebAuthenticatorCoordinatorMessageReceiver.cpp */; };
     
    33493355                575075A720AB763600693EA9 /* WebCredentialMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCredentialMac.mm; sourceTree = "<group>"; };
    33503356                5750F32A2032D4E500389347 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
     3357                5756DD74218D104900D4EE6A /* MockHidService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockHidService.h; sourceTree = "<group>"; };
     3358                5756DD75218D104900D4EE6A /* MockHidService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MockHidService.cpp; sourceTree = "<group>"; };
     3359                5756DD76218D14A200D4EE6A /* MockHidConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockHidConnection.h; sourceTree = "<group>"; };
     3360                5756DD77218D14A200D4EE6A /* MockHidConnection.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MockHidConnection.cpp; sourceTree = "<group>"; };
     3361                57597EB721811D9A0037F924 /* CtapHidDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CtapHidDriver.h; sourceTree = "<group>"; };
     3362                57597EBB2181848F0037F924 /* CtapHidAuthenticator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CtapHidAuthenticator.h; sourceTree = "<group>"; };
     3363                57597EBC2181848F0037F924 /* CtapHidAuthenticator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CtapHidAuthenticator.cpp; sourceTree = "<group>"; };
     3364                57597EC021818BE20037F924 /* CtapHidDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CtapHidDriver.cpp; sourceTree = "<group>"; };
    33513365                5760828B2029854200116678 /* WebAuthenticatorCoordinator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAuthenticatorCoordinator.h; sourceTree = "<group>"; };
    33523366                5760828C2029854200116678 /* WebAuthenticatorCoordinator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebAuthenticatorCoordinator.cpp; sourceTree = "<group>"; };
     
    33553369                57608296202BD8BA00116678 /* WebAuthenticatorCoordinatorProxy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebAuthenticatorCoordinatorProxy.cpp; sourceTree = "<group>"; };
    33563370                57608299202BDAE200116678 /* WebAuthenticatorCoordinatorProxy.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebAuthenticatorCoordinatorProxy.messages.in; sourceTree = "<group>"; };
     3371                5772F204217DBD6A0056BF2C /* HidService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HidService.h; sourceTree = "<group>"; };
     3372                5772F205217DBD6A0056BF2C /* HidService.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HidService.mm; sourceTree = "<group>"; };
    33573373                578DC2972155A0010074E815 /* LocalAuthenticationSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalAuthenticationSoftLink.h; sourceTree = "<group>"; };
     3374                57AC8F4E217FEED90055438C /* HidConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HidConnection.h; sourceTree = "<group>"; };
     3375                57AC8F4F217FEED90055438C /* HidConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HidConnection.mm; sourceTree = "<group>"; };
    33583376                57B4B45D20B504AB00D4AD79 /* AuthenticationManagerCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AuthenticationManagerCocoa.mm; path = Authentication/cocoa/AuthenticationManagerCocoa.mm; sourceTree = "<group>"; };
    33593377                57B4B45E20B504AB00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClientCertificateAuthenticationXPCConstants.h; path = Authentication/cocoa/ClientCertificateAuthenticationXPCConstants.h; sourceTree = "<group>"; };
     
    33783396                57DCEDBE214CA01B0016B847 /* MockWebAuthenticationConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockWebAuthenticationConfiguration.h; sourceTree = "<group>"; };
    33793397                57DCEDC1214F114C0016B847 /* MockLocalService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockLocalService.h; sourceTree = "<group>"; };
    3380                 57DCEDC2214F114C0016B847 /* MockLocalService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MockLocalService.cpp; sourceTree = "<group>"; };
     3398                57DCEDC2214F114C0016B847 /* MockLocalService.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockLocalService.mm; sourceTree = "<group>"; };
    33813399                57DCEDC5214F18300016B847 /* MockLocalConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockLocalConnection.h; sourceTree = "<group>"; };
    33823400                57DCEDC6214F18300016B847 /* MockLocalConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockLocalConnection.mm; sourceTree = "<group>"; };
     
    66476665                        sourceTree = "<group>";
    66486666                };
     6667                57597EBF218184B20037F924 /* fido */ = {
     6668                        isa = PBXGroup;
     6669                        children = (
     6670                                57597EBC2181848F0037F924 /* CtapHidAuthenticator.cpp */,
     6671                                57597EBB2181848F0037F924 /* CtapHidAuthenticator.h */,
     6672                                57597EC021818BE20037F924 /* CtapHidDriver.cpp */,
     6673                                57597EB721811D9A0037F924 /* CtapHidDriver.h */,
     6674                        );
     6675                        path = fido;
     6676                        sourceTree = "<group>";
     6677                };
    66496678                5760828A202984C900116678 /* WebAuthentication */ = {
    66506679                        isa = PBXGroup;
     
    66616690                        children = (
    66626691                                57DCED9E2148F9D10016B847 /* Cocoa */,
     6692                                57597EBF218184B20037F924 /* fido */,
    66636693                                57DCEDBD214C9FA90016B847 /* Mock */,
    66646694                                57DCEDA42149E64A0016B847 /* Authenticator.cpp */,
     
    66886718                        isa = PBXGroup;
    66896719                        children = (
     6720                                57AC8F4E217FEED90055438C /* HidConnection.h */,
     6721                                57AC8F4F217FEED90055438C /* HidConnection.mm */,
     6722                                5772F204217DBD6A0056BF2C /* HidService.h */,
     6723                                5772F205217DBD6A0056BF2C /* HidService.mm */,
    66906724                                578DC2972155A0010074E815 /* LocalAuthenticationSoftLink.h */,
    66916725                                57DCEDA12149C1E20016B847 /* LocalAuthenticator.h */,
     
    67046738                                57DCEDCD214F51680016B847 /* MockAuthenticatorManager.cpp */,
    67056739                                57DCEDC9214F4E420016B847 /* MockAuthenticatorManager.h */,
     6740                                5756DD77218D14A200D4EE6A /* MockHidConnection.cpp */,
     6741                                5756DD76218D14A200D4EE6A /* MockHidConnection.h */,
     6742                                5756DD75218D104900D4EE6A /* MockHidService.cpp */,
     6743                                5756DD74218D104900D4EE6A /* MockHidService.h */,
    67066744                                57DCEDC5214F18300016B847 /* MockLocalConnection.h */,
    67076745                                57DCEDC6214F18300016B847 /* MockLocalConnection.mm */,
    6708                                 57DCEDC2214F114C0016B847 /* MockLocalService.cpp */,
    67096746                                57DCEDC1214F114C0016B847 /* MockLocalService.h */,
     6747                                57DCEDC2214F114C0016B847 /* MockLocalService.mm */,
    67106748                                57DCEDBE214CA01B0016B847 /* MockWebAuthenticationConfiguration.h */,
    67116749                        );
     
    88898927                                B878B615133428DC006888E9 /* CorrectionPanel.h in Headers */,
    88908928                                A1FB68271F6E51C100C43F9F /* CrashReporterClientSPI.h in Headers */,
     8929                                57597EBD218184900037F924 /* CtapHidAuthenticator.h in Headers */,
     8930                                57597EB921811D9A0037F924 /* CtapHidDriver.h in Headers */,
    88918931                                C55F91711C59676E0029E92D /* DataDetectionResult.h in Headers */,
    88928932                                1AC75380183BE50F0072CB15 /* DataReference.h in Headers */,
     
    89338973                                C0CE72AD1247E78D00BC0EC4 /* HandleMessage.h in Headers */,
    89348974                                1AC75A1B1B3368270056745B /* HangDetectionDisabler.h in Headers */,
     8975                                57AC8F50217FEED90055438C /* HidConnection.h in Headers */,
    89358976                                2DD5A72B1EBF09A7009BA597 /* HiddenPageThrottlingAutoIncreasesCounter.h in Headers */,
     8977                                5772F206217DBD6A0056BF2C /* HidService.h in Headers */,
    89368978                                312CC9F2215B06F100DE40CA /* HighPerformanceGPUManager.h in Headers */,
    89378979                                839A2F321E2067450039057E /* HighPerformanceGraphicsUsageSampler.h in Headers */,
     
    1063510677                                51FAEC3B1B0657680009C4E7 /* ChildProcessMessageReceiver.cpp in Sources */,
    1063610678                                2D92A77D212B6A7100F493FD /* Connection.cpp in Sources */,
     10679                                57597EBE218184900037F924 /* CtapHidAuthenticator.cpp in Sources */,
     10680                                57597EC121818BE20037F924 /* CtapHidDriver.cpp in Sources */,
    1063710681                                2D92A77E212B6A7100F493FD /* DataReference.cpp in Sources */,
    1063810682                                2D92A77F212B6A7100F493FD /* Decoder.cpp in Sources */,
  • trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h

    r237410 r238166  
    9292        }
    9393
    94         void resize(const IntSize& size)
     94        void resize(const WebCore::IntSize& size)
    9595        {
    9696            if (m_layerTreeHost.m_surface)
  • trunk/Tools/ChangeLog

    r238165 r238166  
     12018-11-13  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Support CTAP HID authenticators on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=188623
     5        <rdar://problem/43353777>
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        This patch adds support for the mock testing and entitlements to allow minibrowser to talk
     10        to hid devices.
     11
     12        * MiniBrowser/MiniBrowser.entitlements:
     13        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
     14        (WTR::TestRunner::setWebAuthenticationMockConfiguration):
     15
    1162018-11-13  Ryosuke Niwa  <rniwa@webkit.org>
    217
  • trunk/Tools/MiniBrowser/MiniBrowser.entitlements

    r234966 r238166  
    33<plist version="1.0">
    44<dict>
     5        <key>com.apple.security.device.usb</key>
     6        <true/>
    57        <key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
    68        <string>com.apple.Safari.SafeBrowsing.Service</string>
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp

    r238098 r238166  
    24322432    }
    24332433
     2434    JSRetainPtr<JSStringRef> hidPropertyName(Adopt, JSStringCreateWithUTF8CString("hid"));
     2435    JSValueRef hidValue = JSObjectGetProperty(context, configuration, hidPropertyName.get(), 0);
     2436    if (!JSValueIsUndefined(context, hidValue) && !JSValueIsNull(context, hidValue)) {
     2437        if (!JSValueIsObject(context, hidValue))
     2438            return;
     2439        JSObjectRef hid = JSValueToObject(context, hidValue, 0);
     2440
     2441        JSRetainPtr<JSStringRef> stagePropertyName(Adopt, JSStringCreateWithUTF8CString("stage"));
     2442        JSValueRef stageValue = JSObjectGetProperty(context, hid, stagePropertyName.get(), 0);
     2443        if (!JSValueIsString(context, stageValue))
     2444            return;
     2445
     2446        JSRetainPtr<JSStringRef> subStagePropertyName(Adopt, JSStringCreateWithUTF8CString("subStage"));
     2447        JSValueRef subStageValue = JSObjectGetProperty(context, hid, subStagePropertyName.get(), 0);
     2448        if (!JSValueIsString(context, subStageValue))
     2449            return;
     2450
     2451        JSRetainPtr<JSStringRef> errorPropertyName(Adopt, JSStringCreateWithUTF8CString("error"));
     2452        JSValueRef errorValue = JSObjectGetProperty(context, hid, errorPropertyName.get(), 0);
     2453        if (!JSValueIsString(context, errorValue))
     2454            return;
     2455
     2456        Vector<WKRetainPtr<WKStringRef>> hidKeys;
     2457        Vector<WKRetainPtr<WKTypeRef>> hidValues;
     2458        hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("Stage") });
     2459        hidValues.append(toWK(adopt(JSValueToStringCopy(context, stageValue, 0)).get()));
     2460        hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("SubStage") });
     2461        hidValues.append(toWK(adopt(JSValueToStringCopy(context, subStageValue, 0)).get()));
     2462        hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("Error") });
     2463        hidValues.append(toWK(adopt(JSValueToStringCopy(context, errorValue, 0)).get()));
     2464
     2465        JSRetainPtr<JSStringRef> payloadBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("payloadBase64"));
     2466        JSValueRef payloadBase64Value = JSObjectGetProperty(context, hid, payloadBase64PropertyName.get(), 0);
     2467        if (!JSValueIsUndefined(context, payloadBase64Value) && !JSValueIsNull(context, payloadBase64Value)) {
     2468            if (!JSValueIsString(context, payloadBase64Value))
     2469                return;
     2470            hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("PayloadBase64") });
     2471            hidValues.append(toWK(adopt(JSValueToStringCopy(context, payloadBase64Value, 0)).get()));
     2472        }
     2473
     2474        JSRetainPtr<JSStringRef> keepAlivePropertyName(Adopt, JSStringCreateWithUTF8CString("keepAlive"));
     2475        JSValueRef keepAliveValue = JSObjectGetProperty(context, hid, keepAlivePropertyName.get(), 0);
     2476        if (!JSValueIsUndefined(context, keepAliveValue) && !JSValueIsNull(context, keepAliveValue)) {
     2477            if (!JSValueIsBoolean(context, keepAliveValue))
     2478                return;
     2479            bool keepAlive = JSValueToBoolean(context, keepAliveValue);
     2480            hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("KeepAlive") });
     2481            hidValues.append(adoptWK(WKBooleanCreate(keepAlive)).get());
     2482        }
     2483
     2484        JSRetainPtr<JSStringRef> fastDataArrivalPropertyName(Adopt, JSStringCreateWithUTF8CString("fastDataArrival"));
     2485        JSValueRef fastDataArrivalValue = JSObjectGetProperty(context, hid, fastDataArrivalPropertyName.get(), 0);
     2486        if (!JSValueIsUndefined(context, fastDataArrivalValue) && !JSValueIsNull(context, fastDataArrivalValue)) {
     2487            if (!JSValueIsBoolean(context, fastDataArrivalValue))
     2488                return;
     2489            bool fastDataArrival = JSValueToBoolean(context, fastDataArrivalValue);
     2490            hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("FastDataArrival") });
     2491            hidValues.append(adoptWK(WKBooleanCreate(fastDataArrival)).get());
     2492        }
     2493
     2494        JSRetainPtr<JSStringRef> continueAfterErrorDataPropertyName(Adopt, JSStringCreateWithUTF8CString("continueAfterErrorData"));
     2495        JSValueRef continueAfterErrorDataValue = JSObjectGetProperty(context, hid, continueAfterErrorDataPropertyName.get(), 0);
     2496        if (!JSValueIsUndefined(context, continueAfterErrorDataValue) && !JSValueIsNull(context, continueAfterErrorDataValue)) {
     2497            if (!JSValueIsBoolean(context, continueAfterErrorDataValue))
     2498                return;
     2499            bool continueAfterErrorData = JSValueToBoolean(context, continueAfterErrorDataValue);
     2500            hidKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("ContinueAfterErrorData") });
     2501            hidValues.append(adoptWK(WKBooleanCreate(continueAfterErrorData)).get());
     2502        }
     2503
     2504        Vector<WKStringRef> rawHidKeys;
     2505        Vector<WKTypeRef> rawHidValues;
     2506        rawHidKeys.resize(hidKeys.size());
     2507        rawHidValues.resize(hidValues.size());
     2508        for (size_t i = 0; i < hidKeys.size(); ++i) {
     2509            rawHidKeys[i] = hidKeys[i].get();
     2510            rawHidValues[i] = hidValues[i].get();
     2511        }
     2512
     2513        configurationKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("Hid") });
     2514        configurationValues.append({ AdoptWK, WKDictionaryCreate(rawHidKeys.data(), rawHidValues.data(), rawHidKeys.size()) });
     2515    }
     2516
    24342517    Vector<WKStringRef> rawConfigurationKeys;
    24352518    Vector<WKTypeRef> rawConfigurationValues;
Note: See TracChangeset for help on using the changeset viewer.