Diff
Modified: trunk/Source/WebCore/ChangeLog (239519 => 239520)
--- trunk/Source/WebCore/ChangeLog 2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Source/WebCore/ChangeLog 2018-12-21 23:06:54 UTC (rev 239520)
@@ -1,3 +1,37 @@
+2018-12-21 Jiewen Tan <[email protected]>
+
+ [WebAuthN] Import an APDU coder from Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=192949
+ <rdar://problem/46879933>
+
+ Reviewed by Brent Fulgham.
+
+ This patch imports an APDU coder from Chromium. Here is the documentation:
+ https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html#u2f-message-framing
+ APDU is a binary format to frame any U2F requests/responses into binaries. It is equivalent to CBOR in CTAP2.
+
+ Here is a list of files that are imported from Chromium:
+ https://cs.chromium.org/chromium/src/components/apdu/apdu_command.cc?rcl=a2f290c10d132f53518e7f99d5635ee814ff8090
+ https://cs.chromium.org/chromium/src/components/apdu/apdu_command.h?rcl=867b103481f6f4ccc79a69bba16c11eefac3cdb6
+ https://cs.chromium.org/chromium/src/components/apdu/apdu_response.cc?rcl=867b103481f6f4ccc79a69bba16c11eefac3cdb6
+ https://cs.chromium.org/chromium/src/components/apdu/apdu_response.h?rcl=867b103481f6f4ccc79a69bba16c11eefac3cdb6
+ https://cs.chromium.org/chromium/src/components/apdu/apdu_unittest.cc?rcl=867b103481f6f4ccc79a69bba16c11eefac3cdb6
+
+ Covered by API tests.
+
+ * Modules/webauthn/apdu/ApduCommand.cpp: Added.
+ (apdu::ApduCommand::createFromMessage):
+ (apdu::ApduCommand::ApduCommand):
+ (apdu::ApduCommand::getEncodedCommand const):
+ * Modules/webauthn/apdu/ApduCommand.h: Added.
+ * Modules/webauthn/apdu/ApduResponse.cpp: Added.
+ (apdu::ApduResponse::createFromMessage):
+ (apdu::ApduResponse::ApduResponse):
+ (apdu::ApduResponse::getEncodedResponse const):
+ * Modules/webauthn/apdu/ApduResponse.h: Added.
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+
2018-12-21 Jer Noble <[email protected]>
Convert raw CDMSessionMediaSourceAVFObjC pointer in MediaPlayerPrivateMediaSourceAVFObjC
Added: trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.cpp (0 => 239520)
--- trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.cpp 2018-12-21 23:06:54 UTC (rev 239520)
@@ -0,0 +1,149 @@
+// 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 "ApduCommand.h"
+
+#if ENABLE(WEB_AUTHN)
+
+namespace apdu {
+
+namespace {
+
+// APDU command data length is 2 bytes encoded in big endian order.
+uint16_t parseMessageLength(const Vector<uint8_t>& message, size_t offset)
+{
+ ASSERT(message.size() >= offset + 2);
+ return (message[offset] << 8) | message[offset + 1];
+}
+
+} // namespace
+
+Optional<ApduCommand> ApduCommand::createFromMessage(const Vector<uint8_t>& message)
+{
+ if (message.size() < kApduMinHeader || message.size() > kApduMaxLength)
+ return WTF::nullopt;
+
+ uint8_t cla = message[0];
+ uint8_t ins = message[1];
+ uint8_t p1 = message[2];
+ uint8_t p2 = message[3];
+
+ size_t responseLength = 0;
+ Vector<uint8_t> data;
+
+ switch (message.size()) {
+ // No data present; no expected response.
+ case kApduMinHeader:
+ break;
+ // Invalid encoding sizes.
+ case kApduMinHeader + 1:
+ case kApduMinHeader + 2:
+ return WTF::nullopt;
+ // No data present; response expected.
+ case kApduMinHeader + 3:
+ // Fifth byte must be 0.
+ if (message[4])
+ return WTF::nullopt;
+ responseLength = parseMessageLength(message, kApduCommandLengthOffset);
+ // Special case where response length of 0x0000 corresponds to 65536
+ // as defined in ISO7816-4.
+ if (!responseLength)
+ responseLength = kApduMaxResponseLength;
+ break;
+ default:
+ // Fifth byte must be 0.
+ if (message[4])
+ return WTF::nullopt;
+ auto dataLength = parseMessageLength(message, kApduCommandLengthOffset);
+
+ if (message.size() == dataLength + kApduCommandDataOffset) {
+ // No response expected.
+ data.appendRange(message.begin() + kApduCommandDataOffset, message.end());
+ } else if (message.size() == dataLength + kApduCommandDataOffset + 2) {
+ // Maximum response size is stored in final 2 bytes.
+ data.appendRange(message.begin() + kApduCommandDataOffset, message.end() - 2);
+ auto responseLengthOffset = kApduCommandDataOffset + dataLength;
+ responseLength = parseMessageLength(message, responseLengthOffset);
+ // Special case where response length of 0x0000 corresponds to 65536
+ // as defined in ISO7816-4.
+ if (!responseLength)
+ responseLength = kApduMaxResponseLength;
+ } else
+ return WTF::nullopt;
+ break;
+ }
+
+ return ApduCommand(cla, ins, p1, p2, responseLength, WTFMove(data));
+}
+
+ApduCommand::ApduCommand(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, size_t responseLength, Vector<uint8_t>&& data)
+ : m_cla(cla)
+ , m_ins(ins)
+ , m_p1(p1)
+ , m_p2(p2)
+ , m_responseLength(responseLength)
+ , m_data(WTFMove(data))
+{
+}
+
+Vector<uint8_t> ApduCommand::getEncodedCommand() const
+{
+ Vector<uint8_t> encoded = { m_cla, m_ins, m_p1, m_p2 };
+
+ // If data exists, request size (Lc) is encoded in 3 bytes, with the first
+ // byte always being null, and the other two bytes being a big-endian
+ // representation of the request size. If data length is 0, response size (Le)
+ // will be prepended with a null byte.
+ if (!m_data.isEmpty()) {
+ size_t dataLength = m_data.size();
+
+ encoded.append(0x0);
+ if (dataLength > kApduMaxDataLength)
+ dataLength = kApduMaxDataLength;
+ encoded.append((dataLength >> 8) & 0xff);
+ encoded.append(dataLength & 0xff);
+ encoded.appendRange(m_data.begin(), m_data.begin() + dataLength);
+ } else if (m_responseLength > 0)
+ encoded.append(0x0);
+
+ if (m_responseLength > 0) {
+ size_t responseLength = m_responseLength;
+ if (responseLength > kApduMaxResponseLength)
+ responseLength = kApduMaxResponseLength;
+ // A zero value represents a response length of 65,536 bytes.
+ encoded.append((responseLength >> 8) & 0xff);
+ encoded.append(responseLength & 0xff);
+ }
+ return encoded;
+}
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.h (0 => 239520)
--- trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.h 2018-12-21 23:06:54 UTC (rev 239520)
@@ -0,0 +1,107 @@
+// 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 <wtf/Noncopyable.h>
+#include <wtf/Optional.h>
+#include <wtf/Vector.h>
+
+namespace apdu {
+
+// APDU commands are defined as part of ISO 7816-4. Commands can be serialized
+// into either short length encodings, where the maximum data length is 256
+// bytes, or an extended length encoding, where the maximum data length is 65536
+// bytes. This class implements only the extended length encoding. Serialized
+// commands consist of a CLA byte, denoting the class of instruction, an INS
+// byte, denoting the instruction code, P1 and P2, each one byte denoting
+// instruction parameters, a length field (Lc), a data field of length Lc, and
+// a maximum expected response length (Le).
+class WEBCORE_EXPORT ApduCommand {
+ WTF_MAKE_NONCOPYABLE(ApduCommand);
+public:
+ // Constructs an APDU command from the serialized message data.
+ static Optional<ApduCommand> createFromMessage(const Vector<uint8_t>&);
+
+ ApduCommand() = default;
+ ApduCommand(
+ uint8_t cla,
+ uint8_t ins,
+ uint8_t p1,
+ uint8_t p2,
+ size_t responseLength,
+ Vector<uint8_t>&& data);
+ ApduCommand(ApduCommand&&) = default;
+ ApduCommand& operator=(ApduCommand&&) = default;
+
+ // Returns serialized message data.
+ Vector<uint8_t> getEncodedCommand() const;
+
+ void setCla(uint8_t cla) { m_cla = cla; }
+ void setIns(uint8_t ins) { m_ins = ins; }
+ void setP1(uint8_t p1) { m_p1 = p1; }
+ void setP2(uint8_t p2) { m_p2 = p2; }
+ void setData(Vector<uint8_t>&& data) { m_data = WTFMove(data); }
+ void setResponseLength(size_t responseLength) { m_responseLength = responseLength; }
+
+ uint8_t cla() const { return m_cla; }
+ uint8_t ins() const { return m_ins; }
+ uint8_t p1() const { return m_p1; }
+ uint8_t p2() const { return m_p2; }
+ size_t responseLength() const { return m_responseLength; }
+ const Vector<uint8_t>& data() const { return m_data; }
+
+ static constexpr size_t kApduMaxResponseLength = 65536;
+
+ static constexpr size_t kApduMinHeader = 4;
+ static constexpr size_t kApduMaxHeader = 7;
+ static constexpr size_t kApduCommandDataOffset = 7;
+ static constexpr size_t kApduCommandLengthOffset = 5;
+
+ // As defined in ISO7816-4, extended length APDU request data is limited to
+ // 16 bits in length with a maximum value of 65535. Response data length is
+ // also limited to 16 bits in length with a value of 0x0000 corresponding to
+ // a length of 65536.
+ static constexpr size_t kApduMaxDataLength = 65535;
+ static constexpr size_t kApduMaxLength = kApduMaxDataLength + kApduMaxHeader + 2;
+
+private:
+ uint8_t m_cla { 0 };
+ uint8_t m_ins { 0 };
+ uint8_t m_p1 { 0 };
+ uint8_t m_p2 { 0 };
+ size_t m_responseLength { 0 };
+ Vector<uint8_t> m_data;
+};
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.cpp (0 => 239520)
--- trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.cpp 2018-12-21 23:06:54 UTC (rev 239520)
@@ -0,0 +1,68 @@
+// 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 "ApduResponse.h"
+
+#if ENABLE(WEB_AUTHN)
+
+namespace apdu {
+
+// static
+Optional<ApduResponse> ApduResponse::createFromMessage(const Vector<uint8_t>& data)
+{
+ // Invalid message size, data is appended by status byte.
+ if (data.size() < 2)
+ return WTF::nullopt;
+
+ uint16_t statusBytes = data[data.size() - 2] << 8;
+ statusBytes |= data[data.size() - 1];
+
+ Vector<uint8_t> newData;
+ newData.appendRange(data.begin(), data.end() - 2);
+ return ApduResponse(WTFMove(newData), static_cast<Status>(statusBytes));
+}
+
+ApduResponse::ApduResponse(Vector<uint8_t>&& data, Status responseStatus)
+ : m_data(WTFMove(data))
+ , m_responseStatus(responseStatus)
+{
+}
+
+Vector<uint8_t> ApduResponse::getEncodedResponse() const
+{
+ Vector<uint8_t> encodedResponse = m_data;
+ encodedResponse.append(static_cast<uint16_t>(m_responseStatus) >> 8 & 0xff);
+ encodedResponse.append(static_cast<uint16_t>(m_responseStatus) & 0xff);
+ return encodedResponse;
+}
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
Added: trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h (0 => 239520)
--- trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h 2018-12-21 23:06:54 UTC (rev 239520)
@@ -0,0 +1,74 @@
+// 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 <wtf/Noncopyable.h>
+#include <wtf/Optional.h>
+#include <wtf/Vector.h>
+
+namespace apdu {
+
+// APDU responses are defined as part of ISO 7816-4. Serialized responses
+// consist of a data field of varying length, up to a maximum 65536, and a
+// two byte status field.
+class WEBCORE_EXPORT ApduResponse {
+ WTF_MAKE_NONCOPYABLE(ApduResponse);
+public:
+ // Status bytes are specified in ISO 7816-4.
+ enum class Status : uint16_t {
+ SW_NO_ERROR = 0x9000,
+ SW_CONDITIONS_NOT_SATISFIED = 0x6985,
+ SW_WRONG_DATA = 0x6A80,
+ SW_WRONG_LENGTH = 0x6700,
+ SW_INS_NOT_SUPPORTED = 0x6D00,
+ };
+
+ // Create a APDU response from the serialized message.
+ static Optional<ApduResponse> createFromMessage(const Vector<uint8_t>& data);
+
+ ApduResponse(Vector<uint8_t>&& data, Status);
+ ApduResponse(ApduResponse&& that) = default;
+ ApduResponse& operator=(ApduResponse&& that) = default;
+
+ Vector<uint8_t> getEncodedResponse() const;
+
+ const Vector<uint8_t>& data() const { return m_data; }
+ Status status() const { return m_responseStatus; }
+
+private:
+ Vector<uint8_t> m_data;
+ Status m_responseStatus;
+};
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
Modified: trunk/Source/WebCore/Sources.txt (239519 => 239520)
--- trunk/Source/WebCore/Sources.txt 2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Source/WebCore/Sources.txt 2018-12-21 23:06:54 UTC (rev 239520)
@@ -256,6 +256,8 @@
Modules/webauthn/AuthenticatorCoordinator.cpp
Modules/webauthn/AuthenticatorCoordinatorClient.cpp
Modules/webauthn/PublicKeyCredential.cpp
+Modules/webauthn/apdu/ApduCommand.cpp
+Modules/webauthn/apdu/ApduResponse.cpp
Modules/webauthn/cbor/CBORReader.cpp
Modules/webauthn/cbor/CBORValue.cpp
Modules/webauthn/cbor/CBORWriter.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (239519 => 239520)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-12-21 23:06:54 UTC (rev 239520)
@@ -1781,6 +1781,8 @@
5706A6961DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5706A6951DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h */; };
5706A6981DDE5E4600A03B14 /* JSRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5706A6971DDE5E4600A03B14 /* JSRsaOaepParams.h */; };
571252691E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h in Headers */ = {isa = PBXBuildFile; fileRef = 571252681E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h */; };
+ 57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 57152B5821CB2E3B000C37CA /* ApduCommand.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 57152B5621CB2E3A000C37CA /* ApduResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
571F21891DA57C54005C9EFD /* JSSubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 571F21881DA57C54005C9EFD /* JSSubtleCrypto.h */; };
572093D31DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 572093D21DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h */; };
5721A9871ECE53B10081295A /* CryptoDigestAlgorithm.h in Headers */ = {isa = PBXBuildFile; fileRef = 5721A9861ECE53B10081295A /* CryptoDigestAlgorithm.h */; };
@@ -8586,6 +8588,10 @@
5706A6991DDE5E8500A03B14 /* JSRsaOaepParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRsaOaepParams.cpp; sourceTree = "<group>"; };
571252681E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmAES_CFB.h; sourceTree = "<group>"; };
5712526A1E52527C008FF369 /* CryptoAlgorithmAES_CFB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmAES_CFB.cpp; sourceTree = "<group>"; };
+ 57152B5521CB2E3A000C37CA /* ApduResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApduResponse.cpp; path = Modules/webauthn/apdu/ApduResponse.cpp; sourceTree = SOURCE_ROOT; };
+ 57152B5621CB2E3A000C37CA /* ApduResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ApduResponse.h; path = Modules/webauthn/apdu/ApduResponse.h; sourceTree = SOURCE_ROOT; };
+ 57152B5721CB2E3A000C37CA /* ApduCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApduCommand.cpp; path = Modules/webauthn/apdu/ApduCommand.cpp; sourceTree = SOURCE_ROOT; };
+ 57152B5821CB2E3B000C37CA /* ApduCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ApduCommand.h; path = Modules/webauthn/apdu/ApduCommand.h; sourceTree = SOURCE_ROOT; };
571F21881DA57C54005C9EFD /* JSSubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSubtleCrypto.h; sourceTree = "<group>"; };
571F218A1DA57C7A005C9EFD /* JSSubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSubtleCrypto.cpp; sourceTree = "<group>"; };
572093D11DDCEA4B00310AB0 /* AesCbcCfbParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AesCbcCfbParams.idl; sourceTree = "<group>"; };
@@ -19270,6 +19276,17 @@
path = "unified-sources";
sourceTree = "<group>";
};
+ 57152B5321CB2CE3000C37CA /* apdu */ = {
+ isa = PBXGroup;
+ children = (
+ 57152B5721CB2E3A000C37CA /* ApduCommand.cpp */,
+ 57152B5821CB2E3B000C37CA /* ApduCommand.h */,
+ 57152B5521CB2E3A000C37CA /* ApduResponse.cpp */,
+ 57152B5621CB2E3A000C37CA /* ApduResponse.h */,
+ );
+ path = apdu;
+ sourceTree = "<group>";
+ };
57303BB32006C6ED00355965 /* cbor */ = {
isa = PBXGroup;
children = (
@@ -19347,6 +19364,7 @@
57D8462A1FEAF57F00CA3682 /* webauthn */ = {
isa = PBXGroup;
children = (
+ 57152B5321CB2CE3000C37CA /* apdu */,
57303BB32006C6ED00355965 /* cbor */,
578A4BFA2166AE0000D08F34 /* fido */,
57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */,
@@ -27862,6 +27880,8 @@
714C7C671FDAD2A900F2BEE1 /* AnimationPlaybackEventInit.h in Headers */,
71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */,
0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */,
+ 57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */,
+ 57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */,
93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */,
A1DF5A941F7EC4320058A477 /* ApplePayContactField.h in Headers */,
A12C59EE2035FC9B0012236B /* ApplePayError.h in Headers */,
Modified: trunk/Tools/ChangeLog (239519 => 239520)
--- trunk/Tools/ChangeLog 2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Tools/ChangeLog 2018-12-21 23:06:54 UTC (rev 239520)
@@ -1,3 +1,15 @@
+2018-12-21 Jiewen Tan <[email protected]>
+
+ [WebAuthN] Import an APDU coder from Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=192949
+ <rdar://problem/46879933>
+
+ Reviewed by Brent Fulgham.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebCore/ApduTest.cpp: Added.
+ (TestWebKitAPI::TEST):
+
2018-12-21 Wenson Hsieh <[email protected]>
Setting the file wrapper and content type of an attachment to a PDF should update its image
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (239519 => 239520)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-12-21 23:06:54 UTC (rev 239520)
@@ -257,6 +257,7 @@
5714ECB91CA8B5B000051AC8 /* DownloadRequestOriginalURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */; };
5714ECBB1CA8BFE400051AC8 /* DownloadRequestOriginalURLFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */; };
5714ECBD1CA8C22A00051AC8 /* DownloadRequestOriginalURL2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */; };
+ 57152B5E21CC2045000C37CA /* ApduTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57152B5D21CC2045000C37CA /* ApduTest.cpp */; };
571F7FD01F2961FB00946648 /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 571F7FCF1F2961E100946648 /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal */; };
572B403421769A88000AD43E /* CtapRequestTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 572B403321769A88000AD43E /* CtapRequestTest.cpp */; };
572B404421781B43000AD43E /* CtapResponseTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 572B404321781B42000AD43E /* CtapResponseTest.cpp */; };
@@ -1604,6 +1605,7 @@
5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURL.html; sourceTree = "<group>"; };
5714ECBA1CA8BFD100051AC8 /* DownloadRequestOriginalURLFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURLFrame.html; sourceTree = "<group>"; };
5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DownloadRequestOriginalURL2.html; sourceTree = "<group>"; };
+ 57152B5D21CC2045000C37CA /* ApduTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApduTest.cpp; sourceTree = "<group>"; };
571F7FCF1F2961E100946648 /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal"; sourceTree = "<group>"; };
572B403321769A88000AD43E /* CtapRequestTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CtapRequestTest.cpp; sourceTree = "<group>"; };
572B40352176A029000AD43E /* FidoTestData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FidoTestData.h; sourceTree = "<group>"; };
@@ -2616,6 +2618,7 @@
3162AE9A1E6F2F8F000E4DBC /* mac */,
ABF510632A19B8AC7EC40E17 /* AbortableTaskQueue.cpp */,
7A909A6F1D877475007E10F8 /* AffineTransform.cpp */,
+ 57152B5D21CC2045000C37CA /* ApduTest.cpp */,
6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */,
93A720E518F1A0E800A848E1 /* CalculationValue.cpp */,
07C046C91E42573E007201E7 /* CARingBuffer.cpp */,
@@ -3837,6 +3840,7 @@
7A909A7D1D877480007E10F8 /* AffineTransform.cpp in Sources */,
A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources */,
2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */,
+ 57152B5E21CC2045000C37CA /* ApduTest.cpp in Sources */,
63F668221F97F7F90032EE51 /* ApplicationManifest.mm in Sources */,
6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */,
834138C7203261CA00F26960 /* AsyncPolicyForNavigationResponse.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/ApduTest.cpp (0 => 239520)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ApduTest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ApduTest.cpp 2018-12-21 23:06:54 UTC (rev 239520)
@@ -0,0 +1,194 @@
+// 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/ApduCommand.h>
+#include <WebCore/ApduResponse.h>
+
+namespace TestWebKitAPI {
+
+using namespace apdu;
+
+TEST(ApduTest, TestDeserializeBasic)
+{
+ uint8_t cla = 0xAA;
+ uint8_t ins = 0xAB;
+ uint8_t p1 = 0xAC;
+ uint8_t p2 = 0xAD;
+ Vector<uint8_t> message({ cla, ins, p1, p2 });
+ auto cmd = ApduCommand::createFromMessage(message);
+ ASSERT_TRUE(cmd);
+ EXPECT_EQ(0u, cmd->responseLength());
+ EXPECT_TRUE(cmd->data().isEmpty());
+ EXPECT_EQ(cla, cmd->cla());
+ EXPECT_EQ(ins, cmd->ins());
+ EXPECT_EQ(p1, cmd->p1());
+ EXPECT_EQ(p2, cmd->p2());
+ // Invalid length.
+ message = { cla, ins, p1 };
+ EXPECT_FALSE(ApduCommand::createFromMessage(message));
+ message.append(p2);
+ message.append(0);
+ // Set APDU command data size as maximum.
+ message.append(0xFF);
+ message.append(0xFF);
+ message.resize(message.size() + ApduCommand::kApduMaxDataLength);
+ // Set maximum response size.
+ message.append(0);
+ message.append(0);
+ // |message| is APDU encoded byte array with maximum data length.
+ EXPECT_TRUE(ApduCommand::createFromMessage(message));
+ message.append(0);
+ // |message| encoding containing data of size maximum data length + 1.
+ EXPECT_FALSE(ApduCommand::createFromMessage(message));
+}
+
+TEST(ApduTest, TestDeserializeComplex)
+{
+ uint8_t cla = 0xAA;
+ uint8_t ins = 0xAB;
+ uint8_t p1 = 0xAC;
+ uint8_t p2 = 0xAD;
+ Vector<uint8_t> data(ApduCommand::kApduMaxDataLength - ApduCommand::kApduMaxHeader - 2, 0x7F);
+ Vector<uint8_t> message = { cla, ins, p1, p2, 0 };
+ message.append((data.size() >> 8) & 0xff);
+ message.append(data.size() & 0xff);
+ message.appendVector(data);
+
+ // Create a message with no response expected.
+ auto cmdNoResponse = ApduCommand::createFromMessage(message);
+ ASSERT_TRUE(cmdNoResponse);
+ EXPECT_EQ(0u, cmdNoResponse->responseLength());
+ EXPECT_EQ(data, cmdNoResponse->data());
+ EXPECT_EQ(cla, cmdNoResponse->cla());
+ EXPECT_EQ(ins, cmdNoResponse->ins());
+ EXPECT_EQ(p1, cmdNoResponse->p1());
+ EXPECT_EQ(p2, cmdNoResponse->p2());
+
+ // Add response length to message.
+ message.append(0xF1);
+ message.append(0xD0);
+ auto cmd = ApduCommand::createFromMessage(message);
+ ASSERT_TRUE(cmd);
+ EXPECT_EQ(data, cmd->data());
+ EXPECT_EQ(cla, cmd->cla());
+ EXPECT_EQ(ins, cmd->ins());
+ EXPECT_EQ(p1, cmd->p1());
+ EXPECT_EQ(p2, cmd->p2());
+ EXPECT_EQ(static_cast<size_t>(0xF1D0), cmd->responseLength());
+}
+
+TEST(ApduTest, TestDeserializeResponse)
+{
+ ApduResponse::Status status;
+ Vector<uint8_t> testVector;
+ // Invalid length.
+ Vector<uint8_t> message({ 0xAA });
+ EXPECT_FALSE(ApduResponse::createFromMessage(message));
+ // Valid length and status.
+ status = ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED;
+ message = { static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8), static_cast<uint8_t>(status) };
+ auto response = ApduResponse::createFromMessage(message);
+ ASSERT_TRUE(response);
+ EXPECT_EQ(ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED, response->status());
+ EXPECT_EQ(response->data(), Vector<uint8_t>());
+ // Valid length and status.
+ status = ApduResponse::Status::SW_NO_ERROR;
+ message = { static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8), static_cast<uint8_t>(status)};
+ testVector = { 0x01, 0x02, 0xEF, 0xFF };
+ message.insertVector(0, testVector);
+ response = ApduResponse::createFromMessage(message);
+ ASSERT_TRUE(response);
+ EXPECT_EQ(ApduResponse::Status::SW_NO_ERROR, response->status());
+ EXPECT_EQ(response->data(), testVector);
+}
+
+TEST(ApduTest, TestSerializeCommand)
+{
+ ApduCommand cmd;
+ cmd.setCla(0xA);
+ cmd.setIns(0xB);
+ cmd.setP1(0xC);
+ cmd.setP2(0xD);
+ // No data, no response expected.
+ Vector<uint8_t> expected({ 0xA, 0xB, 0xC, 0xD });
+ ASSERT(expected == cmd.getEncodedCommand());
+ auto deserializedCmd = ApduCommand::createFromMessage(expected);
+ ASSERT_TRUE(deserializedCmd);
+ EXPECT_EQ(expected, deserializedCmd->getEncodedCommand());
+ // No data, response expected.
+ cmd.setResponseLength(0xCAFE);
+ expected = { 0xA, 0xB, 0xC, 0xD, 0x0, 0xCA, 0xFE };
+ EXPECT_EQ(expected, cmd.getEncodedCommand());
+ deserializedCmd = ApduCommand::createFromMessage(expected);
+ ASSERT_TRUE(deserializedCmd);
+ EXPECT_EQ(expected, deserializedCmd->getEncodedCommand());
+ // Data exists, response expected.
+ Vector<uint8_t> data({ 0x1, 0x2, 0x3, 0x4 });
+ cmd.setData(WTFMove(data));
+ expected = { 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4, 0xCA, 0xFE };
+ EXPECT_EQ(expected, cmd.getEncodedCommand());
+ deserializedCmd = ApduCommand::createFromMessage(expected);
+ ASSERT_TRUE(deserializedCmd);
+ EXPECT_EQ(expected, deserializedCmd->getEncodedCommand());
+ // Data exists, no response expected.
+ cmd.setResponseLength(0);
+ expected = { 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4 };
+ EXPECT_EQ(expected, cmd.getEncodedCommand());
+ EXPECT_EQ(expected, ApduCommand::createFromMessage(expected)->getEncodedCommand());
+}
+
+TEST(ApduTest, TestSerializeEdgeCases)
+{
+ ApduCommand cmd;
+ cmd.setCla(0xA);
+ cmd.setIns(0xB);
+ cmd.setP1(0xC);
+ cmd.setP2(0xD);
+ // Set response length to maximum, which should serialize to 0x0000.
+ cmd.setResponseLength(ApduCommand::kApduMaxResponseLength);
+ Vector<uint8_t> expected({ 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x0 });
+ EXPECT_EQ(expected, cmd.getEncodedCommand());
+ auto deserializedCmd = ApduCommand::createFromMessage(expected);
+ ASSERT_TRUE(deserializedCmd);
+ EXPECT_EQ(expected, deserializedCmd->getEncodedCommand());
+ // Maximum data size.
+ Vector<uint8_t> oversized(ApduCommand::kApduMaxDataLength);
+ cmd.setData(WTFMove(oversized));
+ deserializedCmd = ApduCommand::createFromMessage(cmd.getEncodedCommand());
+ ASSERT_TRUE(deserializedCmd);
+ EXPECT_EQ(cmd.getEncodedCommand(), deserializedCmd->getEncodedCommand());
+}
+
+} // namespace TestWebKitAPI
+
+#endif // ENABLE(WEB_AUTHN)