Changeset 291176 in webkit


Ignore:
Timestamp:
Mar 11, 2022 9:49:14 AM (4 months ago)
Author:
J Pascoe
Message:

[WebAuthn] Support authenticatorSelection.residentKey ResidentKeyRequirement
https://bugs.webkit.org/show_bug.cgi?id=237567
rdar://89788378

Reviewed by Brent Fulgham and Chris Dumez.

Source/WebCore:

In Web Authentication level one, relying parties can specify authenticatorSelection.residentKeyRequired,
to signify they require a client-side discoverable credential. However, if the authenticator does not
support client-side discoverable credentials, the rp has no way to clarify they want a client-side
discoverable credential only if available.

This patch implements authenticatorSelection.residentKeyRequired introduced in level 2, which has three
values 'Preferred', 'Required', and 'Discouraged'. This allows RPs to create a client-side discoverable
credential if possible.

  • CMakeLists.txt:
  • DerivedSources-input.xcfilelist:
  • DerivedSources-output.xcfilelist:
  • DerivedSources.make:
  • Modules/webauthn/PublicKeyCredentialCreationOptions.h:

(WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria::encode const):
(WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria::decode):

  • Modules/webauthn/PublicKeyCredentialCreationOptions.idl:
  • Modules/webauthn/ResidentKeyRequirement.h: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
  • Modules/webauthn/ResidentKeyRequirement.idl: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
  • Modules/webauthn/fido/AuthenticatorSupportedOptions.cpp:

(fido::AuthenticatorSupportedOptions::setResidentKeyAvailability):
(fido::convertToCBOR):
(fido::AuthenticatorSupportedOptions::setSupportsResidentKey): Deleted.

  • Modules/webauthn/fido/AuthenticatorSupportedOptions.h:
  • Modules/webauthn/fido/DeviceRequestConverter.cpp:

(fido::encodeMakeCredenitalRequestAsCBOR):

  • Modules/webauthn/fido/DeviceRequestConverter.h:
  • Modules/webauthn/fido/DeviceResponseConverter.cpp:

(fido::readCTAPGetInfoResponse):

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:

Source/WebKit:

In Web Authentication level one, relying parties can specify authenticatorSelection.residentKeyRequired,
to signify they require a client-side discoverable credential. However, if the authenticator does not
support client-side discoverable credentials, the rp has no way to clarify they want a client-side
discoverable credential only if available.

This patch implements authenticatorSelection.residentKeyRequired introduced in level 2, which has three
values 'Preferred', 'Required', and 'Discouraged'. This allows RPs to create a client-side discoverable
credential if possible.

  • UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.h:
  • UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm:

(-[_WKAuthenticatorSelectionCriteria init]):

  • UIProcess/API/Cocoa/_WKResidentKeyRequirement.h: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
  • UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:

(residentKey):
(authenticatorSelectionCriteria):
(+[_WKWebAuthenticationPanel encodeMakeCredentialCommandWithClientDataJSON:options:userVerificationAvailability:]):
(+[_WKWebAuthenticationPanel encodeMakeCredentialCommandWithClientDataHash:options:userVerificationAvailability:]):

  • UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:

(WebKit::CtapAuthenticator::makeCredential):

  • WebKit.xcodeproj/project.pbxproj:

Tools:

Add API tests for authenticatorSelection.residentKey.

  • TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp:

(TestWebKitAPI::TEST):

  • TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:

(TestWebKitAPI::TEST):

LayoutTests:

Add layout tests using residentKey field.

  • http/wpt/webauthn/public-key-credential-create-failure-hid.https-expected.txt:
  • http/wpt/webauthn/public-key-credential-create-failure-hid.https.html:
  • http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt:
  • http/wpt/webauthn/public-key-credential-create-success-hid.https.html:
