Title: [295407] trunk/Source
Revision
295407
Author
[email protected]
Date
2022-06-08 17:55:13 -0700 (Wed, 08 Jun 2022)

Log Message

[WebAuthn] Support credProps extension and refactor extension handling
https://bugs.webkit.org/show_bug.cgi?id=241199
rdar://90281799

Reviewed by Brent Fulgham.

This patch implements the credProps Web Authentication extension specified here:
https://www.w3.org/TR/webauthn-2/#sctn-authenticator-credential-properties-extension

This extension provides information about the created credential to the relying party,
at this time this is only the resident key credential property. This is useful information
for RPs to enable passwordless flows.

The patch also refactors how we ferry extension inputs/outputs between WebKit and Authentication
Services. We now passthrough inputs and outputs as a cbor serialized blob. This is well specified
as described here: https://www.w3.org/TR/webauthn-2/#sctn-extensions-inputs-outputs

This extension is covered by the web platform test webauthn/createcredential-resident-key.https.html.

* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp: Added.
(WebCore::AuthenticationExtensionsClientInputs::fromCBOR):
(WebCore::AuthenticationExtensionsClientInputs::toCBOR const):
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h:
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.idl:
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cpp: Added.
(WebCore::AuthenticationExtensionsClientOutputs::fromCBOR):
(WebCore::AuthenticationExtensionsClientOutputs::toCBOR const):
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.h:
(WebCore::AuthenticationExtensionsClientOutputs::encode const):
(WebCore::AuthenticationExtensionsClientOutputs::decode):
(WebCore::AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput::encode const):
(WebCore::AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput::decode):
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.idl:
* Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::create const):
* Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp:
(WebCore::AuthenticatorResponse::tryCreate):
(WebCore::AuthenticatorResponse::data const):
* Source/WebCore/Modules/webauthn/AuthenticatorResponse.h:
* Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h:
(WebCore::AuthenticatorResponseData::encode const):
(WebCore::AuthenticatorResponseData::decode):
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponse.mm:
(-[_WKAuthenticatorAssertionResponse initWithClientDataJSON:rawId:extensionOutputsCBOR:authenticatorData:signature:userHandle:attachment:]):
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm:
(-[_WKAuthenticatorAttestationResponse initWithClientDataJSON:rawId:extensionOutputsCBOR:attestationObject:attachment:transports:]):
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.mm:
(-[_WKAuthenticatorResponse initWithClientDataJSON:rawId:extensionOutputsCBOR:attachment:]):
* Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponseInternal.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.mm:
(-[_WKPublicKeyCredentialCreationOptions dealloc]):
* Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.mm:
(-[_WKPublicKeyCredentialRequestOptions dealloc]):
* Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(toNSData):
(+[_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:]):
(wkAuthenticatorAttestationResponse):
(wkAuthenticatorAssertionResponse):
(wkExtensionsClientOutputs): Deleted.
* Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h:
* Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:
(WebKit::LocalAuthenticator::processClientExtensions):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification):
(WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested):
(WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification):
* Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
(WebKit::configureRegistrationRequestContext):
(WebKit::configureAssertionOptions):
(WebKit::toExtensionOutputs):
(WebKit::continueAfterRequest):
* Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
(WebKit::CtapAuthenticator::continueMakeCredentialAfterResponseReceived):

Canonical link: https://commits.webkit.org/251413@main

Modified Paths

Added Paths

Diff

