Changeset 259680 in webkit


Ignore:
Timestamp:
Apr 7, 2020 4:01:20 PM (4 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthn] Cancel WebAuthn requests when users cancel LocalAuthentication prompts
https://bugs.webkit.org/show_bug.cgi?id=209923
<rdar://problem/61223713>

Reviewed by Brent Fulgham.

Source/WebCore:

Covered by new tests within existing test files.

  • testing/MockWebAuthenticationConfiguration.h:

(WebCore::MockWebAuthenticationConfiguration::LocalConfiguration::encode const):
(WebCore::MockWebAuthenticationConfiguration::LocalConfiguration::decode):

  • testing/MockWebAuthenticationConfiguration.idl:

Adds a new parameter to reflect user cancellations on LocalAuthentication UI.

Source/WebKit:

This patch intents to streamline WebAuthn local authenticator UX a bit more. Here, we should treat user
cancellation of the LocalAuthentication UI as if it were being done on the UI Client's WebAuthn UI.

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

(WebKit::AuthenticatorManager::cancelRequest):

  • UIProcess/WebAuthentication/AuthenticatorManager.h:
  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h:
  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:

(WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
(WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
(WebKit::LocalAuthenticator::validateUserVerification const):

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

(WebKit::LocalConnection::verifyUser const):

  • UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:

(WebKit::MockLocalConnection::MockLocalConnection):
(WebKit::MockLocalConnection::verifyUser const):
(WebKit::MockLocalConnection::filterResponses const):

  • WebKit.xcodeproj/project.pbxproj:

Tools:

Modifies existing tests to accommodate changes in MockWebAuthenticationConfiguration.idl.

  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-la.html:
  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-duplicate-credential.html:
  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-error.html:
  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la.html:

LayoutTests:

Adds a new test for the change and modifies existing tests to accommodate changes in MockWebAuthenticationConfiguration.idl.

  • http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html:
  • http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt:
  • http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
  • http/wpt/webauthn/public-key-credential-create-success-local.https.html:
  • http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html:
  • http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
  • http/wpt/webauthn/public-key-credential-get-success-local.https.html:
Location:
trunk
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r259678 r259680  
     12020-04-07  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cancel WebAuthn requests when users cancel LocalAuthentication prompts
     4        https://bugs.webkit.org/show_bug.cgi?id=209923
     5        <rdar://problem/61223713>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Adds a new test for the change and modifies existing tests to accommodate changes in MockWebAuthenticationConfiguration.idl.
     10
     11        * http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html:
     12        * http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt:
     13        * http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
     14        * http/wpt/webauthn/public-key-credential-create-success-local.https.html:
     15        * http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html:
     16        * http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
     17        * http/wpt/webauthn/public-key-credential-get-success-local.https.html:
     18
    1192020-04-07  Jacob Uphoff  <jacob_uphoff@apple.com>
    220
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html

    r258293 r259680  
    77    // Default mock configuration. Tests need to override if they need different configuration.
    88    if (window.internals)
    9         internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } });
     9        internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "no", acceptAttestation: false } });
    1010
    1111    promise_test(t => {
     
    127127        };
    128128        if (window.internals)
    129             internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false } });
     129            internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "yes", acceptAttestation: false } });
    130130        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
    131131    }, "PublicKeyCredential's [[create]] without private keys in a mock local authenticator.");
     
    153153        };
    154154        if (window.internals)
    155             internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false, privateKeyBase64: privateKeyBase64 } });
     155            internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "yes", acceptAttestation: false, privateKeyBase64: privateKeyBase64 } });
    156156        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
    157157            if (window.testRunner)
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt

    r258293 r259680  
    88PASS PublicKeyCredential's [[create]] not deleting old credential in a mock local authenticator.
    99PASS PublicKeyCredential's [[create]] with timeout in a mock local authenticator.
     10PASS PublicKeyCredential's [[create]] with user cancel in a mock local authenticator.
    1011
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html

    r258293 r259680  
    77    // Default mock configuration. Tests need to override if they need different configuration.
    88    if (window.internals)
    9         internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
     9        internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false } });
    1010
    1111    promise_test(t => {
     
    122122        };
    123123        if (window.internals)
    124             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
     124            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false } });
    125125        return promiseRejects(t, "UnknownError", navigator.credentials.create(options), "Couldn't create private key.");
    126126    }, "PublicKeyCredential's [[create]] without private keys in a mock local authenticator.");
     
    147147        };
    148148        if (window.internals)
    149             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, privateKeyBase64: privateKeyBase64 } });
     149            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false, privateKeyBase64: privateKeyBase64 } });
    150150        return promiseRejects(t, "UnknownError", navigator.credentials.create(options), "Couldn't attest: The operation couldn't complete.").then(() => {
    151151            if (window.testRunner)
     
    174174        };
    175175        if (window.internals) {
    176             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
     176            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false } });
    177177            testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, testUserEntityBundleBase64);
    178178        }
     
    203203
    204204        if (window.internals)
    205             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
     205            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false } });
    206206        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
    207207    }, "PublicKeyCredential's [[create]] with timeout in a mock local authenticator.");
     208
     209    promise_test(function(t) {
     210        const options = {
     211            publicKey: {
     212                rp: {
     213                    name: "example.com"
     214                },
     215                user: {
     216                    name: "John Appleseed",
     217                    id: asciiToUint8Array("123456"),
     218                    displayName: "John",
     219                },
     220                challenge: asciiToUint8Array("123456"),
     221                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
     222            }
     223        };
     224
     225        if (window.internals)
     226            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "cancel", acceptAttestation: false } });
     227        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "This request has been cancelled by the user.");
     228    }, "PublicKeyCredential's [[create]] with user cancel in a mock local authenticator.");
     229
    208230</script>
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html

    r258293 r259680  
    5353            internals.setMockWebAuthenticationConfiguration({
    5454                local: {
    55                     acceptAuthentication: true,
     55                    userVerification: "yes",
    5656                    acceptAttestation: false,
    5757                    privateKeyBase64: privateKeyBase64,
     
    8686            internals.setMockWebAuthenticationConfiguration({
    8787                local: {
    88                     acceptAuthentication: true,
     88                    userVerification: "yes",
    8989                    acceptAttestation: false,
    9090                    privateKeyBase64: privateKeyBase64,
     
    120120            internals.setMockWebAuthenticationConfiguration({
    121121                local: {
    122                     acceptAuthentication: true,
     122                    userVerification: "yes",
    123123                    acceptAttestation: false,
    124124                    privateKeyBase64: privateKeyBase64,
     
    164164            internals.setMockWebAuthenticationConfiguration({
    165165                local: {
    166                     acceptAuthentication: true,
     166                    userVerification: "yes",
    167167                    acceptAttestation: false,
    168168                    privateKeyBase64: privateKeyBase64,
     
    198198            internals.setMockWebAuthenticationConfiguration({
    199199                local: {
    200                     acceptAuthentication: true,
     200                    userVerification: "yes",
    201201                    acceptAttestation: true,
    202202                    privateKeyBase64: privateKeyBase64,
     
    234234            internals.setMockWebAuthenticationConfiguration({
    235235                local: {
    236                     acceptAuthentication: true,
     236                    userVerification: "yes",
    237237                    acceptAttestation: true,
    238238                    privateKeyBase64: privateKeyBase64,
     
    270270            internals.setMockWebAuthenticationConfiguration({
    271271                local: {
    272                     acceptAuthentication: true,
     272                    userVerification: "yes",
    273273                    acceptAttestation: false,
    274274                    privateKeyBase64: privateKeyBase64,
     
    309309            internals.setMockWebAuthenticationConfiguration({
    310310                local: {
    311                     acceptAuthentication: true,
     311                    userVerification: "yes",
    312312                    acceptAttestation: true,
    313313                    privateKeyBase64: privateKeyBase64,
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html

    r258293 r259680  
    77    promise_test(t => {
    88        if (window.internals)
    9             internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } });
     9            internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "no", acceptAttestation: false } });
    1010
    1111        const options = {
     
    3131        // Default mock configuration. Tests need to override if they need different configuration.
    3232        if (window.internals)
    33             internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     33            internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "no", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    3434
    3535        const options = {
     
    5757        // Default mock configuration. Tests need to override if they need different configuration.
    5858        if (window.internals)
    59             internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     59            internals.setMockWebAuthenticationConfiguration({ silentFailure: true, local: { userVerification: "no", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    6060
    6161        const options = {
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html

    r258293 r259680  
    77    promise_test(t => {
    88        if (window.internals)
    9             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
     9            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false } });
    1010
    1111        const options = {
     
    3030        // Default mock configuration. Tests need to override if they need different configuration.
    3131        if (window.internals)
    32             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     32            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    3333
    3434        const options = {
     
    5555        // Default mock configuration. Tests need to override if they need different configuration.
    5656        if (window.internals)
    57             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     57            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    5858
    5959        const options = {
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https.html

    r258293 r259680  
    4242        // Default mock configuration. Tests need to override if they need different configuration.
    4343        if (window.internals)
    44             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     44            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    4545
    4646        const options = {
     
    6363        // Default mock configuration. Tests need to override if they need different configuration.
    6464        if (window.internals)
    65             internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
     65            internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false, preferredCredentialIdBase64: credentialIDBase64 } });
    6666
    6767        const options = {
  • trunk/Source/WebCore/ChangeLog

    r259676 r259680  
     12020-04-07  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cancel WebAuthn requests when users cancel LocalAuthentication prompts
     4        https://bugs.webkit.org/show_bug.cgi?id=209923
     5        <rdar://problem/61223713>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Covered by new tests within existing test files.
     10
     11        * testing/MockWebAuthenticationConfiguration.h:
     12        (WebCore::MockWebAuthenticationConfiguration::LocalConfiguration::encode const):
     13        (WebCore::MockWebAuthenticationConfiguration::LocalConfiguration::decode):
     14        * testing/MockWebAuthenticationConfiguration.idl:
     15        Adds a new parameter to reflect user cancellations on LocalAuthentication UI.
     16
    1172020-04-07  Tadeu Zagallo  <tzagallo@apple.com>
    218
  • trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.h

    r258293 r259680  
    6262    };
    6363
     64    enum class UserVerification : uint8_t {
     65        No,
     66        Yes,
     67        Cancel
     68    };
     69
    6470    struct LocalConfiguration {
    65         bool acceptAuthentication { false };
     71        UserVerification userVerification { UserVerification::No };
    6672        bool acceptAttestation { false };
    6773        String privateKeyBase64;
     
    113119void MockWebAuthenticationConfiguration::LocalConfiguration::encode(Encoder& encoder) const
    114120{
    115     encoder << acceptAuthentication << acceptAttestation << privateKeyBase64 << userCertificateBase64 << intermediateCACertificateBase64 << preferredCredentialIdBase64;
     121    encoder << userVerification << acceptAttestation << privateKeyBase64 << userCertificateBase64 << intermediateCACertificateBase64 << preferredCredentialIdBase64;
    116122}
    117123
     
    121127    MockWebAuthenticationConfiguration::LocalConfiguration result;
    122128
    123     Optional<bool> acceptAuthentication;
    124     decoder >> acceptAuthentication;
    125     if (!acceptAuthentication)
    126         return WTF::nullopt;
    127     result.acceptAuthentication = *acceptAuthentication;
     129    Optional<UserVerification> userVerification;
     130    decoder >> userVerification;
     131    if (!userVerification)
     132        return WTF::nullopt;
     133    result.userVerification = *userVerification;
    128134
    129135    Optional<bool> acceptAttestation;
     
    298304};
    299305
     306template<> struct EnumTraits<WebCore::MockWebAuthenticationConfiguration::UserVerification> {
     307    using values = EnumValues<
     308        WebCore::MockWebAuthenticationConfiguration::UserVerification,
     309        WebCore::MockWebAuthenticationConfiguration::UserVerification::No,
     310        WebCore::MockWebAuthenticationConfiguration::UserVerification::Yes,
     311        WebCore::MockWebAuthenticationConfiguration::UserVerification::Cancel
     312    >;
     313};
     314
    300315} // namespace WTF
    301316
  • trunk/Source/WebCore/testing/MockWebAuthenticationConfiguration.idl

    r258293 r259680  
    6262[
    6363    Conditional=WEB_AUTHN,
     64] enum UserVerification {
     65    "no",
     66    "yes",
     67    "cancel"
     68};
     69
     70[
     71    Conditional=WEB_AUTHN,
    6472] dictionary MockWebAuthenticationConfiguration {
    6573    boolean silentFailure = false;
     
    7280    Conditional=WEB_AUTHN,
    7381] dictionary MockLocalConfiguration {
    74     boolean acceptAuthentication = false;
     82    UserVerification userVerification = "no";
    7583    boolean acceptAttestation = false;
    7684    DOMString privateKeyBase64;
  • trunk/Source/WebKit/ChangeLog

    r259679 r259680  
     12020-04-07  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cancel WebAuthn requests when users cancel LocalAuthentication prompts
     4        https://bugs.webkit.org/show_bug.cgi?id=209923
     5        <rdar://problem/61223713>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch intents to streamline WebAuthn local authenticator UX a bit more. Here, we should treat user
     10        cancellation of the LocalAuthentication UI as if it were being done on the UI Client's WebAuthn UI.
     11
     12        * UIProcess/WebAuthentication/Authenticator.h:
     13        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
     14        (WebKit::AuthenticatorManager::cancelRequest):
     15        * UIProcess/WebAuthentication/AuthenticatorManager.h:
     16        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h:
     17        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
     18        (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
     19        (WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
     20        (WebKit::LocalAuthenticator::validateUserVerification const):
     21        * UIProcess/WebAuthentication/Cocoa/LocalConnection.h:
     22        * UIProcess/WebAuthentication/Cocoa/LocalConnection.mm:
     23        (WebKit::LocalConnection::verifyUser const):
     24        * UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
     25        (WebKit::MockLocalConnection::MockLocalConnection):
     26        (WebKit::MockLocalConnection::verifyUser const):
     27        (WebKit::MockLocalConnection::filterResponses const):
     28        * WebKit.xcodeproj/project.pbxproj:
     29
    1302020-04-07  Sihui Liu  <sihui_liu@hotmail.com>
    231
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.h

    r257954 r259680  
    5858        virtual void selectAssertionResponse(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, WebAuthenticationSource, CompletionHandler<void(WebCore::AuthenticatorAssertionResponse*)>&&) = 0;
    5959        virtual void decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&&) = 0;
     60        virtual void cancelRequest() = 0;
    6061    };
    6162
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp

    r258961 r259680  
    180180            return;
    181181    }
    182     invokePendingCompletionHandler(ExceptionData { NotAllowedError, "Operation timed out."_s });
    183     clearState();
    184     m_requestTimeOutTimer.stop();
     182    cancelRequest();
    185183}
    186184
     
    193191    if (!m_pendingCompletionHandler || m_pendingRequestData.panel.get() != &panel)
    194192        return;
    195     invokePendingCompletionHandler(ExceptionData { NotAllowedError, "This request has been cancelled by the user."_s });
    196     clearState();
    197     m_requestTimeOutTimer.stop();
     193    cancelRequest();
    198194}
    199195
     
    294290        panel.client().decidePolicyForLocalAuthenticator(WTFMove(completionHandler));
    295291    });
     292}
     293
     294void AuthenticatorManager::cancelRequest()
     295{
     296    invokePendingCompletionHandler(ExceptionData { NotAllowedError, "This request has been cancelled by the user."_s });
     297    clearState();
     298    m_requestTimeOutTimer.stop();
    296299}
    297300
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h

    r257954 r259680  
    8585    void selectAssertionResponse(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, WebAuthenticationSource, CompletionHandler<void(WebCore::AuthenticatorAssertionResponse*)>&&) final;
    8686    void decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&&) final;
     87    void cancelRequest() final;
    8788
    8889    // Overriden by MockAuthenticatorManager.
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h

    r258293 r259680  
    6969    void receiveException(WebCore::ExceptionData&&, WebAuthenticationStatus = WebAuthenticationStatus::LAError) const;
    7070    void deleteDuplicateCredential() const;
     71    bool validateUserVerification(LocalConnection::UserVerification) const;
    7172
    7273    State m_state { State::Init };
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm

    r258961 r259680  
    275275    auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options);
    276276
    277     if (verification == LocalConnection::UserVerification::No) {
    278         receiveException({ NotAllowedError, "Couldn't verify user."_s });
    279         return;
    280     }
     277    if (!validateUserVerification(verification))
     278        return;
    281279
    282280    // Here is the keychain schema.
     
    501499    m_state = State::UserVerified;
    502500
    503     if (verification == LocalConnection::UserVerification::No) {
    504         receiveException({ NotAllowedError, "Couldn't verify user."_s });
    505         return;
    506     }
     501    if (!validateUserVerification(verification))
     502        return;
    507503
    508504    // Step 10.
     
    589585}
    590586
     587bool LocalAuthenticator::validateUserVerification(LocalConnection::UserVerification verification) const
     588{
     589    if (verification == LocalConnection::UserVerification::Cancel) {
     590        if (auto* observer = this->observer())
     591            observer->cancelRequest();
     592        return false;
     593    }
     594
     595    if (verification == LocalConnection::UserVerification::No) {
     596        receiveException({ NotAllowedError, "Couldn't verify user."_s });
     597        return false;
     598    }
     599
     600    return true;
     601}
     602
    591603} // namespace WebKit
    592604
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.h

    r258961 r259680  
    5252    WTF_MAKE_NONCOPYABLE(LocalConnection);
    5353public:
    54     enum class UserVerification : bool {
     54    enum class UserVerification : uint8_t {
    5555        No,
    56         Yes
     56        Yes,
     57        Cancel
    5758    };
    5859
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm

    r258961 r259680  
    8484            LOG_ERROR("Couldn't authenticate with biometrics: %@", error);
    8585            verification = UserVerification::No;
     86            if (error.code == LAErrorUserCancel)
     87                verification = UserVerification::Cancel;
    8688        }
    8789        RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), verification, context = WTFMove(context)] () mutable {
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm

    r258961 r259680  
    3939
    4040namespace WebKit {
     41using namespace WebCore;
    4142
    42 MockLocalConnection::MockLocalConnection(const WebCore::MockWebAuthenticationConfiguration& configuration)
     43MockLocalConnection::MockLocalConnection(const MockWebAuthenticationConfiguration& configuration)
    4344    : m_configuration(configuration)
    4445{
    4546}
    4647
    47 void MockLocalConnection::verifyUser(const String&, WebCore::ClientDataType, SecAccessControlRef, UserVerificationCallback&& callback) const
     48void MockLocalConnection::verifyUser(const String&, ClientDataType, SecAccessControlRef, UserVerificationCallback&& callback) const
    4849{
    4950    // Mock async operations.
    5051    RunLoop::main().dispatch([configuration = m_configuration, callback = WTFMove(callback)]() mutable {
    5152        ASSERT(configuration.local);
    52         if (!configuration.local->acceptAuthentication) {
    53             callback(UserVerification::No, nil);
    54             return;
     53
     54        UserVerification userVerification = UserVerification::No;
     55        switch (configuration.local->userVerification) {
     56        case MockWebAuthenticationConfiguration::UserVerification::No:
     57            break;
     58        case MockWebAuthenticationConfiguration::UserVerification::Yes:
     59            userVerification = UserVerification::Yes;
     60            break;
     61        case MockWebAuthenticationConfiguration::UserVerification::Cancel:
     62            userVerification = UserVerification::Cancel;
    5563        }
    56         callback(UserVerification::Yes, adoptNS([allocLAContextInstance() init]).get());
     64
     65        callback(userVerification, adoptNS([allocLAContextInstance() init]).get());
    5766    });
    5867}
     
    114123}
    115124
    116 void MockLocalConnection::filterResponses(HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>& responses) const
     125void MockLocalConnection::filterResponses(HashSet<Ref<AuthenticatorAssertionResponse>>& responses) const
    117126{
    118127    const auto& preferredCredentialIdBase64 = m_configuration.local->preferredCredentialIdBase64;
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r259674 r259680  
    39033903                57B8E3D62355864A00D5C5D1 /* FidoAuthenticator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FidoAuthenticator.cpp; sourceTree = "<group>"; };
    39043904                57BBEA6C22BC0BFE00273995 /* SOAuthorizationLoadPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOAuthorizationLoadPolicy.h; sourceTree = "<group>"; };
     3905                57C3E8AC242490D5001E2209 /* WebAuthenticationRequestData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebAuthenticationRequestData.cpp; sourceTree = "<group>"; };
    39053906                57C6244A234679A400383FE7 /* WebAuthenticationFlags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAuthenticationFlags.h; sourceTree = "<group>"; };
    39063907                57DCED6A2142EAE20016B847 /* WebAuthenticatorCoordinatorMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAuthenticatorCoordinatorMessages.h; path = DerivedSources/WebKit2/WebAuthenticatorCoordinatorMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
     
    80668067                                57DCED8A214853130016B847 /* AuthenticatorTransportService.h */,
    80678068                                57C6244A234679A400383FE7 /* WebAuthenticationFlags.h */,
     8069                                57C3E8AC242490D5001E2209 /* WebAuthenticationRequestData.cpp */,
    80688070                                57DCEDA62149F9DA0016B847 /* WebAuthenticationRequestData.h */,
    80698071                                57608296202BD8BA00116678 /* WebAuthenticatorCoordinatorProxy.cpp */,
  • trunk/Tools/ChangeLog

    r259675 r259680  
     12020-04-07  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Cancel WebAuthn requests when users cancel LocalAuthentication prompts
     4        https://bugs.webkit.org/show_bug.cgi?id=209923
     5        <rdar://problem/61223713>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Modifies existing tests to accommodate changes in MockWebAuthenticationConfiguration.idl.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-la.html:
     12        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-duplicate-credential.html:
     13        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-error.html:
     14        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la.html:
     15
    1162020-04-07  Ryan Haddad  <ryanhaddad@apple.com>
    217
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-la.html

    r257954 r259680  
    22<script>
    33    if (window.internals) {
    4         internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
     4        internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "yes", acceptAttestation: false } });
    55        internals.withUserGesture(() => { input.focus(); });
    66    }
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-duplicate-credential.html

    r257269 r259680  
    1919
    2020    if (window.internals) {
    21         internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
     21        internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false } });
    2222        internals.withUserGesture(() => { input.focus(); });
    2323    }
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la-error.html

    r257269 r259680  
    22<script>
    33    if (window.internals) {
    4         internals.setMockWebAuthenticationConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
     4        internals.setMockWebAuthenticationConfiguration({ local: { userVerification: "no", acceptAttestation: false } });
    55        internals.withUserGesture(() => { input.focus(); });
    66    }
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-la.html

    r257269 r259680  
    3333        internals.setMockWebAuthenticationConfiguration({
    3434            local: {
    35                 acceptAuthentication: true,
     35                userVerification: "yes",
    3636                acceptAttestation: true,
    3737                privateKeyBase64: testES256PrivateKeyBase64,
Note: See TracChangeset for help on using the changeset viewer.