Location:
trunk
Files:
28 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r291173 r291176  
     12022-03-11  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Support authenticatorSelection.residentKey ResidentKeyRequirement
     4        https://bugs.webkit.org/show_bug.cgi?id=237567
     5        rdar://89788378
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        Add layout tests using residentKey field.
     10
     11        * http/wpt/webauthn/public-key-credential-create-failure-hid.https-expected.txt:
     12        * http/wpt/webauthn/public-key-credential-create-failure-hid.https.html:
     13        * http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt:
     14        * http/wpt/webauthn/public-key-credential-create-success-hid.https.html:
     15
    1162022-03-11  Don Olmstead  <don.olmstead@sony.com>
    217
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-hid.https-expected.txt

    r286785 r291176  
     1CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
    12CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
    23CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
     
    89PASS PublicKeyCredential's [[create]] with malicious payload in a mock hid authenticator.
    910PASS PublicKeyCredential's [[create]] with unsupported options in a mock hid authenticator.
     11PASS PublicKeyCredential's [[create]] with unsupported options in a mock hid authenticator. 2
    1012PASS PublicKeyCredential's [[create]] with mixed options in a mock hid authenticator.
    1113PASS PublicKeyCredential's [[create]] with mixed options in a mock hid authenticator. 2
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-hid.https.html

    r272345 r291176  
    8686                challenge: asciiToUint8Array("123456"),
    8787                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
     88                authenticatorSelection: { residentKey: "required" }
     89            }
     90        };
     91
     92        if (window.internals)
     93            internals.setMockWebAuthenticationConfiguration({ hid: { stage: "request", subStage: "msg", error: "unsupported-options" } });
     94        return promiseRejects(t, "UnknownError", navigator.credentials.create(options), "Unknown internal error. Error code: 43");
     95    }, "PublicKeyCredential's [[create]] with unsupported options in a mock hid authenticator. 2");
     96
     97    promise_test(function(t) {
     98        const options = {
     99            publicKey: {
     100                rp: {
     101                    name: "example.com"
     102                },
     103                user: {
     104                    name: "John Appleseed",
     105                    id: asciiToUint8Array("123456"),
     106                    displayName: "John",
     107                },
     108                challenge: asciiToUint8Array("123456"),
     109                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    88110                timeout: 10,
    89111                authenticatorSelection: { authenticatorAttachment: "platform", requireResidentKey: true, userVerification: "required" }
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt

    r290515 r291176  
     1CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
     2CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
     3CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
    14CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
    25CONSOLE MESSAGE: User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events.
     
    1720PASS PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock hid authenticator.
    1821PASS PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock hid authenticator.
     22PASS PublicKeyCredential's [[create]] with residentKey { Discouraged } in a mock hid authenticator.
     23PASS PublicKeyCredential's [[create]] with residentKey { Preferred } in a mock hid authenticator.
     24PASS PublicKeyCredential's [[create]] with residentKey { Required } in a mock hid authenticator.
    1925PASS PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock hid authenticator.
    2026PASS PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock hid authenticator.
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html

    r290515 r291176  
    113113                challenge: Base64URL.parse("MTIzNDU2"),
    114114                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
     115                authenticatorSelection: { residentKey: "discouraged" },
     116                timeout: 100
     117            }
     118        };
     119
     120        return navigator.credentials.create(options).then(credential => {
     121            checkCtapMakeCredentialResult(credential);
     122        });
     123    }, "PublicKeyCredential's [[create]] with residentKey { Discouraged } in a mock hid authenticator.");
     124
     125    promise_test(t => {
     126        const options = {
     127            publicKey: {
     128                rp: {
     129                    name: "localhost",
     130                },
     131                user: {
     132                    name: "John Appleseed",
     133                    id: Base64URL.parse(testUserhandleBase64),
     134                    displayName: "Appleseed",
     135                },
     136                challenge: Base64URL.parse("MTIzNDU2"),
     137                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
     138                authenticatorSelection: { residentKey: "preferred" },
     139                timeout: 100
     140            }
     141        };
     142
     143        return navigator.credentials.create(options).then(credential => {
     144            checkCtapMakeCredentialResult(credential);
     145        });
     146    }, "PublicKeyCredential's [[create]] with residentKey { Preferred } in a mock hid authenticator.");
     147
     148    promise_test(t => {
     149        const options = {
     150            publicKey: {
     151                rp: {
     152                    name: "localhost",
     153                },
     154                user: {
     155                    name: "John Appleseed",
     156                    id: Base64URL.parse(testUserhandleBase64),
     157                    displayName: "Appleseed",
     158                },
     159                challenge: Base64URL.parse("MTIzNDU2"),
     160                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
     161                authenticatorSelection: { residentKey: "required" },
     162                timeout: 100
     163            }
     164        };
     165
     166        return navigator.credentials.create(options).then(credential => {
     167            checkCtapMakeCredentialResult(credential);
     168        });
     169    }, "PublicKeyCredential's [[create]] with residentKey { Required } in a mock hid authenticator.");
     170
     171    promise_test(t => {
     172        const options = {
     173            publicKey: {
     174                rp: {
     175                    name: "localhost",
     176                },
     177                user: {
     178                    name: "John Appleseed",
     179                    id: Base64URL.parse(testUserhandleBase64),
     180                    displayName: "Appleseed",
     181                },
     182                challenge: Base64URL.parse("MTIzNDU2"),
     183                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    115184                authenticatorSelection: { userVerification: "preferred" },
    116185                timeout: 100
  • trunk/Source/WebCore/CMakeLists.txt

    r291144 r291176  
    666666    Modules/webauthn/PublicKeyCredentialRequestOptions.idl
    667667    Modules/webauthn/PublicKeyCredentialType.idl
     668    Modules/webauthn/ResidentKeyRequirement.idl
    668669    Modules/webauthn/UserVerificationRequirement.idl
    669670
  • trunk/Source/WebCore/ChangeLog

    r291175 r291176  
     12022-03-11  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Support authenticatorSelection.residentKey ResidentKeyRequirement
     4        https://bugs.webkit.org/show_bug.cgi?id=237567
     5        rdar://89788378
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        In Web Authentication level one, relying parties can specify authenticatorSelection.residentKeyRequired,
     10        to signify they require a client-side discoverable credential. However, if the authenticator does not
     11        support client-side discoverable credentials, the rp has no way to clarify they want a client-side
     12        discoverable credential only if available.
     13
     14        This patch implements authenticatorSelection.residentKeyRequired introduced in level 2, which has three
     15        values 'Preferred', 'Required', and 'Discouraged'. This allows RPs to create a client-side discoverable
     16        credential if possible.
     17
     18        * CMakeLists.txt:
     19        * DerivedSources-input.xcfilelist:
     20        * DerivedSources-output.xcfilelist:
     21        * DerivedSources.make:
     22        * Modules/webauthn/PublicKeyCredentialCreationOptions.h:
     23        (WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria::encode const):
     24        (WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria::decode):
     25        * Modules/webauthn/PublicKeyCredentialCreationOptions.idl:
     26        * Modules/webauthn/ResidentKeyRequirement.h: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
     27        * Modules/webauthn/ResidentKeyRequirement.idl: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
     28        * Modules/webauthn/fido/AuthenticatorSupportedOptions.cpp:
     29        (fido::AuthenticatorSupportedOptions::setResidentKeyAvailability):
     30        (fido::convertToCBOR):
     31        (fido::AuthenticatorSupportedOptions::setSupportsResidentKey): Deleted.
     32        * Modules/webauthn/fido/AuthenticatorSupportedOptions.h:
     33        * Modules/webauthn/fido/DeviceRequestConverter.cpp:
     34        (fido::encodeMakeCredenitalRequestAsCBOR):
     35        * Modules/webauthn/fido/DeviceRequestConverter.h:
     36        * Modules/webauthn/fido/DeviceResponseConverter.cpp:
     37        (fido::readCTAPGetInfoResponse):
     38        * Sources.txt:
     39        * WebCore.xcodeproj/project.pbxproj:
     40
    1412022-03-11  Ben Nham  <nham@apple.com>
    242
  • trunk/Source/WebCore/DerivedSources-input.xcfilelist

    r291144 r291176  
    752752$(PROJECT_DIR)/Modules/webauthn/PublicKeyCredentialRequestOptions.idl
    753753$(PROJECT_DIR)/Modules/webauthn/PublicKeyCredentialType.idl
     754$(PROJECT_DIR)/Modules/webauthn/ResidentKeyRequirement.idl
    754755$(PROJECT_DIR)/Modules/webauthn/UserVerificationRequirement.idl
    755756$(PROJECT_DIR)/Modules/webcodecs/VideoColorPrimaries.idl
  • trunk/Source/WebCore/DerivedSources-output.xcfilelist

    r291144 r291176  
    21162116$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRequestCookieConsentOptions.cpp
    21172117$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSRequestCookieConsentOptions.h
     2118$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSResidentKeyRequirement.cpp
     2119$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSResidentKeyRequirement.h
    21182120$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSResizeObserver.cpp
    21192121$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSResizeObserver.h
  • trunk/Source/WebCore/DerivedSources.make

    r291144 r291176  
    648648    $(WebCore)/Modules/webauthn/PublicKeyCredentialRequestOptions.idl \
    649649    $(WebCore)/Modules/webauthn/PublicKeyCredentialType.idl \
     650    $(WebCore)/Modules/webauthn/ResidentKeyRequirement.idl \
    650651    $(WebCore)/Modules/webauthn/UserVerificationRequirement.idl \
    651652        $(WebCore)/Modules/webcodecs/VideoColorPrimaries.idl \
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h

    r290515 r291176  
    3232#include "PublicKeyCredentialDescriptor.h"
    3333#include "PublicKeyCredentialType.h"
     34#include "ResidentKeyRequirement.h"
    3435#include "UserVerificationRequirement.h"
    3536#include <wtf/Forward.h>
     
    6667    struct AuthenticatorSelectionCriteria {
    6768        std::optional<AuthenticatorAttachment> authenticatorAttachment;
     69        // residentKey replaces requireResidentKey, see: https://www.w3.org/TR/webauthn-2/#dictionary-authenticatorSelection
     70        std::optional<ResidentKeyRequirement> residentKey;
    6871        bool requireResidentKey { false };
    6972        UserVerificationRequirement userVerification { UserVerificationRequirement::Preferred };
     
    111114void PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria::encode(Encoder& encoder) const
    112115{
    113     encoder << authenticatorAttachment << requireResidentKey << userVerification;
     116    encoder << authenticatorAttachment << requireResidentKey << userVerification << residentKey;
    114117}
    115118
     
    133136    if (!decoder.decode(result.userVerification))
    134137        return std::nullopt;
     138
     139    std::optional<std::optional<ResidentKeyRequirement>> residentKey;
     140    decoder >> residentKey;
     141    if (!residentKey)
     142        return std::nullopt;
     143    result.residentKey = *residentKey;
     144
    135145    return result;
    136146}
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.idl

    r274894 r291176  
    7373] dictionary AuthenticatorSelectionCriteria {
    7474    AuthenticatorAttachment      authenticatorAttachment;
     75    ResidentKeyRequirement       residentKey;
    7576    boolean                      requireResidentKey = false;
    7677    UserVerificationRequirement  userVerification = "preferred";
  • trunk/Source/WebCore/Modules/webauthn/ResidentKeyRequirement.h

    r291175 r291176  
    11/*
    2  * Copyright (C) 2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "_WKAuthenticatorSelectionCriteria.h"
     26#pragma once
    2827
    29 @implementation _WKAuthenticatorSelectionCriteria
     28#if ENABLE(WEB_AUTHN)
    3029
    31 - (instancetype)init
    32 {
    33     if (!(self = [super init]))
    34         return nil;
     30#include <wtf/EnumTraits.h>
    3531
    36     self.authenticatorAttachment = _WKAuthenticatorAttachmentAll;
    37     self.requireResidentKey = NO;
    38     self.userVerification = _WKUserVerificationRequirementPreferred;
    39     return self;
    40 }
     32namespace WebCore {
    4133
    42 @end
     34enum class ResidentKeyRequirement : uint8_t {
     35    Required,
     36    Preferred,
     37    Discouraged
     38};
     39
     40} // namespace WebCore
     41
     42namespace WTF {
     43
     44template<> struct EnumTraits<WebCore::ResidentKeyRequirement> {
     45    using values = EnumValues<
     46        WebCore::ResidentKeyRequirement,
     47        WebCore::ResidentKeyRequirement::Required,
     48        WebCore::ResidentKeyRequirement::Preferred,
     49        WebCore::ResidentKeyRequirement::Discouraged
     50    >;
     51};
     52
     53} // namespace WTF
     54
     55#endif // ENABLE(WEB_AUTHN)
  • trunk/Source/WebCore/Modules/webauthn/ResidentKeyRequirement.idl

    r291175 r291176  
    11/*
    2  * Copyright (C) 2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "_WKAuthenticatorSelectionCriteria.h"
    28 
    29 @implementation _WKAuthenticatorSelectionCriteria
    30 
    31 - (instancetype)init
    32 {
    33     if (!(self = [super init]))
    34         return nil;
    35 
    36     self.authenticatorAttachment = _WKAuthenticatorAttachmentAll;
    37     self.requireResidentKey = NO;
    38     self.userVerification = _WKUserVerificationRequirementPreferred;
    39     return self;
    40 }
    41 
    42 @end
     26[
     27    Conditional=WEB_AUTHN,
     28    ImplementedAs=ResidentKeyRequirement
     29] enum ResidentKeyRequirement {
     30    "required",
     31    "preferred",
     32    "discouraged"
     33};
  • trunk/Source/WebCore/Modules/webauthn/fido/AuthenticatorSupportedOptions.cpp

    r237983 r291176  
    3737namespace fido {
    3838
    39 AuthenticatorSupportedOptions& AuthenticatorSupportedOptions::setSupportsResidentKey(bool supportsResidentKey)
     39AuthenticatorSupportedOptions& AuthenticatorSupportedOptions::setResidentKeyAvailability(ResidentKeyAvailability residentKeyAvailability)
    4040{
    41     m_supportsResidentKey = supportsResidentKey;
     41    m_residentKeyAvailability = residentKeyAvailability;
    4242    return *this;
    4343}
     
    7272
    7373    CBORValue::MapValue optionMap;
    74     optionMap.emplace(CBORValue(kResidentKeyMapKey), CBORValue(options.supportsResidentKey()));
     74    optionMap.emplace(CBORValue(kResidentKeyMapKey), CBORValue(options.residentKeyAvailability() == AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported));
    7575    optionMap.emplace(CBORValue(kUserPresenceMapKey), CBORValue(options.userPresenceRequired()));
    7676    optionMap.emplace(CBORValue(kPlatformDeviceMapKey), CBORValue(options.isPlatformDevice()));
  • trunk/Source/WebCore/Modules/webauthn/fido/AuthenticatorSupportedOptions.h

    r237983 r291176  
    5252    };
    5353
     54    enum class ResidentKeyAvailability : bool {
     55        kSupported,
     56        kNotSupported
     57    };
     58
    5459    enum class ClientPinAvailability {
    5560        kSupportedAndPinSet,
     
    6368
    6469    AuthenticatorSupportedOptions& setIsPlatformDevice(bool);
    65     AuthenticatorSupportedOptions& setSupportsResidentKey(bool);
     70    AuthenticatorSupportedOptions& setResidentKeyAvailability(ResidentKeyAvailability);
    6671    AuthenticatorSupportedOptions& setUserVerificationAvailability(UserVerificationAvailability);
    6772    AuthenticatorSupportedOptions& setUserPresenceRequired(bool);
     
    6974
    7075    bool isPlatformDevice() const { return m_isPlatformDevice; }
    71     bool supportsResidentKey() const { return m_supportsResidentKey; }
    72     UserVerificationAvailability userVerificationAvailability() const { return m_userVerificationAvailability; }
     76    ResidentKeyAvailability residentKeyAvailability() const { return m_residentKeyAvailability; };
     77    UserVerificationAvailability userVerificationAvailability() const { return m_userVerificationAvailability; };
    7378    bool userPresenceRequired() const { return m_userPresenceRequired; }
    7479    ClientPinAvailability clientPinAvailability() const { return m_clientPinAvailability; }
     
    8186    // and therefore can satisfy the authenticatorGetAssertion request with
    8287    // allowList parameter not specified or empty.
    83     bool m_supportsResidentKey { false };
     88    ResidentKeyAvailability m_residentKeyAvailability { ResidentKeyAvailability::kNotSupported };
    8489    // Indicates whether the device is capable of verifying the user on its own.
    8590    UserVerificationAvailability m_userVerificationAvailability { UserVerificationAvailability::kNotSupported };
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceRequestConverter.cpp

    r290026 r291176  
    3636#include "PublicKeyCredentialCreationOptions.h"
    3737#include "PublicKeyCredentialRequestOptions.h"
     38#include "ResidentKeyRequirement.h"
    3839#include <wtf/Vector.h>
    3940
     
    8687}
    8788
    88 Vector<uint8_t> encodeMakeCredenitalRequestAsCBOR(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions& options, UVAvailability uvCapability, std::optional<PinParameters> pin)
     89Vector<uint8_t> encodeMakeCredenitalRequestAsCBOR(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions& options, UVAvailability uvCapability, AuthenticatorSupportedOptions::ResidentKeyAvailability residentKeyAvailability, std::optional<PinParameters> pin)
    8990{
    9091    CBORValue::MapValue cborMap;
     
    103104    if (options.authenticatorSelection) {
    104105        // Resident keys are not supported by default.
    105         if (options.authenticatorSelection->requireResidentKey)
     106        if (options.authenticatorSelection->residentKey) {
     107            if (*options.authenticatorSelection->residentKey == ResidentKeyRequirement::Required
     108                || (*options.authenticatorSelection->residentKey == ResidentKeyRequirement::Preferred && residentKeyAvailability == AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported))
     109                optionMap[CBORValue(kResidentKeyMapKey)] = CBORValue(true);
     110        } else if (options.authenticatorSelection->requireResidentKey)
    106111            optionMap[CBORValue(kResidentKeyMapKey)] = CBORValue(true);
    107112
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceRequestConverter.h

    r278185 r291176  
    5151// integer keys and CBOR encoded values as defined by the CTAP spec.
    5252// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#authenticatorMakeCredential
    53 WEBCORE_EXPORT Vector<uint8_t> encodeMakeCredenitalRequestAsCBOR(const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialCreationOptions&, AuthenticatorSupportedOptions::UserVerificationAvailability, std::optional<PinParameters> = std::nullopt);
     53WEBCORE_EXPORT Vector<uint8_t> encodeMakeCredenitalRequestAsCBOR(const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialCreationOptions&, AuthenticatorSupportedOptions::UserVerificationAvailability, AuthenticatorSupportedOptions::ResidentKeyAvailability, std::optional<PinParameters> = std::nullopt);
    5454
    5555// Serializes GetAssertion request parameter into CBOR encoded map with
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp

    r278358 r291176  
    265265            if (!optionMapIt->second.isBool())
    266266                return std::nullopt;
    267 
    268             options.setSupportsResidentKey(optionMapIt->second.getBool());
     267            if (optionMapIt->second.getBool())
     268                options.setResidentKeyAvailability(AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
     269            else
     270                options.setResidentKeyAvailability(AuthenticatorSupportedOptions::ResidentKeyAvailability::kNotSupported);
    269271        }
    270272
  • trunk/Source/WebCore/Sources.txt

    r291144 r291176  
    37023702JSRequestAnimationFrameCallback.cpp
    37033703JSRequestCookieConsentOptions.cpp
     3704JSResidentKeyRequirement.cpp
    37043705JSResizeObserver.cpp
    37053706JSResizeObserverBoxOptions.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r291144 r291176  
    17301730                51FB5504113E3E9100821176 /* JSCloseEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FB5502113E3E9100821176 /* JSCloseEvent.h */; };
    17311731                51FB67DC1AE6B82F00D06C5A /* ContentExtensionStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FB67DA1AE6B5E400D06C5A /* ContentExtensionStyleSheet.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1732                52688AA627D6A7DA003577A2 /* ResidentKeyRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = 52688AA327D6A7DA003577A2 /* ResidentKeyRequirement.h */; settings = {ATTRIBUTES = (Private, ); }; };
    17321733                5273CC77256103CF00850007 /* PlatformXRCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 5273CC75256103CF00850007 /* PlatformXRCocoa.h */; };
    17331734                5273CC8E25637EB500850007 /* WebXRTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18D83E0243F71CE009247D6 /* WebXRTest.cpp */; };
     
    1006710068                526724F11CB2FDF60075974D /* TextTrackRepresentationCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextTrackRepresentationCocoa.mm; sourceTree = "<group>"; };
    1006810069                526724F21CB2FDF60075974D /* TextTrackRepresentationCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentationCocoa.h; sourceTree = "<group>"; };
     10070                52688AA327D6A7DA003577A2 /* ResidentKeyRequirement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ResidentKeyRequirement.h; sourceTree = "<group>"; };
     10071                52688AA527D6A7DA003577A2 /* ResidentKeyRequirement.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ResidentKeyRequirement.idl; sourceTree = "<group>"; };
    1006910072                5273CC74256103CF00850007 /* PlatformXRCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformXRCocoa.mm; sourceTree = "<group>"; };
    1007010073                5273CC75256103CF00850007 /* PlatformXRCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformXRCocoa.h; sourceTree = "<group>"; };
     
    2331523318                                57303BEA20097F4000355965 /* PublicKeyCredentialType.h */,
    2331623319                                57303BF02009846100355965 /* PublicKeyCredentialType.idl */,
     23320                                52688AA327D6A7DA003577A2 /* ResidentKeyRequirement.h */,
     23321                                52688AA527D6A7DA003577A2 /* ResidentKeyRequirement.idl */,
    2331723322                                572B402321768D85000AD43E /* UserVerificationRequirement.h */,
    2331823323                                572B402521768D85000AD43E /* UserVerificationRequirement.idl */,
     
    3706337068                                F4034FAC275EAD6E003A81F8 /* RequestCookieConsentOptions.h in Headers */,
    3706437069                                F55B3DD01251F12D003EF269 /* ResetInputType.h in Headers */,
     37070                                52688AA627D6A7DA003577A2 /* ResidentKeyRequirement.h in Headers */,
    3706537071                                58B2F9F42232D45300938D63 /* ResizeObservation.h in Headers */,
    3706637072                                58B2F9F52232D45800938D63 /* ResizeObserver.h in Headers */,
  • trunk/Source/WebKit/ChangeLog

    r291174 r291176  
     12022-03-11  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Support authenticatorSelection.residentKey ResidentKeyRequirement
     4        https://bugs.webkit.org/show_bug.cgi?id=237567
     5        rdar://89788378
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        In Web Authentication level one, relying parties can specify authenticatorSelection.residentKeyRequired,
     10        to signify they require a client-side discoverable credential. However, if the authenticator does not
     11        support client-side discoverable credentials, the rp has no way to clarify they want a client-side
     12        discoverable credential only if available.
     13
     14        This patch implements authenticatorSelection.residentKeyRequired introduced in level 2, which has three
     15        values 'Preferred', 'Required', and 'Discouraged'. This allows RPs to create a client-side discoverable
     16        credential if possible.
     17
     18        * UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.h:
     19        * UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm:
     20        (-[_WKAuthenticatorSelectionCriteria init]):
     21        * UIProcess/API/Cocoa/_WKResidentKeyRequirement.h: Copied from Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm.
     22        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
     23        (residentKey):
     24        (authenticatorSelectionCriteria):
     25        (+[_WKWebAuthenticationPanel encodeMakeCredentialCommandWithClientDataJSON:options:userVerificationAvailability:]):
     26        (+[_WKWebAuthenticationPanel encodeMakeCredentialCommandWithClientDataHash:options:userVerificationAvailability:]):
     27        * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
     28        (WebKit::CtapAuthenticator::makeCredential):
     29        * WebKit.xcodeproj/project.pbxproj:
     30
    1312022-03-11  Fujii Hironori  <Hironori.Fujii@sony.com>
    232
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.h

    r279089 r291176  
    3030#import <Foundation/Foundation.h>
    3131#import <WebKit/_WKAuthenticatorAttachment.h>
     32#import <WebKit/_WKResidentKeyRequirement.h>
     33
    3234#import <WebKit/_WKUserVerificationRequirement.h>
    3335
     
    4042@property (nonatomic) _WKAuthenticatorAttachment authenticatorAttachment;
    4143
     44/* (@discussion The default value is _WKResidentKeyRequirementNotPresent */
     45@property (nonatomic) _WKResidentKeyRequirement residentKey WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     46
    4247/*!@discussion The default value is NO.*/
    4348@property (nonatomic) BOOL requireResidentKey;
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorSelectionCriteria.mm

    r270142 r291176  
    3535
    3636    self.authenticatorAttachment = _WKAuthenticatorAttachmentAll;
     37    self.residentKey = _WKResidentKeyRequirementNotPresent;
    3738    self.requireResidentKey = NO;
    3839    self.userVerification = _WKUserVerificationRequirementPreferred;
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKResidentKeyRequirement.h

    r291175 r291176  
    11/*
    2  * Copyright (C) 2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "_WKAuthenticatorSelectionCriteria.h"
     26#pragma once
    2827
    29 @implementation _WKAuthenticatorSelectionCriteria
     28#import <WebKit/WKFoundation.h>
    3029
    31 - (instancetype)init
    32 {
    33     if (!(self = [super init]))
    34         return nil;
    35 
    36     self.authenticatorAttachment = _WKAuthenticatorAttachmentAll;
    37     self.requireResidentKey = NO;
    38     self.userVerification = _WKUserVerificationRequirementPreferred;
    39     return self;
    40 }
    41 
    42 @end
     30typedef NS_ENUM(NSInteger, _WKResidentKeyRequirement) {
     31    _WKResidentKeyRequirementNotPresent,
     32    _WKResidentKeyRequirementRequired,
     33    _WKResidentKeyRequirementPreferred,
     34    _WKResidentKeyRequirementDiscouraged,
     35} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm

    r291018 r291176  
    736736}
    737737
     738static std::optional<WebCore::ResidentKeyRequirement> toWebCore(_WKResidentKeyRequirement uv)
     739{
     740    switch (uv) {
     741    case _WKResidentKeyRequirementNotPresent:
     742        return std::nullopt;
     743    case _WKResidentKeyRequirementRequired:
     744        return WebCore::ResidentKeyRequirement::Required;
     745    case _WKResidentKeyRequirementPreferred:
     746        return WebCore::ResidentKeyRequirement::Preferred;
     747    case _WKResidentKeyRequirementDiscouraged:
     748        return WebCore::ResidentKeyRequirement::Discouraged;
     749    default:
     750        ASSERT_NOT_REACHED();
     751        return WebCore::ResidentKeyRequirement::Preferred;
     752    }
     753}
     754
    738755static WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria authenticatorSelectionCriteria(_WKAuthenticatorSelectionCriteria *authenticatorSelection)
    739756{
    740757    WebCore::PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria result;
    741758    result.authenticatorAttachment = authenticatorAttachment(authenticatorSelection.authenticatorAttachment);
     759    result.residentKey = toWebCore(authenticatorSelection.residentKey);
    742760    result.requireResidentKey = authenticatorSelection.requireResidentKey;
    743761    result.userVerification = userVerification(authenticatorSelection.userVerification);
     
    931949    auto hash = produceClientDataJsonHash(clientDataJSON);
    932950
    933     auto encodedVector = fido::encodeMakeCredenitalRequestAsCBOR(hash, [_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:options], coreUserVerificationAvailability(userVerificationAvailability), std::nullopt);
     951    auto encodedVector = fido::encodeMakeCredenitalRequestAsCBOR(hash, [_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:options], coreUserVerificationAvailability(userVerificationAvailability), fido::AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, std::nullopt);
    934952    encodedCommand = adoptNS([[NSData alloc] initWithBytes:encodedVector.data() length:encodedVector.size()]);
    935953#endif
     
    956974    RetainPtr<NSData> encodedCommand;
    957975#if ENABLE(WEB_AUTHN)
    958     auto encodedVector = fido::encodeMakeCredenitalRequestAsCBOR(vectorFromNSData(clientDataHash), [_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:options], coreUserVerificationAvailability(userVerificationAvailability), std::nullopt);
     976    auto encodedVector = fido::encodeMakeCredenitalRequestAsCBOR(vectorFromNSData(clientDataHash), [_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:options], coreUserVerificationAvailability(userVerificationAvailability), fido::AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, std::nullopt);
    959977    encodedCommand = adoptNS([[NSData alloc] initWithBytes:encodedVector.data() length:encodedVector.size()]);
    960978#endif
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp

    r290026 r291176  
    9797    auto& options = std::get<PublicKeyCredentialCreationOptions>(requestData().options);
    9898    auto internalUVAvailability = m_info.options().userVerificationAvailability();
     99    auto residentKeyAvailability = m_info.options().residentKeyAvailability();
    99100    // If UV is required, then either built-in uv or a pin will work.
    100101    if (internalUVAvailability == UVAvailability::kSupportedAndConfigured && (!options.authenticatorSelection || options.authenticatorSelection->userVerification != UserVerificationRequirement::Discouraged) && m_pinAuth.isEmpty())
    101         cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability);
     102        cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability, residentKeyAvailability);
    102103    else if (m_info.options().clientPinAvailability() == AuthenticatorSupportedOptions::ClientPinAvailability::kSupportedAndPinSet)
    103         cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability, PinParameters { pin::kProtocolVersion, m_pinAuth });
     104        cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability, residentKeyAvailability, PinParameters { pin::kProtocolVersion, m_pinAuth });
    104105    else
    105         cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability);
     106        cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, options, internalUVAvailability, residentKeyAvailability);
    106107    driver().transact(WTFMove(cborCmd), [weakThis = WeakPtr { *this }](Vector<uint8_t>&& data) {
    107108        ASSERT(RunLoop::isMain());
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r291167 r291176  
    10821082                51FAEC3B1B0657680009C4E7 /* AuxiliaryProcessMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51FAEC361B0657310009C4E7 /* AuxiliaryProcessMessageReceiver.cpp */; };
    10831083                51FD18B61651FBAD00DBE1CE /* NetworkResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FD18B41651FBAD00DBE1CE /* NetworkResourceLoader.h */; };
     1084                52688AB427D7CE40003577A2 /* _WKResidentKeyRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = 52688AB327D7CE40003577A2 /* _WKResidentKeyRequirement.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10841085                5272D4C91E735F0900EB4290 /* WKProtectionSpaceNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 5272D4C71E735F0900EB4290 /* WKProtectionSpaceNS.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10851086                528C37C1195CBB1A00D8B9CC /* WKBackForwardListPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9F28101958F478008CAC72 /* WKBackForwardListPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    46434644                51FD18B31651FBAD00DBE1CE /* NetworkResourceLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkResourceLoader.cpp; sourceTree = "<group>"; };
    46444645                51FD18B41651FBAD00DBE1CE /* NetworkResourceLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkResourceLoader.h; sourceTree = "<group>"; };
     4646                52688AB327D7CE40003577A2 /* _WKResidentKeyRequirement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = _WKResidentKeyRequirement.h; path = UIProcess/API/Cocoa/_WKResidentKeyRequirement.h; sourceTree = "<group>"; };
    46454647                5272D4C71E735F0900EB4290 /* WKProtectionSpaceNS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKProtectionSpaceNS.h; path = mac/WKProtectionSpaceNS.h; sourceTree = "<group>"; };
    46464648                5272D4C81E735F0900EB4290 /* WKProtectionSpaceNS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKProtectionSpaceNS.mm; path = mac/WKProtectionSpaceNS.mm; sourceTree = "<group>"; };
     
    69816983                        isa = PBXGroup;
    69826984                        children = (
     6985                                52688AB327D7CE40003577A2 /* _WKResidentKeyRequirement.h */,
    69836986                                5C157A0A2717C9F100ED5280 /* webpushd */,
    69846987                                B396EA5512E0ED2D00F4FEB7 /* config.h */,
     
    1298312986                                377216B81A4E6BE000DCA718 /* _WKRenderingProgressEvents.h in Headers */,
    1298412987                                1F604BAA1889FBB800EE0395 /* _WKRenderingProgressEventsInternal.h in Headers */,
     12988                                52688AB427D7CE40003577A2 /* _WKResidentKeyRequirement.h in Headers */,
    1298512989                                5CB7AFE023C52CE500E49CF3 /* _WKResourceLoadDelegate.h in Headers */,
    1298612990                                5CB7AFE823C69B6100E49CF3 /* _WKResourceLoadInfo.h in Headers */,
     
    1367413678                                572EBBC22536A60A000552B3 /* WebAuthnProcessMessages.h in Headers */,
    1367513679                                572EBBC92536AFD5000552B3 /* WebAuthnProcessProxy.h in Headers */,
    13676                                 572EBBD02536BB11000552B3 /* WebAuthnProcessProxyMessages.h in Headers */,
    1367713680                                F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */,
    1367813681                                990D39F5243BE64800199388 /* WebAutomationDOMWindowObserver.h in Headers */,
  • trunk/Tools/ChangeLog

    r291152 r291176  
     12022-03-11  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Support authenticatorSelection.residentKey ResidentKeyRequirement
     4        https://bugs.webkit.org/show_bug.cgi?id=237567
     5        rdar://89788378
     6
     7        Reviewed by Brent Fulgham and Chris Dumez.
     8
     9        Add API tests for authenticatorSelection.residentKey.
     10
     11        * TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp:
     12        (TestWebKitAPI::TEST):
     13        * TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:
     14        (TestWebKitAPI::TEST):
     15
    1162022-03-10  Carlos Garcia Campos  <cgarcia@igalia.com>
    217
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp

    r285698 r291176  
    6161
    6262    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
    63     PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, true, UserVerificationRequirement::Preferred };
    64 
    65     PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
    66     Vector<uint8_t> hash;
    67     hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
    68     auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured);
     63    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, std::nullopt, true, UserVerificationRequirement::Preferred };
     64
     65    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     66    Vector<uint8_t> hash;
     67    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     68    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
    6969    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequest));
    7070    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequest, serializedData.size()), 0);
     
    8484
    8585    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
    86     PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, false, UserVerificationRequirement::Discouraged };
    87 
    88     PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
    89     Vector<uint8_t> hash;
    90     hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
    91     auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured);
     86    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, std::nullopt, false, UserVerificationRequirement::Discouraged };
     87
     88    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     89    Vector<uint8_t> hash;
     90    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     91    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
    9292    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestShort));
    9393    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestShort, serializedData.size()), 0);
     
    107107
    108108    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
    109     PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, false, UserVerificationRequirement::Required };
    110 
    111     PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
    112     Vector<uint8_t> hash;
    113     hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
    114     auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kNotSupported);
     109    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, std::nullopt, false, UserVerificationRequirement::Required };
     110
     111    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     112    Vector<uint8_t> hash;
     113    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     114    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kNotSupported, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
    115115    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestShort));
    116116    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestShort, serializedData.size()), 0);
     
    130130
    131131    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
    132     PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, true, UserVerificationRequirement::Preferred };
     132    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, std::nullopt, true, UserVerificationRequirement::Preferred };
    133133
    134134    PinParameters pin;
     
    139139    Vector<uint8_t> hash;
    140140    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
    141     auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, pin);
     141    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, pin);
    142142    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestWithPin));
    143143    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestWithPin, serializedData.size()), 0);
     144}
     145
     146TEST(CTAPRequestTest, TestConstructMakeCredentialRequestRKPreferred)
     147{
     148    PublicKeyCredentialCreationOptions::RpEntity rp;
     149    rp.name = "Acme";
     150    rp.id = "acme.com";
     151
     152    PublicKeyCredentialCreationOptions::UserEntity user;
     153    user.name = "johnpsmith@example.com";
     154    user.icon = "https://pics.acme.com/00/p/aBjjjpqPb.png";
     155    user.id = WebCore::toBufferSource(TestData::kUserId, sizeof(TestData::kUserId));
     156    user.displayName = "John P. Smith";
     157
     158    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
     159    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, ResidentKeyRequirement::Preferred, true, UserVerificationRequirement::Preferred };
     160
     161    PinParameters pin;
     162    pin.protocol = pin::kProtocolVersion;
     163    pin.auth.append(TestData::kCtap2PinAuth, sizeof(TestData::kCtap2PinAuth));
     164
     165    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     166    Vector<uint8_t> hash;
     167    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     168    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, pin);
     169    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestWithPin));
     170    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestWithPin, serializedData.size()), 0);
     171}
     172
     173TEST(CTAPRequestTest, TestConstructMakeCredentialRequestRKPreferredNotSupported)
     174{
     175    PublicKeyCredentialCreationOptions::RpEntity rp;
     176    rp.name = "Acme";
     177    rp.id = "acme.com";
     178
     179    PublicKeyCredentialCreationOptions::UserEntity user;
     180    user.name = "johnpsmith@example.com";
     181    user.icon = "https://pics.acme.com/00/p/aBjjjpqPb.png";
     182    user.id = WebCore::toBufferSource(TestData::kUserId, sizeof(TestData::kUserId));
     183    user.displayName = "John P. Smith";
     184
     185    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
     186    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, ResidentKeyRequirement::Preferred, true, UserVerificationRequirement::Required };
     187
     188    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     189    Vector<uint8_t> hash;
     190    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     191    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kNotSupported, AuthenticatorSupportedOptions::ResidentKeyAvailability::kNotSupported);
     192    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestShort));
     193    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestShort, serializedData.size()), 0);
     194}
     195
     196TEST(CTAPRequestTest, TestConstructMakeCredentialRequestRKDiscouraged)
     197{
     198    PublicKeyCredentialCreationOptions::RpEntity rp;
     199    rp.name = "Acme";
     200    rp.id = "acme.com";
     201
     202    PublicKeyCredentialCreationOptions::UserEntity user;
     203    user.name = "johnpsmith@example.com";
     204    user.icon = "https://pics.acme.com/00/p/aBjjjpqPb.png";
     205    user.id = WebCore::toBufferSource(TestData::kUserId, sizeof(TestData::kUserId));
     206    user.displayName = "John P. Smith";
     207
     208    Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } };
     209    PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { AuthenticatorAttachment::Platform, ResidentKeyRequirement::Discouraged, true, UserVerificationRequirement::Required };
     210
     211    PublicKeyCredentialCreationOptions options { rp, user, { }, params, std::nullopt, { }, selection, AttestationConveyancePreference::None, std::nullopt };
     212    Vector<uint8_t> hash;
     213    hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash));
     214    auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kNotSupported, AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
     215    EXPECT_EQ(serializedData.size(), sizeof(TestData::kCtapMakeCredentialRequestShort));
     216    EXPECT_EQ(memcmp(serializedData.data(), TestData::kCtapMakeCredentialRequestShort, serializedData.size()), 0);
    144217}
    145218
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp

    r285698 r291176  
    590590    EXPECT_NE(getInfoResponse->versions().find(ProtocolVersion::kU2f), getInfoResponse->versions().end());
    591591    EXPECT_TRUE(getInfoResponse->options().isPlatformDevice());
    592     EXPECT_TRUE(getInfoResponse->options().supportsResidentKey());
     592    EXPECT_EQ(AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, getInfoResponse->options().residentKeyAvailability());
    593593    EXPECT_TRUE(getInfoResponse->options().userPresenceRequired());
    594594    EXPECT_EQ(AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, getInfoResponse->options().userVerificationAvailability());
     
    605605    EXPECT_NE(getInfoResponse->versions().find(ProtocolVersion::kU2f), getInfoResponse->versions().end());
    606606    EXPECT_TRUE(getInfoResponse->options().isPlatformDevice());
    607     EXPECT_TRUE(getInfoResponse->options().supportsResidentKey());
     607    EXPECT_EQ(AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, getInfoResponse->options().residentKeyAvailability());
    608608    EXPECT_TRUE(getInfoResponse->options().userPresenceRequired());
    609609    EXPECT_EQ(AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedAndConfigured, getInfoResponse->options().userVerificationAvailability());
     
    623623    response.setExtensions({ "uvm", "hmac-secret" });
    624624    AuthenticatorSupportedOptions options;
    625     options.setSupportsResidentKey(true);
     625    options.setResidentKeyAvailability(AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported);
    626626    options.setIsPlatformDevice(true);
    627627    options.setClientPinAvailability(AuthenticatorSupportedOptions::ClientPinAvailability::kSupportedButPinNotSet);
Note: See TracChangeset for help on using the changeset viewer.