Added: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp (0 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp	                        (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AuthenticationExtensionsClientInputs.h"
+
+#if ENABLE(WEB_AUTHN)
+
+#include "CBORReader.h"
+#include "CBORWriter.h"
+
+namespace WebCore {
+
+std::optional<AuthenticationExtensionsClientInputs> AuthenticationExtensionsClientInputs::fromCBOR(const Vector<uint8_t>& buffer)
+{
+    std::optional<cbor::CBORValue> decodedValue = cbor::CBORReader::read(buffer);
+    if (!decodedValue || !decodedValue->isMap())
+        return std::nullopt;
+    AuthenticationExtensionsClientInputs clientInputs;
+
+    const auto& decodedMap = decodedValue->getMap();
+    auto it = decodedMap.find(cbor::CBORValue("appid"));
+    if (it != decodedMap.end() && it->second.isString())
+        clientInputs.appid = it->second.getString();
+    it = decodedMap.find(cbor::CBORValue("googleLegacyAppidSupport"));
+    if (it != decodedMap.end() && it->second.isBool())
+        clientInputs.googleLegacyAppidSupport = it->second.getBool();
+    it = decodedMap.find(cbor::CBORValue("credProps"));
+    if (it != decodedMap.end() && it->second.isBool())
+        clientInputs.credProps = it->second.getBool();
+    return clientInputs;
+}
+
+Vector<uint8_t> AuthenticationExtensionsClientInputs::toCBOR() const
+{
+    cbor::CBORValue::MapValue clientInputsMap;
+    if (!appid.isEmpty())
+        clientInputsMap[cbor::CBORValue("appid")] = cbor::CBORValue(appid);
+    if (googleLegacyAppidSupport)
+        clientInputsMap[cbor::CBORValue("googleLegacyAppidSupport")] = cbor::CBORValue(googleLegacyAppidSupport);
+    if (credProps)
+        clientInputsMap[cbor::CBORValue("credProps")] = cbor::CBORValue(credProps);
+
+    auto clientInputs = cbor::CBORWriter::write(cbor::CBORValue(WTFMove(clientInputsMap)));
+    ASSERT(clientInputs);
+
+    return *clientInputs;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -34,9 +34,13 @@
 struct AuthenticationExtensionsClientInputs {
     String appid;
     bool googleLegacyAppidSupport;
+    bool credProps;
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static std::optional<AuthenticationExtensionsClientInputs> decode(Decoder&);
+
+    WEBCORE_EXPORT Vector<uint8_t> toCBOR() const;
+    WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientInputs> fromCBOR(const Vector<uint8_t>&);
 };
 
 template<class Encoder>

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.idl (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.idl	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.idl	2022-06-09 00:55:13 UTC (rev 295407)
@@ -29,4 +29,5 @@
     USVString appid;
     // For Google to turn off the legacy AppID support.
     boolean googleLegacyAppidSupport = true;
+    boolean credProps;
 };

Added: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cpp (0 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cpp	                        (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AuthenticationExtensionsClientOutputs.h"
+
+#if ENABLE(WEB_AUTHN)
+
+#include "CBORReader.h"
+#include "CBORWriter.h"
+
+namespace WebCore {
+
+std::optional<AuthenticationExtensionsClientOutputs> AuthenticationExtensionsClientOutputs::fromCBOR(const Vector<uint8_t>& buffer)
+{
+    std::optional<cbor::CBORValue> decodedValue = cbor::CBORReader::read(buffer);
+    if (!decodedValue || !decodedValue->isMap())
+        return std::nullopt;
+    AuthenticationExtensionsClientOutputs clientOutputs;
+
+    const auto& decodedMap = decodedValue->getMap();
+    auto it = decodedMap.find(cbor::CBORValue("appid"));
+    if (it != decodedMap.end() && it->second.isBool())
+        clientOutputs.appid = it->second.getBool();
+    it = decodedMap.find(cbor::CBORValue("credProps"));
+    if (it != decodedMap.end() && it->second.isMap()) {
+        CredentialPropertiesOutput credProps;
+        it = it->second.getMap().find(cbor::CBORValue("rk"));
+        if (it != decodedMap.end() && it->second.isBool())
+            credProps.rk = it->second.getBool();
+        clientOutputs.credProps = credProps;
+    }
+
+    return clientOutputs;
+}
+
+Vector<uint8_t> AuthenticationExtensionsClientOutputs::toCBOR() const
+{
+    cbor::CBORValue::MapValue clientOutputsMap;
+    if (appid)
+        clientOutputsMap[cbor::CBORValue("appid")] = cbor::CBORValue(*appid);
+    if (credProps) {
+        cbor::CBORValue::MapValue credPropsMap;
+        credPropsMap[cbor::CBORValue("rk")] = cbor::CBORValue(credProps->rk);
+        clientOutputsMap[cbor::CBORValue("credProps")] = cbor::CBORValue(credPropsMap);
+    }
+
+    auto clientOutputs = cbor::CBORWriter::write(cbor::CBORValue(WTFMove(clientOutputsMap)));
+    ASSERT(clientOutputs);
+
+    return *clientOutputs;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.h (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -27,14 +27,74 @@
 
 #if ENABLE(WEB_AUTHN)
 
+#include "CBORReader.h"
+#include "CBORWriter.h"
 #include <optional>
 
 namespace WebCore {
 
 struct AuthenticationExtensionsClientOutputs {
+    struct CredentialPropertiesOutput {
+        bool rk;
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static std::optional<CredentialPropertiesOutput> decode(Decoder&);
+    };
     std::optional<bool> appid;
+    std::optional<CredentialPropertiesOutput> credProps;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<AuthenticationExtensionsClientOutputs> decode(Decoder&);
+
+    WEBCORE_EXPORT Vector<uint8_t> toCBOR() const;
+    WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientOutputs> fromCBOR(const Vector<uint8_t>&);
 };
 
+template<class Encoder>
+void AuthenticationExtensionsClientOutputs::encode(Encoder& encoder) const
+{
+    encoder << appid << credProps;
+}
+
+template<class Decoder>
+std::optional<AuthenticationExtensionsClientOutputs> AuthenticationExtensionsClientOutputs::decode(Decoder& decoder)
+{
+    AuthenticationExtensionsClientOutputs result;
+
+    std::optional<std::optional<bool>> appid;
+    decoder >> appid;
+    if (!appid)
+        return std::nullopt;
+    result.appid = WTFMove(*appid);
+
+    std::optional<std::optional<CredentialPropertiesOutput>> credProps;
+    decoder >> credProps;
+    if (!credProps)
+        return std::nullopt;
+    result.credProps = WTFMove(*credProps);
+
+    return result;
+}
+
+template<class Encoder>
+void AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput::encode(Encoder& encoder) const
+{
+    encoder << rk;
+}
+
+template<class Decoder>
+std::optional<AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput> AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput::decode(Decoder& decoder)
+{
+    CredentialPropertiesOutput result;
+
+    std::optional<bool> rk;
+    decoder >> rk;
+    if (!rk)
+        return std::nullopt;
+    result.rk = *rk;
+
+    return result;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.idl (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.idl	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.idl	2022-06-09 00:55:13 UTC (rev 295407)
@@ -22,6 +22,12 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
+[
+    Conditional=WEB_AUTHN,
+    JSGenerateToJSObject,
+] dictionary CredentialPropertiesOutput {
+    boolean rk;
+};
 
 [
     Conditional=WEB_AUTHN,
@@ -28,4 +34,5 @@
     JSGenerateToJSObject,
 ] dictionary AuthenticationExtensionsClientOutputs {
     boolean appid;
+    CredentialPropertiesOutput credProps;
 };

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -155,7 +155,7 @@
 
     // Step 11-12.
     // Only Google Legacy AppID Support Extension is supported.
-    options.extensions = AuthenticationExtensionsClientInputs { String(), processGoogleLegacyAppIdSupportExtension(options.extensions, options.rp.id) };
+    options.extensions = AuthenticationExtensionsClientInputs { String(), processGoogleLegacyAppIdSupportExtension(options.extensions, options.rp.id), options.extensions && options.extensions->credProps };
 
     // Step 13-15.
     auto clientDataJson = buildClientDataJson(ClientDataType::Create, options.challenge, callerOrigin, scope);

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -43,13 +43,16 @@
         if (!data.attestationObject)
             return nullptr;
 
-        return AuthenticatorAttestationResponse::create(data.rawId.releaseNonNull(), data.attestationObject.releaseNonNull(), attachment, WTFMove(data.transports));
+        auto response = AuthenticatorAttestationResponse::create(data.rawId.releaseNonNull(), data.attestationObject.releaseNonNull(), attachment, WTFMove(data.transports));
+        if (data.extensionOutputs)
+            response->setExtensions(WTFMove(*data.extensionOutputs));
+        return WTFMove(response);
     }
 
     if (!data.authenticatorData || !data.signature)
         return nullptr;
 
-    return AuthenticatorAssertionResponse::create(data.rawId.releaseNonNull(), data.authenticatorData.releaseNonNull(), data.signature.releaseNonNull(), WTFMove(data.userHandle), AuthenticationExtensionsClientOutputs { data.appid }, attachment);
+    return AuthenticatorAssertionResponse::create(data.rawId.releaseNonNull(), data.authenticatorData.releaseNonNull(), data.signature.releaseNonNull(), WTFMove(data.userHandle), WTFMove(data.extensionOutputs), attachment);
 }
 
 AuthenticatorResponseData AuthenticatorResponse::data() const
@@ -56,7 +59,7 @@
 {
     AuthenticatorResponseData data;
     data.rawId = m_rawId.copyRef();
-    data.appid = m_extensions.appid;
+    data.extensionOutputs = m_extensions;
     return data;
 }
 

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -54,7 +54,7 @@
 
     WEBCORE_EXPORT ArrayBuffer* rawId() const;
     WEBCORE_EXPORT void setExtensions(AuthenticationExtensionsClientOutputs&&);
-    AuthenticationExtensionsClientOutputs extensions() const;
+    WEBCORE_EXPORT AuthenticationExtensionsClientOutputs extensions() const;
     void setClientDataJSON(Ref<ArrayBuffer>&&);
     ArrayBuffer* clientDataJSON() const;
     WEBCORE_EXPORT AuthenticatorAttachment attachment() const;

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h (295406 => 295407)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEB_AUTHN)
 
+#include "AuthenticationExtensionsClientOutputs.h"
 #include "AuthenticatorTransport.h"
 #include <_javascript_Core/ArrayBuffer.h>
 #include <wtf/Forward.h>
@@ -42,7 +43,7 @@
     RefPtr<ArrayBuffer> rawId;
 
     // Extensions
-    std::optional<bool> appid;
+    std::optional<AuthenticationExtensionsClientOutputs> extensionOutputs;
 
     // AuthenticatorAttestationResponse
     RefPtr<ArrayBuffer> attestationObject;
@@ -92,6 +93,7 @@
     }
     encoder << false;
     encodeArrayBuffer(encoder, *rawId);
+    encoder << extensionOutputs;
 
     encoder << isAuthenticatorAttestationResponse;
 
@@ -106,9 +108,6 @@
     encodeArrayBuffer(encoder, *authenticatorData);
     encodeArrayBuffer(encoder, *signature);
 
-    // Encode AppID before user handle to avoid the userHandle flag.
-    encoder << appid;
-
     if (!userHandle) {
         encoder << false;
         return;
@@ -132,6 +131,12 @@
     result.rawId = decodeArrayBuffer(decoder);
     if (!result.rawId)
         return std::nullopt;
+    
+    std::optional<std::optional<AuthenticationExtensionsClientOutputs>> extensionOutputs;
+    decoder >> extensionOutputs;
+    if (!extensionOutputs)
+        return std::nullopt;
+    result.extensionOutputs = WTFMove(*extensionOutputs);
 
     std::optional<bool> isAuthenticatorAttestationResponse;
     decoder >> isAuthenticatorAttestationResponse;
@@ -160,12 +165,6 @@
     if (!result.signature)
         return std::nullopt;
 
-    std::optional<std::optional<bool>> appid;
-    decoder >> appid;
-    if (!appid)
-        return std::nullopt;
-    result.appid = WTFMove(*appid);
-
     std::optional<bool> hasUserHandle;
     decoder >> hasUserHandle;
     if (!hasUserHandle)

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (295406 => 295407)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-06-09 00:55:13 UTC (rev 295407)
@@ -1756,6 +1756,8 @@
 		5273CCB32564576F00850007 /* JSFakeXRRigidTransformInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5273CCAE2564576D00850007 /* JSFakeXRRigidTransformInit.cpp */; };
 		5273CCB42564576F00850007 /* JSFakeXRViewInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5273CCAF2564576E00850007 /* JSFakeXRViewInit.cpp */; };
 		52A0BE6627C227E10046611E /* JSFakeXRJointStateInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A0BE6527C227E00046611E /* JSFakeXRJointStateInit.cpp */; };
+		52B07441284680CA00511B65 /* AuthenticationExtensionsClientInputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B07440284680C900511B65 /* AuthenticationExtensionsClientInputs.cpp */; };
+		52B074432846810A00511B65 /* AuthenticationExtensionsClientOutputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B074422846810A00511B65 /* AuthenticationExtensionsClientOutputs.cpp */; };
 		52B0D4BE1C57FD1E0077CE53 /* PlatformView.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52B0D4C01C57FD660077CE53 /* VideoFullscreenChangeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B0D4BF1C57FD660077CE53 /* VideoFullscreenChangeObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52B0D4C21C57FF910077CE53 /* VideoFullscreenInterfaceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B0D4C11C57FF910077CE53 /* VideoFullscreenInterfaceMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -10127,6 +10129,8 @@
 		5273CCAE2564576D00850007 /* JSFakeXRRigidTransformInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFakeXRRigidTransformInit.cpp; sourceTree = "<group>"; };
 		5273CCAF2564576E00850007 /* JSFakeXRViewInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFakeXRViewInit.cpp; sourceTree = "<group>"; };
 		52A0BE6527C227E00046611E /* JSFakeXRJointStateInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFakeXRJointStateInit.cpp; sourceTree = "<group>"; };
+		52B07440284680C900511B65 /* AuthenticationExtensionsClientInputs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AuthenticationExtensionsClientInputs.cpp; sourceTree = "<group>"; };
+		52B074422846810A00511B65 /* AuthenticationExtensionsClientOutputs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AuthenticationExtensionsClientOutputs.cpp; sourceTree = "<group>"; };
 		52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformView.h; sourceTree = "<group>"; };
 		52B0D4BF1C57FD660077CE53 /* VideoFullscreenChangeObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenChangeObserver.h; sourceTree = "<group>"; };
 		52B0D4C11C57FF910077CE53 /* VideoFullscreenInterfaceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenInterfaceMac.h; sourceTree = "<group>"; };
@@ -23416,8 +23420,10 @@
 				578A4BFA2166AE0000D08F34 /* fido */,
 				57D135212294973400827401 /* AttestationConveyancePreference.h */,
 				57D135232294973400827401 /* AttestationConveyancePreference.idl */,
+				52B07440284680C900511B65 /* AuthenticationExtensionsClientInputs.cpp */,
 				57DA47A522401E0F002A4612 /* AuthenticationExtensionsClientInputs.h */,
 				57DA47A722401E0F002A4612 /* AuthenticationExtensionsClientInputs.idl */,
+				52B074422846810A00511B65 /* AuthenticationExtensionsClientOutputs.cpp */,
 				57585965239F14CC00C74572 /* AuthenticationExtensionsClientOutputs.h */,
 				57585967239F14CD00C74572 /* AuthenticationExtensionsClientOutputs.idl */,
 				5758596E239F397900C74572 /* AuthenticatorAssertionResponse.cpp */,
@@ -39073,6 +39079,8 @@
 				CD0EEE0E14743F39003EAFA2 /* AudioOutputUnitAdaptorIOS.cpp in Sources */,
 				CDA79827170A279100D45C55 /* AudioSessionIOS.mm in Sources */,
 				CD8A7BBB197735FE00CBD643 /* AudioSourceProviderAVFObjC.mm in Sources */,
+				52B07441284680CA00511B65 /* AuthenticationExtensionsClientInputs.cpp in Sources */,
+				52B074432846810A00511B65 /* AuthenticationExtensionsClientOutputs.cpp in Sources */,
 				46BA49B827BB44330077F63F /* AVAssetTrackUtilities.mm in Sources */,
 				0FCA293526FC3917006B4AEB /* AVAudioSessionCaptureDeviceManager.mm in Sources */,
 				0738E5EC2499839000DA101C /* AVOutputDeviceMenuControllerTargetPicker.mm in Sources */,

Modified: trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h (295406 => 295407)


--- trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -164,6 +164,7 @@
 @property (nonatomic, nullable, copy) NSData *clientDataHash;
 @property (nonatomic, nullable, readonly, copy) NSString *userVerificationPreference;
 @property (nonatomic, nullable, copy) ASCWebAuthenticationExtensionsClientInputs *extensions;
+@property (nonatomic, nullable, copy) NSData *extensionsCBOR;
 @property (nonatomic, nullable, copy) NSNumber *timeout;
 
 @property (nonatomic, nullable, readonly, copy) NSArray<ASCPublicKeyCredentialDescriptor *> *allowedCredentials;
@@ -202,6 +203,7 @@
 @property (nonatomic, nullable, copy) NSString *userVerificationPreference;
 @property (nonatomic, nullable, copy) NSString *attestationPreference;
 @property (nonatomic, nullable, copy) ASCWebAuthenticationExtensionsClientInputs *extensions;
+@property (nonatomic, nullable, copy) NSData *extensionsCBOR;
 @property (nonatomic, nullable, copy) NSNumber *timeout;
 
 @property (nonatomic) BOOL shouldRequireResidentKey;
@@ -291,6 +293,7 @@
 @property (nonatomic, copy, readonly) NSData *attestationObject;
 @property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
 @property (nonatomic, copy) NSArray<NSNumber *> *transports;
+@property (nonatomic, copy, nullable) NSData *extensionOutputsCBOR;
 
 + (instancetype)new NS_UNAVAILABLE;
 - (instancetype)init NS_UNAVAILABLE;
@@ -306,6 +309,7 @@
 @property (nonatomic, copy, readonly) NSString *relyingPartyIdentifier;
 @property (nonatomic, copy, readonly) NSData *attestationObject;
 @property (nonatomic, copy) NSArray<NSNumber *> *transports;
+@property (nonatomic, copy, readonly, nullable) NSData *extensionOutputsCBOR;
 
 @end
 
@@ -321,6 +325,7 @@
 @property (nonatomic, copy, readonly) NSData *authenticatorData;
 @property (nonatomic, copy, readonly) NSData *signature;
 @property (nonatomic, copy, readonly, nullable) NSData *userHandle;
+@property (nonatomic, copy, readonly, nullable) NSData *extensionOutputsCBOR;
 
 @end
 
@@ -334,6 +339,7 @@
 @property (nonatomic, copy, readonly) NSData *signature;
 @property (nonatomic, copy, readonly, nullable) NSData *userHandle;
 @property (nonatomic, copy, readonly) NSData *rawClientDataJSON;
+@property (nonatomic, copy, readonly, nullable) NSData *extensionOutputsCBOR;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponse.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponse.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponse.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -43,4 +43,15 @@
     return self;
 }
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensionOutputsCBOR authenticatorData:(NSData *)authenticatorData signature:(NSData *)signature userHandle:(NSData *)userHandle attachment:(_WKAuthenticatorAttachment)attachment
+{
+    if (!(self = [super initWithClientDataJSON:clientDataJSON rawId:rawId extensionOutputsCBOR:extensionOutputsCBOR attachment:attachment]))
+        return nil;
+
+    _authenticatorData = authenticatorData;
+    _signature = signature;
+    _userHandle = userHandle;
+    return self;
+}
+
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAssertionResponseInternal.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -36,6 +36,8 @@
 
 - (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions authenticatorData:(NSData *)authenticatorData signature:(NSData *)signature userHandle:(NSData * _Nullable)userHandle attachment:(_WKAuthenticatorAttachment)attachment;
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensionOutputsCBOR authenticatorData:(NSData *)authenticatorData signature:(NSData *)signature userHandle:(NSData * _Nullable)userHandle attachment:(_WKAuthenticatorAttachment)attachment;
+
 @end
 
 NS_ASSUME_NONNULL_END

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponse.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -42,4 +42,14 @@
     return self;
 }
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensionOutputsCBOR attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment transports:(NSArray<NSNumber *> *)transports
+{
+    if (!(self = [super initWithClientDataJSON:clientDataJSON rawId:rawId extensionOutputsCBOR:WTFMove(extensionOutputsCBOR) attachment:attachment]))
+        return nil;
+
+    _attestationObject = attestationObject;
+    _transports = transports;
+    return self;
+}
+
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorAttestationResponseInternal.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -36,6 +36,8 @@
 
 - (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment transports:(NSArray<NSNumber *> *)transports;
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensions attestationObject:(NSData *)attestationObject attachment:(_WKAuthenticatorAttachment)attachment transports:(NSArray<NSNumber *> *)transports;
+
 @end
 
 NS_ASSUME_NONNULL_END

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -41,6 +41,7 @@
 @property (nullable, nonatomic, readonly) NSData *clientDataJSON;
 @property (nonatomic, readonly) NSData *rawId;
 @property (nullable, nonatomic, readonly, strong) _WKAuthenticationExtensionsClientOutputs *extensions;
+@property (nullable, nonatomic, copy) NSData *extensionOutputsCBOR;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponse.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -46,6 +46,19 @@
     return self;
 }
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensionOutputsCBOR attachment:(_WKAuthenticatorAttachment)attachment
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _clientDataJSON = clientDataJSON;
+    _rawId = rawId;
+    _extensionOutputsCBOR = extensionOutputsCBOR;
+    _attachment = attachment;
+
+    return self;
+}
+
 - (_WKAuthenticationExtensionsClientOutputs *)extensions
 {
     return _extensions.get();

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponseInternal.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponseInternal.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKAuthenticatorResponseInternal.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -36,6 +36,7 @@
 
 - (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensions:(RetainPtr<_WKAuthenticationExtensionsClientOutputs>&&)extensions attachment:(_WKAuthenticatorAttachment)attachment;
 
+- (instancetype)initWithClientDataJSON:(NSData *)clientDataJSON rawId:(NSData *)rawId extensionOutputsCBOR:(NSData *)extensionOutputsCBOR attachment:(_WKAuthenticatorAttachment)attachment;
 @end
 
 NS_ASSUME_NONNULL_END

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -63,6 +63,7 @@
 /*!@discussion The default value is _WKAttestationConveyancePrefenprenceNone.*/
 @property (nonatomic) _WKAttestationConveyancePreference attestation;
 @property (nullable, nonatomic, strong) _WKAuthenticationExtensionsClientInputs *extensions;
+@property (nullable, nonatomic, strong) NSData *extensionsCBOR;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialCreationOptions.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -51,6 +51,7 @@
     [_excludeCredentials release];
     [_authenticatorSelection release];
     [_extensions release];
+    [_extensionsCBOR release];
     [super dealloc];
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -47,6 +47,7 @@
 /*!@discussion The default value is _WKAuthenticatorAttachmentAll.*/
 @property (nonatomic) _WKAuthenticatorAttachment authenticatorAttachment;
 @property (nullable, nonatomic, strong) _WKAuthenticationExtensionsClientInputs *extensions;
+@property (nullable, nonatomic, copy) NSData *extensionsCBOR;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKPublicKeyCredentialRequestOptions.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -44,6 +44,7 @@
     [_relyingPartyIdentifier release];
     [_allowCredentials release];
     [_extensions release];
+    [_extensionsCBOR release];
     [super dealloc];
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -42,6 +42,7 @@
 #import "_WKPublicKeyCredentialRequestOptions.h"
 #import "_WKPublicKeyCredentialRelyingPartyEntity.h"
 #import "_WKPublicKeyCredentialUserEntity.h"
+#import <WebCore/AuthenticationExtensionsClientInputs.h>
 #import <WebCore/AuthenticatorAttachment.h>
 #import <WebCore/AuthenticatorResponse.h>
 #import <WebCore/AuthenticatorResponseData.h>
@@ -105,6 +106,11 @@
     crypto->addBytes(clientDataJson.bytes, clientDataJson.length);
     return crypto->computeHash();
 }
+
+static inline RetainPtr<NSData> toNSData(const Vector<uint8_t>& data)
+{
+    return adoptNS([[NSData alloc] initWithBytes:data.data() length:data.size()]);
+}
 #endif
 
 NSString * const _WKLocalAuthenticatorCredentialNameKey = @"_WKLocalAuthenticatorCredentialNameKey";
@@ -825,7 +831,10 @@
     if (options.authenticatorSelection)
         result.authenticatorSelection = authenticatorSelectionCriteria(options.authenticatorSelection);
     result.attestation = attestationConveyancePreference(options.attestation);
-    result.extensions = authenticationExtensionsClientInputs(options.extensions);
+    if (options.extensionsCBOR)
+        result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(vectorFromNSData(options.extensionsCBOR));
+    else
+        result.extensions = authenticationExtensionsClientInputs(options.extensions);
 #endif
 
     return result;
@@ -842,14 +851,6 @@
     }
 }
 
-static RetainPtr<_WKAuthenticationExtensionsClientOutputs> wkExtensionsClientOutputs(const WebCore::AuthenticatorResponseData& data)
-{
-    RetainPtr<_WKAuthenticationExtensionsClientOutputs> extensions;
-    if (data.appid)
-        extensions = adoptNS([[_WKAuthenticationExtensionsClientOutputs alloc] initWithAppid:data.appid.value()]);
-    return extensions;
-}
-
 static RetainPtr<NSArray<NSNumber *>> wkTransports(const Vector<WebCore::AuthenticatorTransport>& transports)
 {
     auto wkTransports = adoptNS([NSMutableArray<NSNumber *> new]);
@@ -861,7 +862,7 @@
 
 static RetainPtr<_WKAuthenticatorAttestationResponse> wkAuthenticatorAttestationResponse(const WebCore::AuthenticatorResponseData& data, NSData *clientDataJSON, WebCore::AuthenticatorAttachment attachment)
 {
-    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()]);
+    auto value = adoptNS([[_WKAuthenticatorAttestationResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensionOutputsCBOR:toNSData(data.extensionOutputs->toCBOR()).autorelease() attestationObject:[NSData dataWithBytes:data.attestationObject->data() length:data.attestationObject->byteLength()] attachment: authenticatorAttachmentToWKAuthenticatorAttachment(attachment) transports:wkTransports(data.transports).autorelease()]);
     
     return value;
 }
@@ -928,7 +929,7 @@
     if (data.userHandle)
         userHandle = [NSData dataWithBytes:data.userHandle->data() length:data.userHandle->byteLength()];
 
-    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)]);
+    return adoptNS([[_WKAuthenticatorAssertionResponse alloc] initWithClientDataJSON:clientDataJSON rawId:[NSData dataWithBytes:data.rawId->data() length:data.rawId->byteLength()] extensionOutputsCBOR:toNSData(data.extensionOutputs->toCBOR()).get() 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)]);
 }
 #endif
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h	2022-06-09 00:55:13 UTC (rev 295407)
@@ -33,6 +33,11 @@
 
 OBJC_CLASS LAContext;
 
