Changeset 292913 in webkit


Ignore:
Timestamp:
Apr 15, 2022 10:38:42 AM (3 months ago)
Author:
J Pascoe
Message:

Source/WebCore:
[WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
https://bugs.webkit.org/show_bug.cgi?id=238966
rdar://problem/91449906

This change implements the getTransports() and getAuthenticatorData() functions
on AuthenticatorAttestationResponse. For security keys, the supported transports of
the key are parsed from authenticatorGetInfo. For the local authenticator, the supported
transports are specified according to which features are available. getAuthenticatorData()
is a convenience method for RPs who want to avoid parsing CBOR.

Reviewed by Brent Fulgham.

  • Modules/webauthn/AuthenticatorAttestationResponse.cpp:

(WebCore::AuthenticatorAttestationResponse::create):
(WebCore::AuthenticatorAttestationResponse::AuthenticatorAttestationResponse):
(WebCore::AuthenticatorAttestationResponse::data const):
(WebCore::AuthenticatorAttestationResponse::getTransports const):
(WebCore::AuthenticatorAttestationResponse::getAuthenticatorData const):

  • Modules/webauthn/AuthenticatorAttestationResponse.h:
  • Modules/webauthn/AuthenticatorAttestationResponse.idl:
  • Modules/webauthn/AuthenticatorResponse.cpp:

(WebCore::AuthenticatorResponse::tryCreate):

  • Modules/webauthn/AuthenticatorResponse.h:
  • Modules/webauthn/AuthenticatorResponseData.h:

(WebCore::AuthenticatorResponseData::encode const):
(WebCore::AuthenticatorResponseData::decode):

  • Modules/webauthn/AuthenticatorTransport.h:
  • Modules/webauthn/AuthenticatorTransport.idl:
  • Modules/webauthn/WebAuthenticationConstants.h:
  • Modules/webauthn/WebAuthenticationUtils.cpp:

(WebCore::convertArrayBufferToVector):

  • Modules/webauthn/WebAuthenticationUtils.h:
  • Modules/webauthn/fido/AuthenticatorGetInfoResponse.cpp:

(fido::AuthenticatorGetInfoResponse::setTransports):
(fido::toStringVector):
(fido::encodeAsCBOR):

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

(fido::convertStringToAuthenticatorTransport):
(fido::readCTAPMakeCredentialResponse):
(fido::readCTAPGetInfoResponse):

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

(fido::readU2fRegisterResponse):

  • Modules/webauthn/fido/U2fResponseConverter.h:

(fido::readU2fRegisterResponse):

Source/WebKit:
[WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
https://bugs.webkit.org/show_bug.cgi?id=238966
rdar://problem/91449906

This change implements the getTransports() and getAuthenticatorData() functions
on AuthenticatorAttestationResponse. For security keys, the supported transports of
the key are parsed from authenticatorGetInfo. For the local authenticator, the supported
transports are specified according to which features are available. getAuthenticatorData()
is a convenience method for RPs who want to avoid parsing CBOR.

Reviewed by Brent Fulgham.

  • Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
  • UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.h:
  • UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm:

(-[_WKAuthenticatorAttestationResponse initWithClientDataJSON:rawId:extensions:attestationObject:attachment:transports:]):
(-[_WKAuthenticatorAttestationResponse initWithClientDataJSON:rawId:extensions:attestationObject:attachment:]): Deleted.

  • UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h:
  • UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:

(wkExtensionsClientOutputs):
(wkAuthenticatorAttestationResponse):
(wkAuthenticatorAssertionResponse):

  • UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:

(WebKit::LocalAuthenticatorInternal::transports):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested):

  • UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:

(WebKit::toASCDescriptor):
(WebKit::toAuthenticatorTransports):
(WebKit::continueAfterRequest):

  • UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:

(WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived):
(WebKit::CtapAuthenticator::transports):

  • UIProcess/WebAuthentication/fido/CtapAuthenticator.h:
  • UIProcess/WebAuthentication/fido/CtapDriver.h:

(WebKit::CtapDriver::transport const):
(WebKit::CtapDriver::protocol const):
(WebKit::CtapDriver::CtapDriver):

  • UIProcess/WebAuthentication/fido/CtapHidDriver.cpp:

(WebKit::CtapHidDriver::CtapHidDriver):

  • UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp:

(WebKit::CtapNfcDriver::CtapNfcDriver):

  • UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp:

(WebKit::U2fAuthenticator::continueRegisterCommandAfterResponseReceived):

Tools:
[WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
https://bugs.webkit.org/show_bug.cgi?id=238966
rdar://problem/91449906

Reviewed by Brent Fulgham.

Add tests for parsing transports from getInfo.

  • TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:

(TestWebKitAPI::TEST):

  • TestWebKitAPI/Tests/WebCore/FidoTestData.h:

LayoutTests:
[WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
https://bugs.webkit.org/show_bug.cgi?id=238966
rdar://problem/91449906

Reviewed by Brent Fulgham.

Add getTransports() to test.

  • http/wpt/webauthn/public-key-credential-create-success-hid.https.html:
  • http/wpt/webauthn/resources/util.js:
Location:
trunk
Files:
38 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r292909 r292913  
     12022-04-15  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
     4        https://bugs.webkit.org/show_bug.cgi?id=238966
     5        rdar://problem/91449906
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add getTransports() to test.
     10
     11        * http/wpt/webauthn/public-key-credential-create-success-hid.https.html:
     12        * http/wpt/webauthn/resources/util.js:
     13
    1142022-04-15  Karl Rackler  <rackler@apple.com>
    215
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html

    r291176 r292913  
    2828
    2929        return navigator.credentials.create(options).then(credential => {
    30             checkCtapMakeCredentialResult(credential);
     30            checkCtapMakeCredentialResult(credential, true, ["usb"]);
    3131        });
    3232    }, "PublicKeyCredential's [[create]] with minimum options in a mock hid authenticator.");
  • trunk/LayoutTests/http/wpt/webauthn/resources/util.js

    r288622 r292913  
    356356}
    357357
    358 function checkCtapMakeCredentialResult(credential, isNoneAttestation = true)
     358function checkCtapMakeCredentialResult(credential, isNoneAttestation = true, transports = null)
    359359{
    360360    // Check response
     
    389389        assert_equals(attestationObject.attStmt.x5c.length, 1);
    390390    }
     391    if (transports)
     392        assert_array_equals(transports, credential.response.getTransports());
    391393}
    392394
  • trunk/Source/WebCore/ChangeLog

    r292911 r292913  
     12022-04-15  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
     4        https://bugs.webkit.org/show_bug.cgi?id=238966
     5        rdar://problem/91449906
     6
     7        This change implements the getTransports() and getAuthenticatorData() functions
     8        on AuthenticatorAttestationResponse. For security keys, the supported transports of
     9        the key are parsed from authenticatorGetInfo. For the local authenticator, the supported
     10        transports are specified according to which features are available. getAuthenticatorData()
     11        is a convenience method for RPs who want to avoid parsing CBOR.
     12
     13        Reviewed by Brent Fulgham.
     14
     15        * Modules/webauthn/AuthenticatorAttestationResponse.cpp:
     16        (WebCore::AuthenticatorAttestationResponse::create):
     17        (WebCore::AuthenticatorAttestationResponse::AuthenticatorAttestationResponse):
     18        (WebCore::AuthenticatorAttestationResponse::data const):
     19        (WebCore::AuthenticatorAttestationResponse::getTransports const):
     20        (WebCore::AuthenticatorAttestationResponse::getAuthenticatorData const):
     21        * Modules/webauthn/AuthenticatorAttestationResponse.h:
     22        * Modules/webauthn/AuthenticatorAttestationResponse.idl:
     23        * Modules/webauthn/AuthenticatorResponse.cpp:
     24        (WebCore::AuthenticatorResponse::tryCreate):
     25        * Modules/webauthn/AuthenticatorResponse.h:
     26        * Modules/webauthn/AuthenticatorResponseData.h:
     27        (WebCore::AuthenticatorResponseData::encode const):
     28        (WebCore::AuthenticatorResponseData::decode):
     29        * Modules/webauthn/AuthenticatorTransport.h:
     30        * Modules/webauthn/AuthenticatorTransport.idl:
     31        * Modules/webauthn/WebAuthenticationConstants.h:
     32        * Modules/webauthn/WebAuthenticationUtils.cpp:
     33        (WebCore::convertArrayBufferToVector):
     34        * Modules/webauthn/WebAuthenticationUtils.h:
     35        * Modules/webauthn/fido/AuthenticatorGetInfoResponse.cpp:
     36        (fido::AuthenticatorGetInfoResponse::setTransports):
     37        (fido::toStringVector):
     38        (fido::encodeAsCBOR):
     39        * Modules/webauthn/fido/AuthenticatorGetInfoResponse.h:
     40        * Modules/webauthn/fido/DeviceResponseConverter.cpp:
     41        (fido::convertStringToAuthenticatorTransport):
     42        (fido::readCTAPMakeCredentialResponse):
     43        (fido::readCTAPGetInfoResponse):
     44        * Modules/webauthn/fido/DeviceResponseConverter.h:
     45        * Modules/webauthn/fido/U2fResponseConverter.cpp:
     46        (fido::readU2fRegisterResponse):
     47        * Modules/webauthn/fido/U2fResponseConverter.h:
     48        (fido::readU2fRegisterResponse):
     49
    1502022-04-15  Brandon Stewart  <brandonstewart@apple.com>
    251
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp

    r278358 r292913  
    3030
    3131#include "AuthenticatorResponseData.h"
     32#include "CBORReader.h"
     33#include "WebAuthenticationUtils.h"
    3234
    3335namespace WebCore {
    3436
    35 Ref<AuthenticatorAttestationResponse> AuthenticatorAttestationResponse::create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment attachment)
     37Ref<AuthenticatorAttestationResponse> AuthenticatorAttestationResponse::create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment attachment, Vector<AuthenticatorTransport>&& transports)
    3638{
    37     return adoptRef(*new AuthenticatorAttestationResponse(WTFMove(rawId), WTFMove(attestationObject), attachment));
     39    return adoptRef(*new AuthenticatorAttestationResponse(WTFMove(rawId), WTFMove(attestationObject), attachment, WTFMove(transports)));
    3840}
    3941
    40 Ref<AuthenticatorAttestationResponse> AuthenticatorAttestationResponse::create(const Vector<uint8_t>& rawId, const Vector<uint8_t>& attestationObject, AuthenticatorAttachment attachment)
     42Ref<AuthenticatorAttestationResponse> AuthenticatorAttestationResponse::create(const Vector<uint8_t>& rawId, const Vector<uint8_t>& attestationObject, AuthenticatorAttachment attachment, Vector<AuthenticatorTransport>&& transports)
    4143{
    42     return create(ArrayBuffer::create(rawId.data(), rawId.size()), ArrayBuffer::create(attestationObject.data(), attestationObject.size()), attachment);
     44    return create(ArrayBuffer::create(rawId.data(), rawId.size()), ArrayBuffer::create(attestationObject.data(), attestationObject.size()), attachment, WTFMove(transports));
    4345}
    4446
    45 AuthenticatorAttestationResponse::AuthenticatorAttestationResponse(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment attachment)
     47AuthenticatorAttestationResponse::AuthenticatorAttestationResponse(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment attachment, Vector<AuthenticatorTransport>&& transports)
    4648    : AuthenticatorResponse(WTFMove(rawId), attachment)
    4749    , m_attestationObject(WTFMove(attestationObject))
     50    , m_transports(WTFMove(transports))
    4851{
    4952}
     
    5457    data.isAuthenticatorAttestationResponse = true;
    5558    data.attestationObject = m_attestationObject.copyRef();
     59    data.transports = m_transports;
    5660    return data;
     61}
     62
     63RefPtr<ArrayBuffer> AuthenticatorAttestationResponse::getAuthenticatorData() const
     64{
     65    auto decodedResponse = cbor::CBORReader::read(convertArrayBufferToVector(m_attestationObject.ptr()));
     66    if (!decodedResponse || !decodedResponse->isMap()) {
     67        ASSERT_NOT_REACHED();
     68        return nullptr;
     69    }
     70    const auto& attObjMap = decodedResponse->getMap();
     71    auto it = attObjMap.find(cbor::CBORValue("authData"));
     72    if (it == attObjMap.end() || !it->second.isByteString()) {
     73        ASSERT_NOT_REACHED();
     74        return nullptr;
     75    }
     76    auto authData = it->second.getByteString();
     77    return ArrayBuffer::tryCreate(authData.data(), authData.size());
    5778}
    5879
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.h

    r278358 r292913  
    2929
    3030#include "AuthenticatorResponse.h"
     31#include "AuthenticatorTransport.h"
    3132
    3233namespace WebCore {
     
    3435class AuthenticatorAttestationResponse : public AuthenticatorResponse {
    3536public:
    36     static Ref<AuthenticatorAttestationResponse> create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment);
    37     WEBCORE_EXPORT static Ref<AuthenticatorAttestationResponse> create(const Vector<uint8_t>& rawId, const Vector<uint8_t>& attestationObject, AuthenticatorAttachment);
     37    static Ref<AuthenticatorAttestationResponse> create(Ref<ArrayBuffer>&& rawId, Ref<ArrayBuffer>&& attestationObject, AuthenticatorAttachment, Vector<AuthenticatorTransport>&&);
     38    WEBCORE_EXPORT static Ref<AuthenticatorAttestationResponse> create(const Vector<uint8_t>& rawId, const Vector<uint8_t>& attestationObject, AuthenticatorAttachment, Vector<AuthenticatorTransport>&&);
    3839
    3940    virtual ~AuthenticatorAttestationResponse() = default;
    4041
    4142    ArrayBuffer* attestationObject() const { return m_attestationObject.ptr(); }
     43    const Vector<AuthenticatorTransport>& getTransports() const { return m_transports; }
     44    RefPtr<ArrayBuffer> getAuthenticatorData() const;
    4245
    4346private:
    44     AuthenticatorAttestationResponse(Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, AuthenticatorAttachment);
     47    AuthenticatorAttestationResponse(Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, AuthenticatorAttachment, Vector<AuthenticatorTransport>&&);
    4548
    4649    Type type() const final { return Type::Attestation; }
     
    4851
    4952    Ref<ArrayBuffer> m_attestationObject;
     53    Vector<AuthenticatorTransport> m_transports;
    5054};
    5155
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.idl

    r283463 r292913  
    3131] interface AuthenticatorAttestationResponse : AuthenticatorResponse {
    3232    [SameObject] readonly attribute ArrayBuffer attestationObject;
     33    sequence<AuthenticatorTransport> getTransports();
     34    ArrayBuffer getAuthenticatorData();
    3335};
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp

    r278358 r292913  
    4444            return nullptr;
    4545
    46         return AuthenticatorAttestationResponse::create(data.rawId.releaseNonNull(), data.attestationObject.releaseNonNull(), attachment);
     46        return AuthenticatorAttestationResponse::create(data.rawId.releaseNonNull(), data.attestationObject.releaseNonNull(), attachment, WTFMove(data.transports));
    4747    }
    4848
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h

    r278358 r292913  
    3636
    3737enum class AuthenticatorAttachment;
     38enum class AuthenticatorTransport;
    3839
    3940struct AuthenticatorResponseData;
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h

    r287380 r292913  
    2828#if ENABLE(WEB_AUTHN)
    2929
     30#include "AuthenticatorTransport.h"
    3031#include <JavaScriptCore/ArrayBuffer.h>
    3132#include <wtf/Forward.h>
     
    5152    RefPtr<ArrayBuffer> signature;
    5253    RefPtr<ArrayBuffer> userHandle;
     54
     55    Vector<WebCore::AuthenticatorTransport> transports;
    5356
    5457    template<class Encoder> void encode(Encoder&) const;
     
    9598    if (isAuthenticatorAttestationResponse && attestationObject) {
    9699        encodeArrayBuffer(encoder, *attestationObject);
     100        encoder << transports;
    97101        return;
    98102    }
     
    140144        if (!result.attestationObject)
    141145            return std::nullopt;
     146
     147        std::optional<Vector<AuthenticatorTransport>> transports;
     148        decoder >> transports;
     149        if (!transports)
     150            return std::nullopt;
     151        result.transports = WTFMove(*transports);
    142152        return result;
    143153    }
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorTransport.h

    r237103 r292913  
    3636    Nfc,
    3737    Ble,
    38     Internal
     38    Internal,
     39    Cable
    3940};
    4041
     
    4950        WebCore::AuthenticatorTransport::Nfc,
    5051        WebCore::AuthenticatorTransport::Ble,
    51         WebCore::AuthenticatorTransport::Internal
     52        WebCore::AuthenticatorTransport::Internal,
     53        WebCore::AuthenticatorTransport::Cable
    5254    >;
    5355};
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorTransport.idl

    r236481 r292913  
    3030    "nfc",
    3131    "ble",
    32     "internal"
     32    "internal",
     33    "cable"
    3334};
  • trunk/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h

    r291882 r292913  
    9494constexpr const char applicationTagKey[] = "tag";
    9595
     96constexpr auto authenticatorTransportUsb = "usb"_s;
     97constexpr auto authenticatorTransportNfc = "nfc"_s;
     98constexpr auto authenticatorTransportBle = "ble"_s;
     99constexpr auto authenticatorTransportInternal = "internal"_s;
     100constexpr auto authenticatorTransportCable = "cable"_s;
     101
    96102} // namespace WebCore
    97103
  • trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp

    r292487 r292913  
    2929#if ENABLE(WEB_AUTHN)
    3030
     31#include "CBORReader.h"
    3132#include "CBORWriter.h"
    3233#include "FidoConstants.h"
     
    4243{
    4344    return { byteArray, length };
     45}
     46
     47Vector<uint8_t> convertArrayBufferToVector(ArrayBuffer* buffer)
     48{
     49    return convertBytesToVector(static_cast<uint8_t*>(buffer->data()), buffer->byteLength());
    4450}
    4551
  • trunk/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h

    r291624 r292913  
    3939WEBCORE_EXPORT Vector<uint8_t> convertBytesToVector(const uint8_t byteArray[], const size_t length);
    4040
     41WEBCORE_EXPORT Vector<uint8_t> convertArrayBufferToVector(ArrayBuffer*);
     42
    4143// Produce a SHA-256 hash of the given RP ID.
    4244WEBCORE_EXPORT Vector<uint8_t> produceRpIdHash(const String& rpId);
  • trunk/Source/WebCore/Modules/webauthn/fido/AuthenticatorGetInfoResponse.cpp

    r290026 r292913  
    3535#include "CBORValue.h"
    3636#include "CBORWriter.h"
     37#include "WebAuthenticationConstants.h"
    3738
    3839namespace fido {
     
    7778}
    7879
     80AuthenticatorGetInfoResponse& AuthenticatorGetInfoResponse::setTransports(Vector<WebCore::AuthenticatorTransport>&& transports)
     81{
     82    m_transports = WTFMove(transports);
     83    return *this;
     84}
     85
     86static String toString(WebCore::AuthenticatorTransport transport)
     87{
     88    switch (transport) {
     89    case WebCore::AuthenticatorTransport::Usb:
     90        return WebCore::authenticatorTransportUsb;
     91        break;
     92    case WebCore::AuthenticatorTransport::Nfc:
     93        return WebCore::authenticatorTransportNfc;
     94        break;
     95    case WebCore::AuthenticatorTransport::Ble:
     96        return WebCore::authenticatorTransportBle;
     97        break;
     98    case WebCore::AuthenticatorTransport::Internal:
     99        return WebCore::authenticatorTransportInternal;
     100        break;
     101    case WebCore::AuthenticatorTransport::Cable:
     102        return WebCore::authenticatorTransportCable;
     103    default:
     104        break;
     105    }
     106    ASSERT_NOT_REACHED();
     107    return nullString();
     108}
     109
    79110Vector<uint8_t> encodeAsCBOR(const AuthenticatorGetInfoResponse& response)
    80111{
     
    99130    if (response.pinProtocol())
    100131        deviceInfoMap.emplace(CBORValue(6), toArrayValue(*response.pinProtocol()));
     132   
     133    if (response.transports()) {
     134        auto transports = *response.transports();
     135        deviceInfoMap.emplace(CBORValue(7), toArrayValue(transports.map(toString)));
     136    }
    101137
    102138    auto encodedBytes = CBORWriter::write(CBORValue(WTFMove(deviceInfoMap)));
  • trunk/Source/WebCore/Modules/webauthn/fido/AuthenticatorGetInfoResponse.h

    r278253 r292913  
    3333
    3434#include "AuthenticatorSupportedOptions.h"
     35#include "AuthenticatorTransport.h"
    3536#include "FidoConstants.h"
    3637#include <wtf/StdSet.h>
     
    5354    AuthenticatorGetInfoResponse& setExtensions(Vector<String>&&);
    5455    AuthenticatorGetInfoResponse& setOptions(AuthenticatorSupportedOptions&&);
     56    AuthenticatorGetInfoResponse& setTransports(Vector<WebCore::AuthenticatorTransport>&&);
    5557
    5658    const StdSet<ProtocolVersion>& versions() const { return m_versions; }
     
    6062    const std::optional<Vector<String>>& extensions() const { return m_extensions; }
    6163    const AuthenticatorSupportedOptions& options() const { return m_options; }
     64    const std::optional<Vector<WebCore::AuthenticatorTransport>>& transports() const { return m_transports; }
    6265
    6366private:
     
    6871    std::optional<Vector<String>> m_extensions;
    6972    AuthenticatorSupportedOptions m_options;
     73    std::optional<Vector<WebCore::AuthenticatorTransport>> m_transports;
    7074};
    7175
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp

    r291863 r292913  
    5555}
    5656
     57static std::optional<AuthenticatorTransport> convertStringToAuthenticatorTransport(const String& transport)
     58{
     59    if (transport == authenticatorTransportUsb)
     60        return AuthenticatorTransport::Usb;
     61    if (transport == authenticatorTransportNfc)
     62        return AuthenticatorTransport::Nfc;
     63    if (transport == authenticatorTransportBle)
     64        return AuthenticatorTransport::Ble;
     65    if (transport == authenticatorTransportInternal)
     66        return AuthenticatorTransport::Internal;
     67    if (transport == authenticatorTransportCable)
     68        return AuthenticatorTransport::Cable;
     69    return std::nullopt;
     70}
     71
    5772std::optional<cbor::CBORValue> decodeResponseMap(const Vector<uint8_t>& inBuffer)
    5873{
     
    96111// Decodes byte array response from authenticator to CBOR value object and
    97112// checks for correct encoding format.
    98 RefPtr<AuthenticatorAttestationResponse> readCTAPMakeCredentialResponse(const Vector<uint8_t>& inBuffer, WebCore::AuthenticatorAttachment attachment, const AttestationConveyancePreference& attestation)
     113RefPtr<AuthenticatorAttestationResponse> readCTAPMakeCredentialResponse(const Vector<uint8_t>& inBuffer, WebCore::AuthenticatorAttachment attachment, Vector<AuthenticatorTransport>&& transports, const AttestationConveyancePreference& attestation)
    99114{
    100115    auto decodedMap = decodeResponseMap(inBuffer);
     
    136151    }
    137152
    138     return AuthenticatorAttestationResponse::create(credentialId, *attestationObject, attachment);
     153    return AuthenticatorAttestationResponse::create(credentialId, *attestationObject, attachment, WTFMove(transports));
    139154}
    140155
     
    326341    }
    327342
     343    it = responseMap.find(CBOR(9));
     344    if (it != responseMap.end()) {
     345        if (!it->second.isArray())
     346            return std::nullopt;
     347
     348        Vector<AuthenticatorTransport> transports;
     349        for (const auto& transportString : it->second.getArray()) {
     350            if (!transportString.isString())
     351                return std::nullopt;
     352            auto transport = convertStringToAuthenticatorTransport(transportString.getString());
     353            if (transport)
     354                transports.append(*transport);
     355        }
     356        response.setTransports(WTFMove(transports));
     357    }
     358
    328359    return WTFMove(response);
    329360}
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.h

    r278358 r292913  
    5353// CBOR map keys that conform to format of attestation object defined by the
    5454// WebAuthN spec : https://w3c.github.io/webauthn/#fig-attStructs
    55 WEBCORE_EXPORT RefPtr<WebCore::AuthenticatorAttestationResponse> readCTAPMakeCredentialResponse(const Vector<uint8_t>&, WebCore::AuthenticatorAttachment, const WebCore::AttestationConveyancePreference& = WebCore::AttestationConveyancePreference::Direct);
     55WEBCORE_EXPORT RefPtr<WebCore::AuthenticatorAttestationResponse> readCTAPMakeCredentialResponse(const Vector<uint8_t>&, WebCore::AuthenticatorAttachment, Vector<WebCore::AuthenticatorTransport>&&, const WebCore::AttestationConveyancePreference& = WebCore::AttestationConveyancePreference::Direct);
    5656
    5757// De-serializes CBOR encoded response to AuthenticatorGetAssertion /
  • trunk/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.cpp

    r291863 r292913  
    138138} // namespace
    139139
    140 RefPtr<AuthenticatorAttestationResponse> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, AuthenticatorAttachment attachment, const AttestationConveyancePreference& attestation)
     140RefPtr<AuthenticatorAttestationResponse> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, AuthenticatorAttachment attachment, Vector<AuthenticatorTransport>&& transports, const AttestationConveyancePreference& attestation)
    141141{
    142142    auto publicKey = extractECPublicKeyFromU2fRegistrationResponse(u2fData);
     
    161161    auto attestationObject = buildAttestationObject(WTFMove(authData), "fido-u2f"_s, WTFMove(fidoAttestationStatement), attestation);
    162162
    163     return AuthenticatorAttestationResponse::create(credentialId, attestationObject, attachment);
     163    return AuthenticatorAttestationResponse::create(credentialId, attestationObject, attachment, WTFMove(transports));
    164164}
    165165
  • trunk/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.h

    r285698 r292913  
    4545// Converts a U2F register response to WebAuthN makeCredential response.
    4646// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html#u2f-authenticatorMakeCredential-interoperability
    47 WEBCORE_EXPORT RefPtr<WebCore::AuthenticatorAttestationResponse> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, WebCore::AuthenticatorAttachment, const WebCore::AttestationConveyancePreference& = WebCore::AttestationConveyancePreference::Direct);
     47WEBCORE_EXPORT RefPtr<WebCore::AuthenticatorAttestationResponse> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, WebCore::AuthenticatorAttachment, Vector<WebCore::AuthenticatorTransport>&& transports = { }, const WebCore::AttestationConveyancePreference& = WebCore::AttestationConveyancePreference::Direct);
    4848
    4949// Converts a U2F authentication response to WebAuthN getAssertion response.
  • trunk/Source/WebKit/ChangeLog

    r292912 r292913  
     12022-04-15  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
     4        https://bugs.webkit.org/show_bug.cgi?id=238966
     5        rdar://problem/91449906
     6
     7        This change implements the getTransports() and getAuthenticatorData() functions
     8        on AuthenticatorAttestationResponse. For security keys, the supported transports of
     9        the key are parsed from authenticatorGetInfo. For the local authenticator, the supported
     10        transports are specified according to which features are available. getAuthenticatorData()
     11        is a convenience method for RPs who want to avoid parsing CBOR.
     12
     13        Reviewed by Brent Fulgham.
     14
     15        * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
     16        * UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.h:
     17        * UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm:
     18        (-[_WKAuthenticatorAttestationResponse initWithClientDataJSON:rawId:extensions:attestationObject:attachment:transports:]):
     19        (-[_WKAuthenticatorAttestationResponse initWithClientDataJSON:rawId:extensions:attestationObject:attachment:]): Deleted.
     20        * UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h:
     21        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
     22        (wkExtensionsClientOutputs):
     23        (wkAuthenticatorAttestationResponse):
     24        (wkAuthenticatorAssertionResponse):
     25        * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
     26        (WebKit::LocalAuthenticatorInternal::transports):
     27        (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
     28        (WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested):
     29        * UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
     30        (WebKit::toASCDescriptor):
     31        (WebKit::toAuthenticatorTransports):
     32        (WebKit::continueAfterRequest):
     33        * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
     34        (WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived):
     35        (WebKit::CtapAuthenticator::transports):
     36        * UIProcess/WebAuthentication/fido/CtapAuthenticator.h:
     37        * UIProcess/WebAuthentication/fido/CtapDriver.h:
     38        (WebKit::CtapDriver::transport const):
     39        (WebKit::CtapDriver::protocol const):
     40        (WebKit::CtapDriver::CtapDriver):
     41        * UIProcess/WebAuthentication/fido/CtapHidDriver.cpp:
     42        (WebKit::CtapHidDriver::CtapHidDriver):
     43        * UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp:
     44        (WebKit::CtapNfcDriver::CtapNfcDriver):
     45        * UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp:
     46        (WebKit::U2fAuthenticator::continueRegisterCommandAfterResponseReceived):
     47
    1482022-04-14  Simon Fraser  <simon.fraser@apple.com>
    249
  • trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h

    r291988 r292913  
    291291@property (nonatomic, copy, readonly) NSData *attestationObject;
    292292@property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
     293@property (nonatomic, copy) NSArray<NSNumber *> *transports;
    293294
    294295+ (instancetype)new NS_UNAVAILABLE;
     
    305306@property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
    306307@property (nonatomic, copy, readonly) NSData *attestationObject;
     308@property (nonatomic, copy) NSArray<NSNumber *> *transports;
    307309
    308310@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.h

    r279089 r292913  
    3434
    3535@property (nonatomic, readonly) NSData *attestationObject;
     36@property (nonatomic, copy) NSArray<NSNumber *> *transports;
    3637
    3738@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm

    r278358 r292913  
    3333@implementation _WKAuthenticatorAttestationResponse
    3434
    35 - (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment
     35- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment transports:(NSArray<NSNumber *> *)transports
    3636{
    3737    if (!(self = [super initWithClientDataJSON:clientDataJSON rawId:rawId extensions:WTFMove(extensions) attachment:attachment]))
     
    3939
    4040    _attestationObject = attestationObject;
     41    _transports = transports;
    4142    return self;
    4243}
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h

    r278358 r292913  
    3535@interface _WKAuthenticatorAttestationResponse ()
    3636
    37 - (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment;
     37- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment transports:(NSArray<NSNumber *> *)transports;
    3838
    3939@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm

    r292587 r292913  
    849849}
    850850
     851static RetainPtr<_WKAuthenticationExtensionsClientOutputs> wkExtensionsClientOutputs(const WebCore::AuthenticatorResponseData& data)
     852{
     853    RetainPtr<_WKAuthenticationExtensionsClientOutputs> extensions;
     854    if (data.appid)
     855        extensions = adoptNS([[_WKAuthenticationExtensionsClientOutputs alloc] initWithAppid:data.appid.value()]);
     856    return extensions;
     857}
     858
     859static RetainPtr<NSArray<NSNumber *>> wkTransports(const Vector<WebCore::AuthenticatorTransport>& transports)
     860{
     861    auto wkTransports = adoptNS([NSMutableArray<NSNumber *> new]);
     862    for (auto transport : transports)
     863        [wkTransports addObject:[NSNumber numberWithInt:(int)transport]];
     864    return wkTransports;
     865}
     866
     867
    851868static RetainPtr<_WKAuthenticatorAttestationResponse> wkAuthenticatorAttestationResponse(const WebCore::AuthenticatorResponseData& data, NSData *clientDataJSON, WebCore::AuthenticatorAttachment attachment)
    852869{
    853     return adoptNS([[_WKAuthenticatorAttestationResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensions:nil attestationObject:[NSData dataWithBytes:data.attestationObject->data() length:data.attestationObject->byteLength()] attachment: authenticatorAttachmentToWKAuthenticatorAttachment(attachment)]);
     870    auto value = adoptNS([[_WKAuthenticatorAttestationResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensions:wkExtensionsClientOutputs(data) attestationObject:[NSData dataWithBytes:data.attestationObject->data() length:data.attestationObject->byteLength()] attachment: authenticatorAttachmentToWKAuthenticatorAttachment(attachment) transports:wkTransports(data.transports).autorelease()]);
     871   
     872    return value;
    854873}
    855874#endif
     
    912931static RetainPtr<_WKAuthenticatorAssertionResponse> wkAuthenticatorAssertionResponse(const WebCore::AuthenticatorResponseData& data, NSData *clientDataJSON, WebCore::AuthenticatorAttachment attachment)
    913932{
    914     RetainPtr<_WKAuthenticationExtensionsClientOutputs> extensions;
    915     if (data.appid)
    916         extensions = adoptNS([[_WKAuthenticationExtensionsClientOutputs alloc] initWithAppid:data.appid.value()]);
    917 
    918933    NSData *userHandle = nil;
    919934    if (data.userHandle)
    920935        userHandle = [NSData dataWithBytes:data.userHandle->data() length:data.userHandle->byteLength()];
    921936
    922     return adoptNS([[_WKAuthenticatorAssertionResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensions:WTFMove(extensions) authenticatorData:[NSData dataWithBytes:data.authenticatorData->data() length:data.authenticatorData->byteLength()] signature:[NSData dataWithBytes:data.signature->data() length:data.signature->byteLength()] userHandle:userHandle attachment:authenticatorAttachmentToWKAuthenticatorAttachment(attachment)]);
     937    return adoptNS([[_WKAuthenticatorAssertionResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensions:wkExtensionsClientOutputs(data) authenticatorData:[NSData dataWithBytes:data.authenticatorData->data() length:data.authenticatorData->byteLength()] signature:[NSData dataWithBytes:data.signature->data() length:data.signature->byteLength()] userHandle:userHandle attachment:authenticatorAttachmentToWKAuthenticatorAttachment(attachment)]);
    923938}
    924939#endif
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm

    r292882 r292913  
    2929#if ENABLE(WEB_AUTHN)
    3030
     31#import "AuthenticationServicesCoreSoftLink.h"
    3132#import <Security/SecItem.h>
    3233#import <WebCore/AuthenticatorAssertionResponse.h>
     
    6162    return nullString();
    6263}
     64static bool shouldUpdateQuery()
     65{
     66    return false;
     67}
    6368#endif
    6469
     
    180185    }
    181186    return result;
     187}
     188
     189static Vector<AuthenticatorTransport> transports()
     190{
     191    Vector<WebCore::AuthenticatorTransport> transports = { WebCore::AuthenticatorTransport::Internal };
     192    if (shouldUpdateQuery())
     193        transports.append(WebCore::AuthenticatorTransport::Cable);
     194    return transports;
    182195}
    183196
     
    427440        auto authData = buildAuthData(creationOptions.rp.id, flags, counter, buildAttestedCredentialData(Vector<uint8_t>(aaguidLength, 0), credentialId, cosePublicKey));
    428441        auto attestationObject = buildAttestationObject(WTFMove(authData), String { emptyString() }, { }, AttestationConveyancePreference::None);
    429         receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform));
     442        receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports()));
    430443        return;
    431444    }
     
    454467        LOG_ERROR("Couldn't attest: %s", String(error.localizedDescription).utf8().data());
    455468        auto attestationObject = buildAttestationObject(WTFMove(authData), String { emptyString() }, { }, AttestationConveyancePreference::None);
    456         receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform));
     469        receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports()));
    457470        return;
    458471    }
     
    473486
    474487    deleteDuplicateCredential();
    475     receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform));
     488    receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports()));
    476489}
    477490
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm

    r292197 r292913  
    155155                transportString = @"internal";
    156156                break;
     157            case AuthenticatorTransport::Cable:
     158                transportString = @"cable";
     159                break;
    157160            }
    158161
     
    338341}
    339342
     343static Vector<WebCore::AuthenticatorTransport> toAuthenticatorTransports(NSArray<NSNumber *> *ascTransports)
     344{
     345    Vector<WebCore::AuthenticatorTransport> transports;
     346    transports.reserveInitialCapacity(ascTransports.count);
     347    for (NSNumber *ascTransport : ascTransports) {
     348        if (WTF::isValidEnum<WebCore::AuthenticatorTransport>(ascTransport.intValue))
     349            transports.uncheckedAppend(static_cast<WebCore::AuthenticatorTransport>(ascTransport.intValue));
     350    }
     351    return transports;
     352}
     353
    340354RetainPtr<ASCCredentialRequestContext> WebAuthenticatorCoordinatorProxy::contextForRequest(WebAuthenticationRequestData&& requestData)
    341355{
     
    362376        response.rawId = toArrayBuffer(registrationCredential.credentialID);
    363377        response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
     378        if ([registrationCredential respondsToSelector:@selector(transports)])
     379            response.transports = toAuthenticatorTransports(registrationCredential.transports);
    364380    } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialRegistrationClass()]) {
    365381        attachment = AuthenticatorAttachment::CrossPlatform;
     
    369385        response.rawId = toArrayBuffer(registrationCredential.credentialID);
    370386        response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
     387        if ([registrationCredential respondsToSelector:@selector(transports)])
     388            response.transports = toAuthenticatorTransports(registrationCredential.transports);
    371389    } else if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialAssertionClass()]) {
    372390        attachment = AuthenticatorAttachment::Platform;
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp

    r292710 r292913  
    115115void CtapAuthenticator::continueMakeCredentialAfterResponseReceived(Vector<uint8_t>&& data)
    116116{
    117     auto response = readCTAPMakeCredentialResponse(data, AuthenticatorAttachment::CrossPlatform, std::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation);
     117    auto response = readCTAPMakeCredentialResponse(data, AuthenticatorAttachment::CrossPlatform, transports(), std::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation);
    118118    if (!response) {
    119119        auto error = getResponseCode(data);
     
    385385}
    386386
     387Vector<AuthenticatorTransport> CtapAuthenticator::transports() const
     388{
     389   
     390    if (auto& infoTransports = m_info.transports())
     391        return *infoTransports;
     392    return Vector { driver().transport() };
     393}
     394
    387395} // namespace WebKit
    388396
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h

    r260970 r292913  
    7171    bool processGoogleLegacyAppIdSupportExtension();
    7272
     73    Vector<WebCore::AuthenticatorTransport> transports() const;
     74
    7375    fido::AuthenticatorGetInfoResponse m_info;
    7476    bool m_isDowngraded { false };
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapDriver.h

    r251295 r292913  
    2828#if ENABLE(WEB_AUTHN)
    2929
     30#include <WebCore/AuthenticatorTransport.h>
    3031#include <WebCore/FidoConstants.h>
    3132#include <wtf/Forward.h>
     
    4647    void setProtocol(fido::ProtocolVersion protocol) { m_protocol = protocol; }
    4748
     49    WebCore::AuthenticatorTransport transport() const { return m_transport; }
     50    fido::ProtocolVersion protocol() const { return m_protocol; }
     51
    4852    virtual void transact(Vector<uint8_t>&& data, ResponseCallback&&) = 0;
    4953    virtual void cancel() { };
    5054
    5155protected:
    52     CtapDriver() = default;
    53     fido::ProtocolVersion protocol() const { return m_protocol; }
     56    CtapDriver(WebCore::AuthenticatorTransport transport)
     57        : m_transport(transport) { }
    5458
    5559private:
    5660    fido::ProtocolVersion m_protocol { fido::ProtocolVersion::kCtap };
     61    WebCore::AuthenticatorTransport m_transport;
    5762};
    5863
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidDriver.cpp

    r284009 r292913  
    158158
    159159CtapHidDriver::CtapHidDriver(UniqueRef<HidConnection>&& connection)
    160     : m_worker(makeUniqueRef<Worker>(WTFMove(connection)))
     160    : CtapDriver(WebCore::AuthenticatorTransport::Usb)
     161    , m_worker(makeUniqueRef<Worker>(WTFMove(connection)))
    161162    , m_nonce(kHidInitNonceLength)
    162163{
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp

    r251645 r292913  
    3838
    3939CtapNfcDriver::CtapNfcDriver(Ref<NfcConnection>&& connection)
    40     : m_connection(WTFMove(connection))
     40    : CtapDriver(AuthenticatorTransport::Nfc)
     41    , m_connection(WTFMove(connection))
    4142{
    4243}
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp

    r285698 r292913  
    158158        auto& options = std::get<PublicKeyCredentialCreationOptions>(requestData().options);
    159159        auto appId = processGoogleLegacyAppIdSupportExtension(options.extensions);
    160         auto response = readU2fRegisterResponse(!appId ? options.rp.id : appId, apduResponse.data(), AuthenticatorAttachment::CrossPlatform, options.attestation);
     160        auto response = readU2fRegisterResponse(!appId ? options.rp.id : appId, apduResponse.data(), AuthenticatorAttachment::CrossPlatform, { driver().transport() }, options.attestation);
    161161        if (!response) {
    162162            receiveRespond(ExceptionData { UnknownError, "Couldn't parse the U2F register response."_s });
  • trunk/Tools/ChangeLog

    r292898 r292913  
     12022-04-15  J Pascoe  <j_pascoe@apple.com>
     2
     3        [WebAuthn] Implement getTransports() and getAuthenticatorData() on AuthenticatorAttestationResponse
     4        https://bugs.webkit.org/show_bug.cgi?id=238966
     5        rdar://problem/91449906
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add tests for parsing transports from getInfo.
     10
     11        * TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:
     12        (TestWebKitAPI::TEST):
     13        * TestWebKitAPI/Tests/WebCore/FidoTestData.h:
     14
    1152022-04-14  Wenson Hsieh  <wenson_hsieh@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp

    r292251 r292913  
    3535#include <JavaScriptCore/ArrayBuffer.h>
    3636#include <WebCore/AuthenticatorAttachment.h>
     37#include <WebCore/AuthenticatorTransport.h>
    3738#include <WebCore/BufferSource.h>
    3839#include <WebCore/CBORReader.h>
     
    354355TEST(CTAPResponseTest, TestReadMakeCredentialResponse)
    355356{
    356     auto makeCredentialResponse = readCTAPMakeCredentialResponse(convertBytesToVector(TestData::kTestMakeCredentialResponse, sizeof(TestData::kTestMakeCredentialResponse)), AuthenticatorAttachment::CrossPlatform);
     357    auto makeCredentialResponse = readCTAPMakeCredentialResponse(convertBytesToVector(TestData::kTestMakeCredentialResponse, sizeof(TestData::kTestMakeCredentialResponse)), AuthenticatorAttachment::CrossPlatform, { });
    357358    ASSERT_TRUE(makeCredentialResponse);
    358     auto cborAttestationObject = cbor::CBORReader::read(convertBytesToVector(reinterpret_cast<uint8_t*>(makeCredentialResponse->attestationObject()->data()), makeCredentialResponse->attestationObject()->byteLength()));
     359    auto cborAttestationObject = cbor::CBORReader::read(convertArrayBufferToVector(makeCredentialResponse->attestationObject()));
    359360    ASSERT_TRUE(cborAttestationObject);
    360361    ASSERT_TRUE(cborAttestationObject->isMap());
     
    611612}
    612613
     614TEST(CTAPResponseTest, TestReadGetInfoResponseDeviceYubikey5c)
     615{
     616    auto getInfoResponse = readCTAPGetInfoResponse(convertBytesToVector(TestData::kTestGetInfoResponseDeviceYubikey5c, sizeof(TestData::kTestGetInfoResponseDeviceYubikey5c)));
     617    ASSERT_TRUE(getInfoResponse);
     618    ASSERT_TRUE(getInfoResponse->maxMsgSize());
     619    EXPECT_EQ(*getInfoResponse->maxMsgSize(), 1200u);
     620    EXPECT_NE(getInfoResponse->versions().find(ProtocolVersion::kCtap), getInfoResponse->versions().end());
     621    EXPECT_NE(getInfoResponse->versions().find(ProtocolVersion::kU2f), getInfoResponse->versions().end());
     622    EXPECT_FALSE(getInfoResponse->options().isPlatformDevice());
     623    EXPECT_EQ(AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported, getInfoResponse->options().residentKeyAvailability());
     624    EXPECT_TRUE(getInfoResponse->options().userPresenceRequired());
     625    EXPECT_EQ(AuthenticatorSupportedOptions::UserVerificationAvailability::kNotSupported, getInfoResponse->options().userVerificationAvailability());
     626    EXPECT_EQ(AuthenticatorSupportedOptions::ClientPinAvailability::kSupportedAndPinSet, getInfoResponse->options().clientPinAvailability());
     627    EXPECT_TRUE(getInfoResponse->transports());
     628    EXPECT_EQ(getInfoResponse->transports()->size(), 1u);
     629    EXPECT_EQ(AuthenticatorTransport::Usb, getInfoResponse->transports()->first());
     630}
     631
    613632TEST(CTAPResponseTest, TestReadGetInfoResponseWithIncorrectFormat)
    614633{
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoTestData.h

    r292251 r292913  
    14471447};
    14481448
     1449constexpr uint8_t kTestGetInfoResponseDeviceYubikey5c[] = {
     1450    // Success
     1451    0x00,
     1452    0xAA, 0x01, 0x83, 0x66, 0x55, 0x32, 0x46, 0x5F, 0x56, 0x32, 0x68, 0x46,
     1453    0x49, 0x44, 0x4F, 0x5F, 0x32, 0x5F, 0x30, 0x6C, 0x46, 0x49, 0x44, 0x4F,
     1454    0x5F, 0x32, 0x5F, 0x31, 0x5F, 0x50, 0x52, 0x45, 0x02, 0x82, 0x6B, 0x63,
     1455    0x72, 0x65, 0x64, 0x50, 0x72, 0x6F, 0x74, 0x65, 0x63, 0x74, 0x6B, 0x68,
     1456    0x6D, 0x61, 0x63, 0x2D, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x03, 0x50,
     1457    0xEE, 0x88, 0x28, 0x79, 0x72, 0x1C, 0x49, 0x13, 0x97, 0x75, 0x3D, 0xFC,
     1458    0xCE, 0x97, 0x07, 0x2A, 0x04, 0xA5, 0x62, 0x72, 0x6B, 0xF5, 0x62, 0x75,
     1459    0x70, 0xF5, 0x64, 0x70, 0x6C, 0x61, 0x74, 0xF4, 0x69, 0x63, 0x6C, 0x69,
     1460    0x65, 0x6E, 0x74, 0x50, 0x69, 0x6E, 0xF5, 0x75, 0x63, 0x72, 0x65, 0x64,
     1461    0x65, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x4D, 0x67, 0x6D, 0x74, 0x50, 0x72,
     1462    0x65, 0x76, 0x69, 0x65, 0x77, 0xF5, 0x05, 0x19, 0x04, 0xB0, 0x06, 0x81,
     1463    0x01,
     1464    // key(07) - maxCredentialCountInList
     1465    0x07,
     1466    // value - unsigned(8)
     1467    0x08,
     1468    // key(08) - maxCredentialIdLength
     1469    0x08,
     1470    // value - unsigned(128)
     1471    0x18, 0x80,
     1472    // key(09) - transports
     1473    0x09,
     1474    // array(1)
     1475    0x81,
     1476    // text(3) - "usb"
     1477    0x63, 0x75, 0x73, 0x62,
     1478    0x0A, 0x82, 0xA2, 0x63, 0x61, 0x6C, 0x67, 0x26, 0x64, 0x74, 0x79, 0x70,
     1479    0x65, 0x6A, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79,
     1480    0xA2, 0x63, 0x61, 0x6C, 0x67, 0x27, 0x64, 0x74, 0x79, 0x70, 0x65, 0x6A,
     1481    0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79,
     1482};
     1483
    14491484} // namespace TestData
    14501485
Note: See TracChangeset for help on using the changeset viewer.