Diff
Modified: trunk/Source/WebCore/ChangeLog (236975 => 236976)
--- trunk/Source/WebCore/ChangeLog 2018-10-09 19:25:18 UTC (rev 236975)
+++ trunk/Source/WebCore/ChangeLog 2018-10-09 19:32:41 UTC (rev 236976)
@@ -1,3 +1,54 @@
+2018-10-09 Jiewen Tan <jiewen_...@apple.com>
+
+ [WebAuthN] Import CTAP HID message and packet structure from Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=189289
+ <rdar://problem/44120310>
+
+ Reviewed by Brent Fulgham.
+
+ This patch imports CTAP HID message and packet structure:
+ https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#message-and-packet-structure
+ from Chromium. With this library, WebKit can now turn binaries into messages that CTAP devices could understand.
+ This patch contains the following Chromium files and modifies them to fit into WebKit:
+ https://cs.chromium.org/chromium/src/device/fido/fido_constants.cc?l=1&rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+ https://cs.chromium.org/chromium/src/device/fido/fido_constants.h?l=1&rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+ https://cs.chromium.org/chromium/src/device/fido/hid/fido_hid_message.cc?l=1&rcl=387f3725de2842e0e6b7175a9b2ed472b0cf781a
+ https://cs.chromium.org/chromium/src/device/fido/hid/fido_hid_message.h?rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+ https://cs.chromium.org/chromium/src/device/fido/hid/fido_hid_packet.cc?rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+ https://cs.chromium.org/chromium/src/device/fido/hid/fido_hid_packet.h?rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+ https://cs.chromium.org/chromium/src/device/fido/hid/fido_hid_message_unittest.cc?rcl=1efcfbeaf4e4cedf58716e1982b5702770571a75
+
+ Covered by API tests.
+
+ * Modules/webauthn/fido/FidoConstants.cpp: Added.
+ (fido::isFidoHidDeviceCommand):
+ * Modules/webauthn/fido/FidoConstants.h: Added.
+ * Modules/webauthn/fido/FidoHidMessage.cpp: Added.
+ (fido::FidoHidMessage::create):
+ (fido::FidoHidMessage::createFromSerializedData):
+ (fido::FidoHidMessage::messageComplete const):
+ (fido::FidoHidMessage::getMessagePayload const):
+ (fido::FidoHidMessage::popNextPacket):
+ (fido::FidoHidMessage::addContinuationPacket):
+ (fido::FidoHidMessage::numPackets const):
+ (fido::FidoHidMessage::FidoHidMessage):
+ * Modules/webauthn/fido/FidoHidMessage.h: Added.
+ * Modules/webauthn/fido/FidoHidPacket.cpp: Added.
+ (fido::FidoHidPacket::FidoHidPacket):
+ (fido::FidoHidInitPacket::createFromSerializedData):
+ (fido::FidoHidInitPacket::FidoHidInitPacket):
+ (fido::FidoHidInitPacket::getSerializedData const):
+ (fido::FidoHidContinuationPacket::createFromSerializedData):
+ (fido::FidoHidContinuationPacket::FidoHidContinuationPacket):
+ (fido::FidoHidContinuationPacket::getSerializedData const):
+ * Modules/webauthn/fido/FidoHidPacket.h: Added.
+ * Modules/webauthn/fido/FidoParsingUtils.cpp: Added.
+ (fido::getInitPacketData):
+ (fido::getContinuationPacketData):
+ * Modules/webauthn/fido/FidoParsingUtils.h: Added.
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+
2018-10-09 Carlos Eduardo Ramalho <cadubent...@gmail.com>
[CoordGraphics] Remove the 'previous backing store' logic
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.cpp (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.cpp 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "FidoConstants.h"
+
+#if ENABLE(WEB_AUTHN)
+
+namespace fido {
+
+bool isFidoHidDeviceCommand(FidoHidDeviceCommand cmd)
+{
+ switch (cmd) {
+ case FidoHidDeviceCommand::kMsg:
+ case FidoHidDeviceCommand::kCbor:
+ case FidoHidDeviceCommand::kInit:
+ case FidoHidDeviceCommand::kPing:
+ case FidoHidDeviceCommand::kCancel:
+ case FidoHidDeviceCommand::kError:
+ case FidoHidDeviceCommand::kKeepAlive:
+ case FidoHidDeviceCommand::kWink:
+ case FidoHidDeviceCommand::kLock:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.h (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.h 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,68 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#pragma once
+
+#if ENABLE(WEB_AUTHN)
+
+namespace fido {
+
+// Commands supported by CTAPHID device as specified in
+// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#ctaphid-commands
+enum class FidoHidDeviceCommand : uint8_t {
+ kMsg = 0x03,
+ kCbor = 0x10,
+ kInit = 0x06,
+ kPing = 0x01,
+ kCancel = 0x11,
+ kError = 0x3F,
+ kKeepAlive = 0x3B,
+ kWink = 0x08,
+ kLock = 0x04,
+};
+
+bool isFidoHidDeviceCommand(FidoHidDeviceCommand cmd);
+
+// HID transport specific constants.
+const size_t kHidPacketSize = 64;
+const uint32_t kHidBroadcastChannel = 0xffffffff;
+const size_t kHidInitPacketHeaderSize = 7;
+const size_t kHidContinuationPacketHeader = 5;
+const size_t kHidMaxPacketSize = 64;
+const size_t kHidInitPacketDataSize = kHidMaxPacketSize - kHidInitPacketHeaderSize;
+const size_t kHidContinuationPacketDataSize = kHidMaxPacketSize - kHidContinuationPacketHeader;
+
+const uint8_t kHidMaxLockSeconds = 10;
+
+// Messages are limited to an initiation packet and 128 continuation packets.
+const size_t kHidMaxMessageSize = 7609;
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.cpp (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.cpp 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,166 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "FidoHidMessage.h"
+
+#if ENABLE(WEB_AUTHN)
+
+#include "FidoParsingUtils.h"
+
+namespace fido {
+
+// static
+std::optional<FidoHidMessage> FidoHidMessage::create(uint32_t channelId, FidoHidDeviceCommand type, const Vector<uint8_t>& data)
+{
+ if (data.size() > kHidMaxMessageSize)
+ return std::nullopt;
+
+ switch (type) {
+ case FidoHidDeviceCommand::kPing:
+ break;
+ case FidoHidDeviceCommand::kMsg:
+ case FidoHidDeviceCommand::kCbor: {
+ if (data.isEmpty())
+ return std::nullopt;
+ break;
+ }
+
+ case FidoHidDeviceCommand::kCancel:
+ case FidoHidDeviceCommand::kWink: {
+ if (!data.isEmpty())
+ return std::nullopt;
+ break;
+ }
+ case FidoHidDeviceCommand::kLock: {
+ if (data.size() != 1 || data[0] > kHidMaxLockSeconds)
+ return std::nullopt;
+ break;
+ }
+ case FidoHidDeviceCommand::kInit: {
+ if (data.size() != 8)
+ return std::nullopt;
+ break;
+ }
+ case FidoHidDeviceCommand::kKeepAlive:
+ case FidoHidDeviceCommand::kError:
+ if (data.size() != 1)
+ return std::nullopt;
+ }
+
+ return FidoHidMessage(channelId, type, data);
+}
+
+// static
+std::optional<FidoHidMessage> FidoHidMessage::createFromSerializedData(const Vector<uint8_t>& serializedData)
+{
+ size_t remainingSize = 0;
+ if (serializedData.size() > kHidPacketSize || serializedData.size() < kHidInitPacketHeaderSize)
+ return std::nullopt;
+
+ auto initPacket = FidoHidInitPacket::createFromSerializedData(serializedData, &remainingSize);
+
+ if (!initPacket)
+ return std::nullopt;
+
+ return FidoHidMessage(WTFMove(initPacket), remainingSize);
+}
+
+bool FidoHidMessage::messageComplete() const
+{
+ return !m_remainingSize;
+}
+
+Vector<uint8_t> FidoHidMessage::getMessagePayload() const
+{
+ Vector<uint8_t> data;
+ size_t dataSize = 0;
+ for (const auto& packet : m_packets)
+ dataSize += packet->getPacketPayload().size();
+ data.reserveInitialCapacity(dataSize);
+
+ for (const auto& packet : m_packets) {
+ const auto& packet_data = packet->getPacketPayload();
+ data.appendVector(packet_data);
+ }
+
+ return data;
+}
+
+Vector<uint8_t> FidoHidMessage::popNextPacket()
+{
+ if (m_packets.isEmpty())
+ return { };
+
+ Vector<uint8_t> data = ""
+ m_packets.removeFirst();
+ return data;
+}
+
+bool FidoHidMessage::addContinuationPacket(const Vector<uint8_t>& buf)
+{
+ size_t remainingSize = m_remainingSize;
+ auto contPacket = FidoHidContinuationPacket::createFromSerializedData(buf, &remainingSize);
+
+ // Reject packets with a different channel id.
+ if (!contPacket || m_channelId != contPacket->channelId())
+ return false;
+
+ m_remainingSize = remainingSize;
+ m_packets.append(WTFMove(contPacket));
+ return true;
+}
+
+size_t FidoHidMessage::numPackets() const
+{
+ return m_packets.size();
+}
+
+FidoHidMessage::FidoHidMessage(uint32_t channelId, FidoHidDeviceCommand type, const Vector<uint8_t>& data)
+ : m_channelId(channelId)
+{
+ uint8_t sequence = 0;
+
+ size_t pos = data.size() > kHidInitPacketDataSize ? kHidInitPacketDataSize : data.size();
+ m_packets.append(std::make_unique<FidoHidInitPacket>(channelId, type, getInitPacketData(data), data.size()));
+ for (; pos < data.size(); pos += kHidContinuationPacketDataSize)
+ m_packets.append(std::make_unique<FidoHidContinuationPacket>(channelId, sequence++, getContinuationPacketData(data, pos)));
+}
+
+FidoHidMessage::FidoHidMessage(std::unique_ptr<FidoHidInitPacket> initPacket, size_t remainingSize)
+ : m_remainingSize(remainingSize)
+{
+ m_channelId = initPacket->channelId();
+ m_cmd = initPacket->command();
+ m_packets.append(WTFMove(initPacket));
+}
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.h (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoHidMessage.h 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,81 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#pragma once
+
+#if ENABLE(WEB_AUTHN)
+
+#include "FidoConstants.h"
+#include "FidoHidPacket.h"
+#include <wtf/Deque.h>
+#include <wtf/Optional.h>
+#include <wtf/Vector.h>
+
+namespace fido {
+
+// Represents HID message format defined by the specification at
+// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#message-and-packet-structure
+class WEBCORE_EXPORT FidoHidMessage {
+ WTF_MAKE_NONCOPYABLE(FidoHidMessage);
+public:
+ // Static functions to create CTAP/U2F HID commands.
+ static std::optional<FidoHidMessage> create(uint32_t channelId, FidoHidDeviceCommand, const Vector<uint8_t>& data);
+
+ // Reconstruct a message from serialized message data.
+ static std::optional<FidoHidMessage> createFromSerializedData(const Vector<uint8_t>&);
+
+ FidoHidMessage(FidoHidMessage&& that) = default;
+ FidoHidMessage& operator=(FidoHidMessage&& other) = default;
+
+ bool messageComplete() const;
+ Vector<uint8_t> getMessagePayload() const;
+ // Pop front of queue with next packet.
+ Vector<uint8_t> popNextPacket();
+ // Adds a continuation packet to the packet list, from the serialized
+ // response value.
+ bool addContinuationPacket(const Vector<uint8_t>&);
+
+ size_t numPackets() const;
+ uint32_t channelId() const { return m_channelId; }
+ FidoHidDeviceCommand cmd() const { return m_cmd; }
+ const Deque<std::unique_ptr<FidoHidPacket>>& getPacketsForTesting() const { return m_packets; }
+
+private:
+ FidoHidMessage(uint32_t channelId, FidoHidDeviceCommand, const Vector<uint8_t>& data);
+ FidoHidMessage(std::unique_ptr<FidoHidInitPacket>, size_t remainingSize);
+
+ uint32_t m_channelId = kHidBroadcastChannel;
+ FidoHidDeviceCommand m_cmd = FidoHidDeviceCommand::kMsg;
+ Deque<std::unique_ptr<FidoHidPacket>> m_packets;
+ size_t m_remainingSize = 0;
+};
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.cpp (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.cpp 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,157 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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 "FidoHidPacket.h"
+
+#if ENABLE(WEB_AUTHN)
+
+#include <algorithm>
+
+namespace fido {
+
+FidoHidPacket::FidoHidPacket(Vector<uint8_t>&& data, uint32_t channelId)
+ : m_data(WTFMove(data))
+ , m_channelId(channelId)
+{
+}
+
+// static
+std::unique_ptr<FidoHidInitPacket> FidoHidInitPacket::createFromSerializedData(const Vector<uint8_t>& serialized, size_t* remainingSize)
+{
+ if (!remainingSize || serialized.size() != kHidPacketSize)
+ return nullptr;
+
+ size_t index = 0;
+ auto channelId = (serialized[index++] & 0xff) << 24;
+ channelId |= (serialized[index++] & 0xff) << 16;
+ channelId |= (serialized[index++] & 0xff) << 8;
+ channelId |= serialized[index++] & 0xff;
+
+ auto command = static_cast<FidoHidDeviceCommand>(serialized[index++] & 0x7f);
+ if (!isFidoHidDeviceCommand(command))
+ return nullptr;
+
+ uint16_t payloadSize = serialized[index++] << 8;
+ payloadSize |= serialized[index++];
+
+ // Check to see if payload is less than maximum size and padded with 0s.
+ uint16_t dataSize = std::min(payloadSize, static_cast<uint16_t>(kHidPacketSize - index));
+
+ // Update remaining size to determine the payload size of follow on packets.
+ *remainingSize = payloadSize - dataSize;
+
+ auto data = ""
+ data.append(serialized.begin() + index, dataSize);
+
+ return std::make_unique<FidoHidInitPacket>(channelId, command, WTFMove(data), payloadSize);
+}
+
+// U2F Initialization packet is defined as:
+// Offset Length
+// 0 4 Channel ID
+// 4 1 Command ID
+// 5 1 High order packet payload size
+// 6 1 Low order packet payload size
+// 7 (s-7) Payload data
+FidoHidInitPacket::FidoHidInitPacket(uint32_t channelId, FidoHidDeviceCommand cmd, Vector<uint8_t>&& data, uint16_t payloadLength)
+ : FidoHidPacket(WTFMove(data), channelId)
+ , m_command(cmd)
+ , m_payloadLength(payloadLength)
+{
+}
+
+Vector<uint8_t> FidoHidInitPacket::getSerializedData() const
+{
+ Vector<uint8_t> serialized;
+ serialized.reserveInitialCapacity(kHidPacketSize);
+ serialized.append((m_channelId >> 24) & 0xff);
+ serialized.append((m_channelId >> 16) & 0xff);
+ serialized.append((m_channelId >> 8) & 0xff);
+ serialized.append(m_channelId & 0xff);
+ serialized.append(static_cast<uint8_t>(m_command) | 0x80);
+ serialized.append((m_payloadLength >> 8) & 0xff);
+ serialized.append(m_payloadLength & 0xff);
+ serialized.append(m_data.begin(), m_data.size());
+ serialized.grow(kHidPacketSize);
+
+ return serialized;
+}
+
+// static
+std::unique_ptr<FidoHidContinuationPacket> FidoHidContinuationPacket::createFromSerializedData(const Vector<uint8_t>& serialized, size_t* remainingSize)
+{
+ if (!remainingSize || serialized.size() != kHidPacketSize)
+ return nullptr;
+
+ size_t index = 0;
+ auto channelId = (serialized[index++] & 0xff) << 24;
+ channelId |= (serialized[index++] & 0xff) << 16;
+ channelId |= (serialized[index++] & 0xff) << 8;
+ channelId |= serialized[index++] & 0xff;
+ auto sequence = serialized[index++];
+
+ // Check to see if packet payload is less than maximum size and padded with 0s.
+ size_t dataSize = std::min(*remainingSize, kHidPacketSize - index);
+ *remainingSize -= dataSize;
+ auto data = ""
+ data.append(serialized.begin() + index, dataSize);
+
+ return std::make_unique<FidoHidContinuationPacket>(channelId, sequence, WTFMove(data));
+}
+
+// U2F Continuation packet is defined as:
+// Offset Length
+// 0 4 Channel ID
+// 4 1 Packet sequence 0x00..0x7f
+// 5 (s-5) Payload data
+FidoHidContinuationPacket::FidoHidContinuationPacket(const uint32_t channelId, const uint8_t sequence, Vector<uint8_t>&& data)
+ : FidoHidPacket(WTFMove(data), channelId)
+ , m_sequence(sequence)
+{
+}
+
+Vector<uint8_t> FidoHidContinuationPacket::getSerializedData() const
+{
+ Vector<uint8_t> serialized;
+ serialized.reserveInitialCapacity(kHidPacketSize);
+ serialized.append((m_channelId >> 24) & 0xff);
+ serialized.append((m_channelId >> 16) & 0xff);
+ serialized.append((m_channelId >> 8) & 0xff);
+ serialized.append(m_channelId & 0xff);
+ serialized.append(m_sequence);
+ serialized.append(m_data.begin(), m_data.size());
+ serialized.grow(kHidPacketSize);
+
+ return serialized;
+}
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.h (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoHidPacket.h 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,112 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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.
+
+#pragma once
+
+#if ENABLE(WEB_AUTHN)
+
+#include "FidoConstants.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace fido {
+
+// HID Packets are defined by the specification at
+// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#message-and-packet-structure
+// Packets are one of two types, initialization packets and continuation
+// packets. HID Packets have header information and a payload. If a
+// FidoHidInitPacket cannot store the entire payload, further payload
+// information is stored in HidContinuationPackets.
+class WEBCORE_EXPORT FidoHidPacket {
+ WTF_MAKE_NONCOPYABLE(FidoHidPacket);
+public:
+ FidoHidPacket(Vector<uint8_t>&& data, uint32_t channelId);
+ virtual ~FidoHidPacket() = default;
+
+ virtual Vector<uint8_t> getSerializedData() const = 0;
+ const Vector<uint8_t>& getPacketPayload() const { return m_data; }
+ uint32_t channelId() const { return m_channelId; }
+
+protected:
+ FidoHidPacket();
+
+ Vector<uint8_t> m_data;
+ uint32_t m_channelId = kHidBroadcastChannel;
+};
+
+// FidoHidInitPacket, based on the CTAP specification consists of a header with
+// data that is serialized into a IOBuffer. A channel identifier is allocated by
+// the CTAP device to ensure its system-wide uniqueness. Command identifiers
+// determine the type of message the packet corresponds to. Payload length
+// is the length of the entire message payload, and the data is only the portion
+// of the payload that will fit into the HidInitPacket.
+class WEBCORE_EXPORT FidoHidInitPacket : public FidoHidPacket {
+public:
+ // Creates a packet from the serialized data of an initialization packet. As
+ // this is the first packet, the payload length of the entire message will be
+ // included within the serialized data. Remaining size will be returned to
+ // inform the callee how many additional packets to expect.
+ static std::unique_ptr<FidoHidInitPacket> createFromSerializedData(const Vector<uint8_t>&, size_t* remainingSize);
+
+ FidoHidInitPacket(uint32_t channelId, FidoHidDeviceCommand, Vector<uint8_t>&& data, uint16_t payloadLength);
+
+ Vector<uint8_t> getSerializedData() const final;
+ FidoHidDeviceCommand command() const { return m_command; }
+ uint16_t payloadLength() const { return m_payloadLength; }
+
+private:
+ FidoHidDeviceCommand m_command;
+ uint16_t m_payloadLength;
+};
+
+// FidoHidContinuationPacket, based on the CTAP Specification consists of a
+// header with data that is serialized into an IOBuffer. The channel identifier
+// will be identical to the identifier in all other packets of the message. The
+// packet sequence will be the sequence number of this particular packet, from
+// 0x00 to 0x7f.
+class WEBCORE_EXPORT FidoHidContinuationPacket : public FidoHidPacket {
+public:
+ // Creates a packet from the serialized data of a continuation packet. As an
+ // HidInitPacket would have arrived earlier with the total payload size,
+ // the remaining size should be passed to inform the packet of how much data
+ // to expect.
+ static std::unique_ptr<FidoHidContinuationPacket> createFromSerializedData(const Vector<uint8_t>&, size_t* remainingSize);
+
+ FidoHidContinuationPacket(uint32_t channelId, uint8_t sequence, Vector<uint8_t>&& data);
+
+ Vector<uint8_t> getSerializedData() const final;
+ uint8_t sequence() const { return m_sequence; }
+
+private:
+ uint8_t m_sequence;
+};
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.cpp (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.cpp 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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 "FidoParsingUtils.h"
+
+#if ENABLE(WEB_AUTHN)
+
+#include "FidoConstants.h"
+
+namespace fido {
+
+Vector<uint8_t> getInitPacketData(const Vector<uint8_t>& data)
+{
+ Vector<uint8_t> result;
+ result.append(data.data(), data.size() > kHidInitPacketDataSize ? kHidInitPacketDataSize : data.size());
+ return result;
+}
+
+Vector<uint8_t> getContinuationPacketData(const Vector<uint8_t>& data, size_t beginPosition)
+{
+ if (beginPosition > data.size())
+ return { };
+
+ Vector<uint8_t> result;
+ result.append(data.data() + beginPosition, data.size() > kHidContinuationPacketDataSize + beginPosition ? kHidContinuationPacketDataSize : data.size() - beginPosition);
+ return result;
+}
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.h (0 => 236976)
--- trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/fido/FidoParsingUtils.h 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_AUTHN)
+
+#include <wtf/Vector.h>
+
+namespace fido {
+
+Vector<uint8_t> getInitPacketData(const Vector<uint8_t>&);
+Vector<uint8_t> getContinuationPacketData(const Vector<uint8_t>&, size_t beginPosition);
+
+} // namespace fido
+
+#endif // ENABLE(WEB_AUTHN)
Modified: trunk/Source/WebCore/Sources.txt (236975 => 236976)
--- trunk/Source/WebCore/Sources.txt 2018-10-09 19:25:18 UTC (rev 236975)
+++ trunk/Source/WebCore/Sources.txt 2018-10-09 19:32:41 UTC (rev 236976)
@@ -254,6 +254,10 @@
Modules/webauthn/cbor/CBORReader.cpp
Modules/webauthn/cbor/CBORValue.cpp
Modules/webauthn/cbor/CBORWriter.cpp
+Modules/webauthn/fido/FidoConstants.cpp
+Modules/webauthn/fido/FidoHidMessage.cpp
+Modules/webauthn/fido/FidoHidPacket.cpp
+Modules/webauthn/fido/FidoParsingUtils.cpp
Modules/webdatabase/ChangeVersionWrapper.cpp
Modules/webdatabase/DOMWindowWebDatabase.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (236975 => 236976)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-09 19:25:18 UTC (rev 236975)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-09 19:32:41 UTC (rev 236976)
@@ -1765,6 +1765,8 @@
57303C4620105D2F00355965 /* AuthenticatorCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 57303C4320105B3D00355965 /* AuthenticatorCoordinator.h */; settings = {ATTRIBUTES = (Private, ); }; };
573489391DAC6B6E00DC0667 /* CryptoAlgorithmParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */; };
5739E12F1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5739E12E1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h */; };
+ 573F5332216806E10045587A /* FidoHidMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 57BAF28A2167D303008E954E /* FidoHidMessage.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 573F533721680D150045587A /* FidoParsingUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 573F533521680D140045587A /* FidoParsingUtils.h */; };
574F55E1204F3B23002948C6 /* COSEConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 574F55DC204F3732002948C6 /* COSEConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
5750A9751E68D00000705C4A /* CryptoKeyEC.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9731E68D00000705C4A /* CryptoKeyEC.h */; };
5750A97E1E6A13EF00705C4A /* CryptoAlgorithmEcKeyParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A97D1E6A13EF00705C4A /* CryptoAlgorithmEcKeyParams.h */; };
@@ -1787,6 +1789,8 @@
57B5F7F91E5BE84000F34F90 /* CryptoAlgorithmAES_GCM.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B5F7F71E5BE84000F34F90 /* CryptoAlgorithmAES_GCM.h */; };
57B5F8091E5D1A9800F34F90 /* CryptoAlgorithmAesGcmParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B5F8081E5D1A9800F34F90 /* CryptoAlgorithmAesGcmParams.h */; };
57B5F8101E5E2A4E00F34F90 /* JSAesGcmParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B5F80B1E5D22DA00F34F90 /* JSAesGcmParams.h */; };
+ 57BAF28C2167D316008E954E /* FidoConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 578A4C0B2167D29600D08F34 /* FidoConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 57BAF28E2167D339008E954E /* FidoHidPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = 578A4C0A2167D29600D08F34 /* FidoHidPacket.h */; settings = {ATTRIBUTES = (Private, ); }; };
57C7A68C1E56967500C67D71 /* BasicCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57C7A68B1E56967500C67D71 /* BasicCredential.h */; settings = {ATTRIBUTES = (Private, ); }; };
57C7A69F1E57917800C67D71 /* JSBasicCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57C7A69D1E57910D00C67D71 /* JSBasicCredential.h */; };
57D0018D1DD5413200ED19D9 /* JSCryptoKeyUsage.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D0018C1DD5413200ED19D9 /* JSCryptoKeyUsage.h */; };
@@ -8562,6 +8566,8 @@
573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmParameters.h; sourceTree = "<group>"; };
5739E12E1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCryptoAlgorithmParameters.h; sourceTree = "<group>"; };
5739E1301DAC7FD100E14383 /* JSCryptoAlgorithmParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCryptoAlgorithmParameters.cpp; sourceTree = "<group>"; };
+ 573F533521680D140045587A /* FidoParsingUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FidoParsingUtils.h; sourceTree = "<group>"; };
+ 573F533621680D150045587A /* FidoParsingUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FidoParsingUtils.cpp; sourceTree = "<group>"; };
574AC7531DAC367D00E9744C /* CryptoAlgorithmParameters.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CryptoAlgorithmParameters.idl; sourceTree = "<group>"; };
574D42791D594FF6002CF50E /* GlobalCrypto.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GlobalCrypto.idl; sourceTree = "<group>"; };
574F55DC204F3732002948C6 /* COSEConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = COSEConstants.h; sourceTree = "<group>"; };
@@ -8601,6 +8607,10 @@
5778BD801DA4733E009E3009 /* SubtleCrypto.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SubtleCrypto.idl; sourceTree = "<group>"; };
5778BD811DA4802C009E3009 /* SubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtleCrypto.h; sourceTree = "<group>"; };
5778BD831DA4817B009E3009 /* SubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtleCrypto.cpp; sourceTree = "<group>"; };
+ 578A4C082167D29500D08F34 /* FidoHidMessage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FidoHidMessage.cpp; sourceTree = "<group>"; };
+ 578A4C092167D29600D08F34 /* FidoHidPacket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FidoHidPacket.cpp; sourceTree = "<group>"; };
+ 578A4C0A2167D29600D08F34 /* FidoHidPacket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FidoHidPacket.h; sourceTree = "<group>"; };
+ 578A4C0B2167D29600D08F34 /* FidoConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FidoConstants.h; sourceTree = "<group>"; };
5790996B1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRSA_PSS.h; sourceTree = "<group>"; };
5790996C1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRSA_PSS.cpp; sourceTree = "<group>"; };
57957CA61E971DE0008072AB /* CryptoAlgorithmHKDF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmHKDF.cpp; sourceTree = "<group>"; };
@@ -8617,6 +8627,8 @@
57B5F80A1E5D22DA00F34F90 /* JSAesGcmParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAesGcmParams.cpp; sourceTree = "<group>"; };
57B5F80B1E5D22DA00F34F90 /* JSAesGcmParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAesGcmParams.h; sourceTree = "<group>"; };
57B5F80D1E5D2F2D00F34F90 /* CryptoAlgorithmAES_GCMMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmAES_GCMMac.cpp; sourceTree = "<group>"; };
+ 57BAF2872167D2F7008E954E /* FidoConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FidoConstants.cpp; sourceTree = "<group>"; };
+ 57BAF28A2167D303008E954E /* FidoHidMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FidoHidMessage.h; sourceTree = "<group>"; };
57C7A6891E56946D00C67D71 /* BasicCredential.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BasicCredential.idl; sourceTree = "<group>"; };
57C7A68B1E56967500C67D71 /* BasicCredential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicCredential.h; sourceTree = "<group>"; };
57C7A6931E578ACA00C67D71 /* BasicCredential.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicCredential.cpp; sourceTree = "<group>"; };
@@ -18973,6 +18985,21 @@
path = cbor;
sourceTree = "<group>";
};
+ 578A4BFA2166AE0000D08F34 /* fido */ = {
+ isa = PBXGroup;
+ children = (
+ 57BAF2872167D2F7008E954E /* FidoConstants.cpp */,
+ 578A4C0B2167D29600D08F34 /* FidoConstants.h */,
+ 578A4C082167D29500D08F34 /* FidoHidMessage.cpp */,
+ 57BAF28A2167D303008E954E /* FidoHidMessage.h */,
+ 578A4C092167D29600D08F34 /* FidoHidPacket.cpp */,
+ 578A4C0A2167D29600D08F34 /* FidoHidPacket.h */,
+ 573F533621680D150045587A /* FidoParsingUtils.cpp */,
+ 573F533521680D140045587A /* FidoParsingUtils.h */,
+ );
+ path = fido;
+ sourceTree = "<group>";
+ };
57C7A6881E56946D00C67D71 /* credentialmanagement */ = {
isa = PBXGroup;
children = (
@@ -19014,6 +19041,7 @@
isa = PBXGroup;
children = (
57303BB32006C6ED00355965 /* cbor */,
+ 578A4BFA2166AE0000D08F34 /* fido */,
57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */,
57303C292009B2FC00355965 /* AuthenticatorAssertionResponse.idl */,
57303C1B2009A98600355965 /* AuthenticatorAttestationResponse.h */,
@@ -28231,6 +28259,10 @@
84730D8D1248F0B300D3A9C9 /* FETurbulence.h in Headers */,
FD31609512B026F700C1A359 /* FFTConvolver.h in Headers */,
FD31609712B026F700C1A359 /* FFTFrame.h in Headers */,
+ 57BAF28C2167D316008E954E /* FidoConstants.h in Headers */,
+ 573F5332216806E10045587A /* FidoHidMessage.h in Headers */,
+ 57BAF28E2167D339008E954E /* FidoHidPacket.h in Headers */,
+ 573F533721680D150045587A /* FidoParsingUtils.h in Headers */,
976D6C81122B8A3D001FD1F7 /* File.h in Headers */,
838F86DA1F509E7400E8CFC5 /* FileCallback.h in Headers */,
066C772B0AB603B700238CC4 /* FileChooser.h in Headers */,
Modified: trunk/Tools/ChangeLog (236975 => 236976)
--- trunk/Tools/ChangeLog 2018-10-09 19:25:18 UTC (rev 236975)
+++ trunk/Tools/ChangeLog 2018-10-09 19:32:41 UTC (rev 236976)
@@ -1,3 +1,15 @@
+2018-10-09 Jiewen Tan <jiewen_...@apple.com>
+
+ [WebAuthN] Import CTAP HID message and packet structure from Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=189289
+ <rdar://problem/44120310>
+
+ Reviewed by Brent Fulgham.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebCore/FidoHidMessageTest.cpp: Added.
+ (TestWebKitAPI::TEST):
+
2018-10-09 Chris Dumez <cdu...@apple.com>
PSON: Doing a cross-site navigation via the URL bar does not swap process on iOS
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (236975 => 236976)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-10-09 19:25:18 UTC (rev 236975)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-10-09 19:32:41 UTC (rev 236976)
@@ -257,6 +257,7 @@
5769C50B1D9B0002000847FB /* SerializedCryptoKeyWrap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5769C50A1D9B0001000847FB /* SerializedCryptoKeyWrap.mm */; };
578CBD67204FB2C80083B9F2 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 578CBD66204FB2C70083B9F2 /* LocalAuthentication.framework */; };
57901FB11CAF142D00ED64F9 /* LoadInvalidURLRequest.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57901FB01CAF141C00ED64F9 /* LoadInvalidURLRequest.html */; };
+ 579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */; };
5797FE311EB15A6800B2F4A0 /* NavigationClientDefaultCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */; };
5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */; };
57C3FA661F7C248F009D4B80 /* WeakPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CB9BC371A67482300FE5678 /* WeakPtr.cpp */; };
@@ -1563,6 +1564,7 @@
57901FAC1CAF12C200ED64F9 /* LoadInvalidURLRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadInvalidURLRequest.mm; sourceTree = "<group>"; };
57901FAE1CAF137100ED64F9 /* LoadInvalidURLRequest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LoadInvalidURLRequest.mm; sourceTree = "<group>"; };
57901FB01CAF141C00ED64F9 /* LoadInvalidURLRequest.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LoadInvalidURLRequest.html; sourceTree = "<group>"; };
+ 579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FidoHidMessageTest.cpp; sourceTree = "<group>"; };
5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NavigationClientDefaultCrypto.cpp; sourceTree = "<group>"; };
5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "navigation-client-default-crypto.html"; sourceTree = "<group>"; };
5798E2AF1CAF5C2800C5CBA0 /* ProvisionalURLNotChange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProvisionalURLNotChange.mm; sourceTree = "<group>"; };
@@ -2528,6 +2530,7 @@
260BA57A1B1D2EE2004FA07C /* DFAHelpers.h */,
26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
3151180F1DB1ADD500176304 /* ExtendedColor.cpp */,
+ 579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */,
7A32D7491F02151500162C44 /* FileMonitor.cpp */,
41973B5A1AF2286A006C7B36 /* FileSystem.cpp */,
7A909A701D877475007E10F8 /* FloatPoint.cpp */,
@@ -3805,6 +3808,7 @@
CDA29B2920FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm in Sources */,
315118101DB1AE4000176304 /* ExtendedColor.cpp in Sources */,
7CCE7EF11A411AE600447C4C /* FailedLoad.cpp in Sources */,
+ 579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */,
7A32D74A1F02151500162C44 /* FileMonitor.cpp in Sources */,
7C83E04F1D0A641800FEBCF3 /* FileSystem.cpp in Sources */,
7CCE7EF31A411AE600447C4C /* Find.cpp in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoHidMessageTest.cpp (0 => 236976)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoHidMessageTest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoHidMessageTest.cpp 2018-10-09 19:32:41 UTC (rev 236976)
@@ -0,0 +1,213 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright (C) 2018 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+// OWNER OR 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"
+
+#if ENABLE(WEB_AUTHN)
+
+#include <WebCore/FidoConstants.h>
+#include <WebCore/FidoHidMessage.h>
+#include <WebCore/FidoHidPacket.h>
+#include <wtf/Deque.h>
+#include <wtf/Vector.h>
+
+namespace TestWebKitAPI {
+
+using namespace fido;
+
+// Packets should be 64 bytes + 1 report ID byte.
+TEST(FidoHidMessageTest, TestPacketSize)
+{
+ uint32_t channelId = 0x05060708;
+ Vector<uint8_t> data;
+
+ auto initPacket = std::make_unique<FidoHidInitPacket>(channelId, FidoHidDeviceCommand::kInit, Vector<uint8_t>(data), data.size());
+ EXPECT_EQ(64u, initPacket->getSerializedData().size());
+
+ auto continuationPacket = std::make_unique<FidoHidContinuationPacket>(channelId, 0, WTFMove(data));
+ EXPECT_EQ(64u, continuationPacket->getSerializedData().size());
+}
+
+/*
+ * U2f Init Packets are of the format:
+ * Byte 0: 0
+ * Byte 1-4: Channel ID
+ * Byte 5: Command byte
+ * Byte 6-7: Big Endian size of data
+ * Byte 8-n: Data block
+ *
+ * Remaining buffer is padded with 0
+ */
+TEST(FidoHidMessageTest, TestPacketData)
+{
+ uint32_t channelId = 0xF5060708;
+ Vector<uint8_t> data {10, 11};
+ FidoHidDeviceCommand cmd = FidoHidDeviceCommand::kWink;
+ auto initPacket = std::make_unique<FidoHidInitPacket>(channelId, cmd, Vector<uint8_t>(data), data.size());
+ size_t index = 0;
+
+ Vector<uint8_t> serialized = initPacket->getSerializedData();
+ EXPECT_EQ((channelId >> 24) & 0xff, serialized[index++]);
+ EXPECT_EQ((channelId >> 16) & 0xff, serialized[index++]);
+ EXPECT_EQ((channelId >> 8) & 0xff, serialized[index++]);
+ EXPECT_EQ(channelId & 0xff, serialized[index++]);
+ EXPECT_EQ(static_cast<uint8_t>(cmd), serialized[index++] & 0x7f);
+
+ EXPECT_EQ(data.size() >> 8, serialized[index++]);
+ EXPECT_EQ(data.size() & 0xff, serialized[index++]);
+ EXPECT_EQ(data[0], serialized[index++]);
+ EXPECT_EQ(data[1], serialized[index++]);
+ for (; index < serialized.size(); index++)
+ EXPECT_EQ(0, serialized[index]) << "mismatch at index " << index;
+}
+
+TEST(FidoHidMessageTest, TestPacketConstructors)
+{
+ uint32_t channelId = 0x05060708;
+ Vector<uint8_t> data {10, 11};
+ FidoHidDeviceCommand cmd = FidoHidDeviceCommand::kWink;
+ size_t length = data.size();
+ auto origPacket = std::make_unique<FidoHidInitPacket>(channelId, cmd, WTFMove(data), length);
+
+ size_t payloadLength = static_cast<size_t>(origPacket->payloadLength());
+ Vector<uint8_t> origData = origPacket->getSerializedData();
+
+ auto reconstructedPacket = FidoHidInitPacket::createFromSerializedData(origData, &payloadLength);
+ EXPECT_EQ(origPacket->command(), reconstructedPacket->command());
+ EXPECT_EQ(origPacket->payloadLength(), reconstructedPacket->payloadLength());
+ EXPECT_EQ(origPacket->getPacketPayload(), reconstructedPacket->getPacketPayload());
+
+ EXPECT_EQ(channelId, reconstructedPacket->channelId());
+
+ ASSERT_EQ(origPacket->getSerializedData().size(), reconstructedPacket->getSerializedData().size());
+ for (size_t index = 0; index < origPacket->getSerializedData().size(); ++index)
+ EXPECT_EQ(origPacket->getSerializedData()[index], reconstructedPacket->getSerializedData()[index]) << "mismatch at index " << index;
+}
+
+TEST(FidoHidMessageTest, TestMaxLengthPacketConstructors)
+{
+ uint32_t channelId = 0xAAABACAD;
+ Vector<uint8_t> data;
+ for (size_t i = 0; i < kHidMaxMessageSize; ++i)
+ data.append(static_cast<uint8_t>(i % 0xff));
+
+ auto origMsg = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kMsg, data);
+ ASSERT_TRUE(origMsg);
+
+ const auto& originalMsgPackets = origMsg->getPacketsForTesting();
+ auto it = originalMsgPackets.begin();
+ auto msgData = (*it)->getSerializedData();
+ auto newMsg = FidoHidMessage::createFromSerializedData(msgData);
+ ++it;
+
+ for (; it != originalMsgPackets.end(); ++it) {
+ msgData = (*it)->getSerializedData();
+ EXPECT_TRUE(newMsg->addContinuationPacket(msgData));
+ }
+
+ auto origIt = originalMsgPackets.begin();
+ const auto& newMsgPackets = newMsg->getPacketsForTesting();
+ auto newMsgIt = newMsgPackets.begin();
+
+ EXPECT_EQ(origMsg->numPackets(), newMsg->numPackets());
+ for (; origIt != originalMsgPackets.end() || newMsgIt != newMsgPackets.end(); ++origIt, ++newMsgIt) {
+ EXPECT_EQ((*origIt)->getPacketPayload(), (*newMsgIt)->getPacketPayload());
+
+ EXPECT_EQ((*origIt)->channelId(), (*newMsgIt)->channelId());
+
+ ASSERT_EQ((*origIt)->getSerializedData().size(), (*newMsgIt)->getSerializedData().size());
+ for (size_t index = 0; index < (*origIt)->getSerializedData().size(); ++index)
+ EXPECT_EQ((*origIt)->getSerializedData()[index], (*newMsgIt)->getSerializedData()[index]) << "mismatch at index " << index;
+ }
+}
+
+TEST(FidoHidMessageTest, TestMessagePartitoning)
+{
+ uint32_t channelId = 0x01010203;
+ Vector<uint8_t> data(kHidInitPacketDataSize + 1);
+ auto twoPacketMessage = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ ASSERT_TRUE(twoPacketMessage);
+ EXPECT_EQ(2U, twoPacketMessage->numPackets());
+
+ data.resize(kHidInitPacketDataSize);
+ auto _onePacketMessage_ = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ ASSERT_TRUE(onePacketMessage);
+ EXPECT_EQ(1U, onePacketMessage->numPackets());
+
+ data.resize(kHidInitPacketDataSize + kHidContinuationPacketDataSize + 1);
+ auto threePacketMessage = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ ASSERT_TRUE(threePacketMessage);
+ EXPECT_EQ(3U, threePacketMessage->numPackets());
+}
+
+TEST(FidoHidMessageTest, TestMaxSize)
+{
+ uint32_t channelId = 0x00010203;
+ Vector<uint8_t> data(kHidMaxMessageSize + 1);
+ auto oversizeMessage = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ EXPECT_FALSE(oversizeMessage);
+}
+
+TEST(FidoHidMessageTest, TestDeconstruct)
+{
+ uint32_t channelId = 0x0A0B0C0D;
+ Vector<uint8_t> data(kHidMaxMessageSize, 0x7F);
+ auto filledMessage = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ ASSERT_TRUE(filledMessage);
+ EXPECT_EQ(data, filledMessage->getMessagePayload());
+}
+
+TEST(FidoHidMessageTest, TestDeserialize)
+{
+ uint32_t channelId = 0x0A0B0C0D;
+ Vector<uint8_t> data(kHidMaxMessageSize);
+
+ auto origMessage = FidoHidMessage::create(channelId, FidoHidDeviceCommand::kPing, data);
+ ASSERT_TRUE(origMessage);
+
+ Deque<Vector<uint8_t>> origList;
+ auto buf = origMessage->popNextPacket();
+ origList.append(buf);
+
+ auto newMessage = FidoHidMessage::createFromSerializedData(buf);
+ while (!newMessage->messageComplete()) {
+ buf = origMessage->popNextPacket();
+ origList.append(buf);
+ newMessage->addContinuationPacket(buf);
+ }
+
+ while (!(buf = newMessage->popNextPacket()).isEmpty()) {
+ EXPECT_EQ(buf, origList.first());
+ origList.removeFirst();
+ }
+}
+
+} // namespace TestWebKitAPI
+
+#endif // ENABLE(WEB_AUTHN)