+namespace WebCore {
+class AuthenticatorAttestationResponse;
+class AuthenticatorAssertionResponse;
+}
+
 namespace WebKit {
 
 class LocalAuthenticator final : public Authenticator {
@@ -59,6 +64,8 @@
 private:
     explicit LocalAuthenticator(UniqueRef<LocalConnection>&&);
 
+    void processClientExtensions(std::variant<Ref<WebCore::AuthenticatorAttestationResponse>, Ref<WebCore::AuthenticatorAssertionResponse>>);
+
     void makeCredential() final;
     void continueMakeCredentialAfterReceivingLAContext(LAContext *);
     void continueMakeCredentialAfterUserVerification(SecAccessControlRef, LocalConnection::UserVerification, LAContext *);

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -318,6 +318,19 @@
     m_connection->verifyUser(accessControlRef, context, WTFMove(callback));
 }
 
+void LocalAuthenticator::processClientExtensions(std::variant<Ref<AuthenticatorAttestationResponse>, Ref<AuthenticatorAssertionResponse>> response)
+{
+    WTF::switchOn(response, [&](const Ref<AuthenticatorAttestationResponse>& response) {
+        auto& creationOptions = std::get<PublicKeyCredentialCreationOptions>(requestData().options);
+        if (creationOptions.extensions && creationOptions.extensions->credProps) {
+            auto extensionOutputs = response->extensions();
+            
+            extensionOutputs.credProps = AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput { true /* rk */ };
+            response->setExtensions(WTFMove(extensionOutputs));
+        }
+    }, [&](const Ref<AuthenticatorAssertionResponse>& options) { });
+}
+
 void LocalAuthenticator::continueMakeCredentialAfterUserVerification(SecAccessControlRef accessControlRef, LocalConnection::UserVerification verification, LAContext *context)
 {
     using namespace LocalAuthenticatorInternal;
@@ -415,7 +428,9 @@
 
         auto authData = buildAuthData(creationOptions.rp.id, flags, counter, buildAttestedCredentialData(Vector<uint8_t>(aaguidLength, 0), credentialId, cosePublicKey));
         auto attestationObject = buildAttestationObject(WTFMove(authData), String { emptyString() }, { }, AttestationConveyancePreference::None);
-        receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports()));
+        auto response = AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports());
+        processClientExtensions(response);
+        receiveRespond(WTFMove(response));
         return;
     }
 
@@ -461,7 +476,9 @@
     auto attestationObject = buildAttestationObject(WTFMove(authData), "apple"_s, WTFMove(attestationStatementMap), creationOptions.attestation);
 
     deleteDuplicateCredential();
-    receiveRespond(AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports()));
+    auto response = AuthenticatorAttestationResponse::create(credentialId, attestationObject, AuthenticatorAttachment::Platform, transports());
+    processClientExtensions(response);
+    receiveRespond(WTFMove(response));
 }
 
 void LocalAuthenticator::getAssertion()
@@ -622,6 +639,7 @@
     // Step 13.
     response->setAuthenticatorData(WTFMove(authData));
     response->setSignature(toArrayBuffer((NSData *)signature.get()));
+    processClientExtensions(response);
     receiveRespond(WTFMove(response));
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2022-06-09 00:55:13 UTC (rev 295407)
@@ -259,7 +259,17 @@
 
         [credentialCreationOptions setExcludedCredentials:excludedCredentials.get()];
     }
+    
+    if (options.extensions) {
+        if ([credentialCreationOptions respondsToSelector:@selector(setExtensionsCBOR:)])
+            [credentialCreationOptions setExtensionsCBOR:toNSData(options.extensions->toCBOR()).get()];
+        else
+            [credentialCreationOptions setExtensions:toASCExtensions(*options.extensions).get()];
+    }
 
+    if (options.timeout && [credentialCreationOptions respondsToSelector:@selector(setTimeout:)])
+        credentialCreationOptions.get().timeout = [NSNumber numberWithUnsignedInt:*options.timeout];
+
     if (requestTypes & ASCCredentialRequestTypePlatformPublicKeyRegistration)
         [requestContext setPlatformKeyCredentialCreationOptions:credentialCreationOptions.get()];
 
@@ -266,12 +276,6 @@
     if (requestTypes & ASCCredentialRequestTypeSecurityKeyPublicKeyRegistration)
         [requestContext setSecurityKeyCredentialCreationOptions:credentialCreationOptions.get()];
 
-    if (options.extensions)
-        [credentialCreationOptions setExtensions:toASCExtensions(*options.extensions).get()];
-
-    if (options.timeout && [credentialCreationOptions respondsToSelector:@selector(setTimeout:)])
-        credentialCreationOptions.get().timeout = [NSNumber numberWithUnsignedInt:*options.timeout];
-
     return requestContext;
 }
 
@@ -285,8 +289,12 @@
         auto challenge = WebCore::toNSData(options.challenge);
         [assertionOptions initWithKind:kind relyingPartyIdentifier:options.rpId challenge:challenge.get() userVerificationPreference:userVerification.get() allowedCredentials:allowedCredentials.get()];
     }
-    if (options.extensions)
-        [assertionOptions setExtensions:toASCExtensions(*options.extensions).get()];
+    if (options.extensions) {
+        if ([assertionOptions respondsToSelector:@selector(setExtensionsCBOR:)])
+            [assertionOptions setExtensionsCBOR:toNSData(options.extensions->toCBOR()).get()];
+        else
+            [assertionOptions setExtensions:toASCExtensions(*options.extensions).get()];
+    }
     if (parentOrigin && [assertionOptions respondsToSelector:@selector(setDestinationSiteForCrossSiteAssertion:)])
         assertionOptions.get().destinationSiteForCrossSiteAssertion = parentOrigin->toString();
     else if (parentOrigin && ![assertionOptions respondsToSelector:@selector(setDestinationSiteForCrossSiteAssertion:)])
@@ -355,6 +363,13 @@
     return transports;
 }
 
+static std::optional<AuthenticationExtensionsClientOutputs> toExtensionOutputs(NSData *extensionOutputsCBOR)
+{
+    if (!extensionOutputsCBOR)
+        return std::nullopt;
+    return AuthenticationExtensionsClientOutputs::fromCBOR(vectorFromNSData(extensionOutputsCBOR));
+}
+
 RetainPtr<ASCCredentialRequestContext> WebAuthenticatorCoordinatorProxy::contextForRequest(WebAuthenticationRequestData&& requestData)
 {
     RetainPtr<ASCCredentialRequestContext> result;
@@ -381,6 +396,8 @@
         response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
         if ([registrationCredential respondsToSelector:@selector(transports)])
             response.transports = toAuthenticatorTransports(registrationCredential.transports);
+        if ([registrationCredential respondsToSelector:@selector(extensionOutputsCBOR)])
+            response.extensionOutputs = toExtensionOutputs(registrationCredential.extensionOutputsCBOR);
     } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialRegistrationClass()]) {
         attachment = AuthenticatorAttachment::CrossPlatform;
         response.isAuthenticatorAttestationResponse = true;
@@ -390,6 +407,8 @@
         response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
         if ([registrationCredential respondsToSelector:@selector(transports)])
             response.transports = toAuthenticatorTransports(registrationCredential.transports);
+        if ([registrationCredential respondsToSelector:@selector(extensionOutputsCBOR)])
+            response.extensionOutputs = toExtensionOutputs(registrationCredential.extensionOutputsCBOR);
     } else if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialAssertionClass()]) {
         attachment = AuthenticatorAttachment::Platform;
         response.isAuthenticatorAttestationResponse = false;
@@ -399,6 +418,8 @@
         response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
         response.signature = toArrayBuffer(assertionCredential.signature);
         response.userHandle = toArrayBuffer(assertionCredential.userHandle);
+        if ([assertionCredential respondsToSelector:@selector(extensionOutputsCBOR)])
+            response.extensionOutputs = toExtensionOutputs(assertionCredential.extensionOutputsCBOR);
     } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialAssertionClass()]) {
         attachment = AuthenticatorAttachment::CrossPlatform;
         response.isAuthenticatorAttestationResponse = false;
@@ -408,6 +429,8 @@
         response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
         response.signature = toArrayBuffer(assertionCredential.signature);
         response.userHandle = toArrayBuffer(assertionCredential.userHandle);
+        if ([assertionCredential respondsToSelector:@selector(extensionOutputsCBOR)])
+            response.extensionOutputs = toExtensionOutputs(assertionCredential.extensionOutputsCBOR);
     } else {
         attachment = (AuthenticatorAttachment) 0;
         ExceptionCode exceptionCode;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -31,6 +31,7 @@
 #include "CtapDriver.h"
 #include "CtapHidDriver.h"
 #include "U2fAuthenticator.h"
+#include <WebCore/AuthenticationExtensionsClientOutputs.h>
 #include <WebCore/AuthenticatorAttachment.h>
 #include <WebCore/CryptoKeyAES.h>
 #include <WebCore/CryptoKeyEC.h>
@@ -133,6 +134,15 @@
         receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
         return;
     }
+    auto& options = std::get<PublicKeyCredentialCreationOptions>(requestData().options);
+    if (options.extensions && options.extensions->credProps) {
+        auto extensionOutputs = response->extensions();
+        
+        auto rkSupported = m_info.options().residentKeyAvailability() == AuthenticatorSupportedOptions::ResidentKeyAvailability::kSupported;
+        auto rkRequested = options.authenticatorSelection && ((options.authenticatorSelection->residentKey && options.authenticatorSelection->residentKey != ResidentKeyRequirement::Discouraged) || options.authenticatorSelection->requireResidentKey);
+        extensionOutputs.credProps = AuthenticationExtensionsClientOutputs::CredentialPropertiesOutput { rkSupported && rkRequested };
+        response->setExtensions(WTFMove(extensionOutputs));
+    }
     receiveRespond(response.releaseNonNull());
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp (295406 => 295407)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp	2022-06-09 00:50:20 UTC (rev 295406)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp	2022-06-09 00:55:13 UTC (rev 295407)
@@ -217,7 +217,7 @@
             return;
         }
         if (m_isAppId)
-            response->setExtensions({ m_isAppId });
+            response->setExtensions({ m_isAppId, std::nullopt });
 
         receiveRespond(response.releaseNonNull());
         return;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to