[prev in list] [next in list] [prev in thread] [next in thread] 

List:       webkit-changes
Subject:    [webkit-changes] [239520] trunk
From:       jiewen_tan () apple ! com
Date:       2018-12-21 23:06:55
Message-ID: 20181221230655.5A29E10051CE () svn ! webkit ! org
[Download RAW message or body]

[Attachment #2 (text/html)]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[239520] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: \
verdana,arial,helvetica,sans-serif; font-size: 10pt;  } #msg dl a { font-weight: \
bold} #msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: \
bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: \
6px; } #logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em \
0; } #logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg \
h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; } \
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; \
} #logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: \
-1.5em; padding-left: 1.5em; } #logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em \
1em 0 1em; background: white;} #logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid \
#fa0; border-bottom: 1px solid #fa0; background: #fff; } #logmsg table th { \
text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted \
#fa0; } #logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: \
0.2em 0.5em; } #logmsg table thead th { text-align: center; border-bottom: 1px solid \
#fa0; } #logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: \
6px; } #patch { width: 100%; }
#patch h4 {font-family: \
verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
 #patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, \
#patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins \
{background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del \
{background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, \
                .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a \
href="http://trac.webkit.org/projects/webkit/changeset/239520">239520</a></dd> \
<dt>Author</dt> <dd>jiewen_tan@apple.com</dd> <dt>Date</dt> <dd>2018-12-21 15:06:54 \
-0800 (Fri, 21 Dec 2018)</dd> </dl>

<h3>Log Message</h3>
<pre>[WebAuthN] Import an APDU coder from Chromium
https://bugs.webkit.org/show_bug.cgi?id=192949
&lt;rdar://problem/46879933&gt;

Reviewed by Brent Fulgham.

Source/WebCore:

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:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/ApduTest.cpp: Added.
(TestWebKitAPI::TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
 <li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
 </ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/WebCore/Modules/webauthn/apdu/</li>
<li><a href="#trunkSourceWebCoreModuleswebauthnapduApduCommandcpp">trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.cpp</a></li>
 <li><a href="#trunkSourceWebCoreModuleswebauthnapduApduCommandh">trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.h</a></li>
 <li><a href="#trunkSourceWebCoreModuleswebauthnapduApduResponsecpp">trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.cpp</a></li>
 <li><a href="#trunkSourceWebCoreModuleswebauthnapduApduResponseh">trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h</a></li>
 <li><a href="#trunkToolsTestWebKitAPITestsWebCoreApduTestcpp">trunk/Tools/TestWebKitAPI/Tests/WebCore/ApduTest.cpp</a></li>
 </ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (239519 => \
239520)</h4> <pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2018-12-21  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebAuthN] Import an APDU coder from Chromium
+        https://bugs.webkit.org/show_bug.cgi?id=192949
+        &lt;rdar://problem/46879933&gt;
+
+        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:
+
</ins><span class="cx"> 2018-12-21  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Convert raw CDMSessionMediaSourceAVFObjC pointer in \
MediaPlayerPrivateMediaSourceAVFObjC </span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebauthnapduApduCommandcpp"></a>
<div class="addfile"><h4>Added: \
trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.cpp (0 => 239520)</h4> <pre \
class="diff"><span> <span class="info">--- \
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) </span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+// 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
+// &quot;AS IS&quot; 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 &quot;config.h&quot;
+#include &quot;ApduCommand.h&quot;
+
+#if ENABLE(WEB_AUTHN)
+
+namespace apdu {
+
+namespace {
+
+// APDU command data length is 2 bytes encoded in big endian order.
+uint16_t parseMessageLength(const Vector&lt;uint8_t&gt;&amp; message, size_t offset)
+{
+    ASSERT(message.size() &gt;= offset + 2);
+    return (message[offset] &lt;&lt; 8) | message[offset + 1];
+}
+
+} // namespace
+
+Optional&lt;ApduCommand&gt; ApduCommand::createFromMessage(const \
Vector&lt;uint8_t&gt;&amp; message) +{
+    if (message.size() &lt; kApduMinHeader || message.size() &gt; 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&lt;uint8_t&gt; 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&lt;uint8_t&gt;&amp;&amp; data) +    : m_cla(cla)
+    , m_ins(ins)
+    , m_p1(p1)
+    , m_p2(p2)
+    , m_responseLength(responseLength)
+    , m_data(WTFMove(data))
+{
+}
+
+Vector&lt;uint8_t&gt; ApduCommand::getEncodedCommand() const
+{
+    Vector&lt;uint8_t&gt; 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 &gt; kApduMaxDataLength)
+            dataLength = kApduMaxDataLength;
+        encoded.append((dataLength &gt;&gt; 8) &amp; 0xff);
+        encoded.append(dataLength &amp; 0xff);
+        encoded.appendRange(m_data.begin(), m_data.begin() + dataLength);
+    } else if (m_responseLength &gt; 0)
+        encoded.append(0x0);
+
+    if (m_responseLength &gt; 0) {
+        size_t responseLength = m_responseLength;
+        if (responseLength &gt; kApduMaxResponseLength)
+            responseLength = kApduMaxResponseLength;
+        // A zero value represents a response length of 65,536 bytes.
+        encoded.append((responseLength &gt;&gt; 8) &amp; 0xff);
+        encoded.append(responseLength &amp; 0xff);
+    }
+    return encoded;
+}
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebauthnapduApduCommandh"></a>
<div class="addfile"><h4>Added: \
trunk/Source/WebCore/Modules/webauthn/apdu/ApduCommand.h (0 => 239520)</h4> <pre \
class="diff"><span> <span class="info">--- \
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) </span><span class="lines">@@ -0,0 +1,107 @@
</span><ins>+// 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
+// &quot;AS IS&quot; 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 &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/Optional.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+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&lt;ApduCommand&gt; createFromMessage(const \
Vector&lt;uint8_t&gt;&amp;); +
+    ApduCommand() = default;
+    ApduCommand(
+        uint8_t cla,
+        uint8_t ins,
+        uint8_t p1,
+        uint8_t p2,
+        size_t responseLength,
+        Vector&lt;uint8_t&gt;&amp;&amp; data);
+    ApduCommand(ApduCommand&amp;&amp;) = default;
+    ApduCommand&amp; operator=(ApduCommand&amp;&amp;) = default;
+
+    // Returns serialized message data.
+    Vector&lt;uint8_t&gt; 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&lt;uint8_t&gt;&amp;&amp; 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&lt;uint8_t&gt;&amp; 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&lt;uint8_t&gt; m_data;
+};
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebauthnapduApduResponsecpp"></a>
<div class="addfile"><h4>Added: \
trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.cpp (0 => 239520)</h4> <pre \
class="diff"><span> <span class="info">--- \
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) </span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+// 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
+// &quot;AS IS&quot; 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 &quot;config.h&quot;
+#include &quot;ApduResponse.h&quot;
+
+#if ENABLE(WEB_AUTHN)
+
+namespace apdu {
+
+// static
+Optional&lt;ApduResponse&gt; ApduResponse::createFromMessage(const \
Vector&lt;uint8_t&gt;&amp; data) +{
+    // Invalid message size, data is appended by status byte.
+    if (data.size() &lt; 2)
+        return WTF::nullopt;
+
+    uint16_t statusBytes = data[data.size() - 2] &lt;&lt; 8;
+    statusBytes |= data[data.size() - 1];
+
+    Vector&lt;uint8_t&gt; newData;
+    newData.appendRange(data.begin(), data.end() - 2);
+    return ApduResponse(WTFMove(newData), static_cast&lt;Status&gt;(statusBytes));
+}
+
+ApduResponse::ApduResponse(Vector&lt;uint8_t&gt;&amp;&amp; data, Status \
responseStatus) +    : m_data(WTFMove(data))
+    , m_responseStatus(responseStatus)
+{
+}
+
+Vector&lt;uint8_t&gt; ApduResponse::getEncodedResponse() const
+{
+    Vector&lt;uint8_t&gt; encodedResponse = m_data;
+    encodedResponse.append(static_cast&lt;uint16_t&gt;(m_responseStatus) &gt;&gt; 8 \
&amp; 0xff); +    encodedResponse.append(static_cast&lt;uint16_t&gt;(m_responseStatus) \
&amp; 0xff); +    return encodedResponse;
+}
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebauthnapduApduResponseh"></a>
<div class="addfile"><h4>Added: \
trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h (0 => 239520)</h4> <pre \
class="diff"><span> <span class="info">--- \
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) </span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+// 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
+// &quot;AS IS&quot; 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 &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/Optional.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+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&lt;ApduResponse&gt; createFromMessage(const \
Vector&lt;uint8_t&gt;&amp; data); +
+    ApduResponse(Vector&lt;uint8_t&gt;&amp;&amp; data, Status);
+    ApduResponse(ApduResponse&amp;&amp; that) = default;
+    ApduResponse&amp; operator=(ApduResponse&amp;&amp; that) = default;
+
+    Vector&lt;uint8_t&gt; getEncodedResponse() const;
+
+    const Vector&lt;uint8_t&gt;&amp; data() const { return m_data; }
+    Status status() const { return m_responseStatus; }
+
+private:
+    Vector&lt;uint8_t&gt; m_data;
+    Status m_responseStatus;
+};
+
+} // namespace apdu
+
+#endif // ENABLE(WEB_AUTHN)
</ins></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (239519 => \
239520)</h4> <pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -256,6 +256,8 @@
</span><span class="cx"> Modules/webauthn/AuthenticatorCoordinator.cpp
</span><span class="cx"> Modules/webauthn/AuthenticatorCoordinatorClient.cpp
</span><span class="cx"> Modules/webauthn/PublicKeyCredential.cpp
</span><ins>+Modules/webauthn/apdu/ApduCommand.cpp
+Modules/webauthn/apdu/ApduResponse.cpp
</ins><span class="cx"> Modules/webauthn/cbor/CBORReader.cpp
</span><span class="cx"> Modules/webauthn/cbor/CBORValue.cpp
</span><span class="cx"> Modules/webauthn/cbor/CBORWriter.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: \
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (239519 => 239520)</h4> <pre \
class="diff"><span> <span class="info">--- \
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) </span><span class="lines">@@ -1781,6 +1781,8 @@
</span><span class="cx"> 		5706A6961DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h \
in Headers */ = {isa = PBXBuildFile; fileRef = 5706A6951DDE5C9500A03B14 /* \
CryptoAlgorithmRsaOaepParams.h */; }; </span><span class="cx"> \
5706A6981DDE5E4600A03B14 /* JSRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; \
fileRef = 5706A6971DDE5E4600A03B14 /* JSRsaOaepParams.h */; }; </span><span \
class="cx"> 		571252691E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h in Headers */ = \
{isa = PBXBuildFile; fileRef = 571252681E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h \
*/; }; </span><ins>+		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, ); }; }; </ins><span \
class="cx"> 		571F21891DA57C54005C9EFD /* JSSubtleCrypto.h in Headers */ = {isa = \
PBXBuildFile; fileRef = 571F21881DA57C54005C9EFD /* JSSubtleCrypto.h */; }; \
</span><span class="cx"> 		572093D31DDCEB9A00310AB0 /* \
CryptoAlgorithmAesCbcCfbParams.h in Headers */ = {isa = PBXBuildFile; fileRef = \
572093D21DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h */; }; </span><span \
class="cx"> 		5721A9871ECE53B10081295A /* CryptoDigestAlgorithm.h in Headers */ = \
{isa = PBXBuildFile; fileRef = 5721A9861ECE53B10081295A /* CryptoDigestAlgorithm.h \
*/; }; </span><span class="lines">@@ -8586,6 +8588,10 @@
</span><span class="cx"> 		5706A6991DDE5E8500A03B14 /* JSRsaOaepParams.cpp */ = {isa \
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = \
JSRsaOaepParams.cpp; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="cx"> 		571252681E524EB1008FF369 /* CryptoAlgorithmAES_CFB.h */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \
CryptoAlgorithmAES_CFB.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="cx"> 		5712526A1E52527C008FF369 /* CryptoAlgorithmAES_CFB.cpp */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = \
CryptoAlgorithmAES_CFB.cpp; sourceTree = &quot;&lt;group&gt;&quot;; }; \
</span><ins>+		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; \
}; </ins><span class="cx"> 		571F21881DA57C54005C9EFD /* JSSubtleCrypto.h */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \
JSSubtleCrypto.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
571F218A1DA57C7A005C9EFD /* JSSubtleCrypto.cpp */ = {isa = PBXFileReference; \
fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSubtleCrypto.cpp; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
572093D11DDCEA4B00310AB0 /* AesCbcCfbParams.idl */ = {isa = PBXFileReference; \
lastKnownFileType = text; path = AesCbcCfbParams.idl; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="lines">@@ -19270,6 +19276,17 @@
</span><span class="cx"> 			path = &quot;unified-sources&quot;;
</span><span class="cx"> 			sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="cx"> 		};
</span><ins>+		57152B5321CB2CE3000C37CA /* apdu */ = {
+			isa = PBXGroup;
+			children = (
+				57152B5721CB2E3A000C37CA /* ApduCommand.cpp */,
+				57152B5821CB2E3B000C37CA /* ApduCommand.h */,
+				57152B5521CB2E3A000C37CA /* ApduResponse.cpp */,
+				57152B5621CB2E3A000C37CA /* ApduResponse.h */,
+			);
+			path = apdu;
+			sourceTree = &quot;&lt;group&gt;&quot;;
+		};
</ins><span class="cx"> 		57303BB32006C6ED00355965 /* cbor */ = {
</span><span class="cx"> 			isa = PBXGroup;
</span><span class="cx"> 			children = (
</span><span class="lines">@@ -19347,6 +19364,7 @@
</span><span class="cx"> 		57D8462A1FEAF57F00CA3682 /* webauthn */ = {
</span><span class="cx"> 			isa = PBXGroup;
</span><span class="cx"> 			children = (
</span><ins>+				57152B5321CB2CE3000C37CA /* apdu */,
</ins><span class="cx"> 				57303BB32006C6ED00355965 /* cbor */,
</span><span class="cx"> 				578A4BFA2166AE0000D08F34 /* fido */,
</span><span class="cx"> 				57303C272009B2FC00355965 /* \
AuthenticatorAssertionResponse.h */, </span><span class="lines">@@ -27862,6 +27880,8 \
@@ </span><span class="cx"> 				714C7C671FDAD2A900F2BEE1 /* \
AnimationPlaybackEventInit.h in Headers */, </span><span class="cx"> \
71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */, </span><span \
class="cx"> 				0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */, \
</span><ins>+				57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */, \
+				57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */, </ins><span \
class="cx"> 				93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */, \
</span><span class="cx"> 				A1DF5A941F7EC4320058A477 /* ApplePayContactField.h in \
Headers */, </span><span class="cx"> 				A12C59EE2035FC9B0012236B /* ApplePayError.h \
in Headers */, </span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (239519 => 239520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog	2018-12-21 23:00:24 UTC (rev 239519)
+++ trunk/Tools/ChangeLog	2018-12-21 23:06:54 UTC (rev 239520)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2018-12-21  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebAuthN] Import an APDU coder from Chromium
+        https://bugs.webkit.org/show_bug.cgi?id=192949
+        &lt;rdar://problem/46879933&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/ApduTest.cpp: Added.
+        (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2018-12-21  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Setting the file wrapper and content type of an \
attachment to a PDF should update its image </span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: \
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (239519 => \
239520)</h4> <pre class="diff"><span>
<span class="info">--- \
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) </span><span class="lines">@@ -257,6 +257,7 @@
</span><span class="cx"> 		5714ECB91CA8B5B000051AC8 /* \
DownloadRequestOriginalURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = \
5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */; }; </span><span \
class="cx"> 		5714ECBB1CA8BFE400051AC8 /* DownloadRequestOriginalURLFrame.html in \
Copy Resources */ = {isa = PBXBuildFile; fileRef = 5714ECBA1CA8BFD100051AC8 /* \
DownloadRequestOriginalURLFrame.html */; }; </span><span class="cx"> \
5714ECBD1CA8C22A00051AC8 /* DownloadRequestOriginalURL2.html in Copy Resources */ = \
{isa = PBXBuildFile; fileRef = 5714ECBC1CA8C21800051AC8 /* \
DownloadRequestOriginalURL2.html */; }; </span><ins>+		57152B5E21CC2045000C37CA /* \
ApduTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57152B5D21CC2045000C37CA \
/* ApduTest.cpp */; }; </ins><span class="cx"> 		571F7FD01F2961FB00946648 /* \
IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal in Copy Resources */ = {isa \
= PBXBuildFile; fileRef = 571F7FCF1F2961E100946648 /* \
IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal */; }; </span><span \
class="cx"> 		572B403421769A88000AD43E /* CtapRequestTest.cpp in Sources */ = {isa = \
PBXBuildFile; fileRef = 572B403321769A88000AD43E /* CtapRequestTest.cpp */; }; \
</span><span class="cx"> 		572B404421781B43000AD43E /* CtapResponseTest.cpp in \
Sources */ = {isa = PBXBuildFile; fileRef = 572B404321781B42000AD43E /* \
CtapResponseTest.cpp */; }; </span><span class="lines">@@ -1604,6 +1605,7 @@
</span><span class="cx"> 		5714ECB81CA8B58800051AC8 /* \
DownloadRequestOriginalURL.html */ = {isa = PBXFileReference; fileEncoding = 4; \
lastKnownFileType = text.html; path = DownloadRequestOriginalURL.html; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="cx"> 		5714ECBA1CA8BFD100051AC8 /* \
DownloadRequestOriginalURLFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; \
lastKnownFileType = text.html; path = DownloadRequestOriginalURLFrame.html; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = \
DownloadRequestOriginalURL2.html; sourceTree = &quot;&lt;group&gt;&quot;; }; \
</span><ins>+		57152B5D21CC2045000C37CA /* ApduTest.cpp */ = {isa = PBXFileReference; \
fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApduTest.cpp; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </ins><span class="cx"> \
571F7FCF1F2961E100946648 /* IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal \
*/ = {isa = PBXFileReference; lastKnownFileType = file; path = \
&quot;IndexedDBStructuredCloneBackwardCompatibility.sqlite3-wal&quot;; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="cx"> 		572B403321769A88000AD43E /* \
CtapRequestTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType \
= sourcecode.cpp.cpp; path = CtapRequestTest.cpp; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="cx"> 		572B40352176A029000AD43E /* \
FidoTestData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path \
= FidoTestData.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="lines">@@ -2616,6 +2618,7 @@ </span><span class="cx"> \
3162AE9A1E6F2F8F000E4DBC /* mac */, </span><span class="cx"> \
ABF510632A19B8AC7EC40E17 /* AbortableTaskQueue.cpp */, </span><span class="cx"> \
7A909A6F1D877475007E10F8 /* AffineTransform.cpp */, \
</span><ins>+				57152B5D21CC2045000C37CA /* ApduTest.cpp */, </ins><span class="cx"> \
6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */, </span><span \
class="cx"> 				93A720E518F1A0E800A848E1 /* CalculationValue.cpp */, </span><span \
class="cx"> 				07C046C91E42573E007201E7 /* CARingBuffer.cpp */, </span><span \
class="lines">@@ -3837,6 +3840,7 @@ </span><span class="cx"> \
7A909A7D1D877480007E10F8 /* AffineTransform.cpp in Sources */, </span><span \
class="cx"> 				A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources \
*/, </span><span class="cx"> 				2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in \
Sources */, </span><ins>+				57152B5E21CC2045000C37CA /* ApduTest.cpp in Sources */,
</ins><span class="cx"> 				63F668221F97F7F90032EE51 /* ApplicationManifest.mm in \
Sources */, </span><span class="cx"> 				6354F4D11F7C3AB500D89DF3 /* \
ApplicationManifestParser.cpp in Sources */, </span><span class="cx"> \
834138C7203261CA00F26960 /* AsyncPolicyForNavigationResponse.mm in Sources */, \
</span></span></pre></div> <a \
id="trunkToolsTestWebKitAPITestsWebCoreApduTestcpp"></a> <div \
class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/ApduTest.cpp (0 => \
239520)</h4> <pre class="diff"><span>
<span class="info">--- 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) </span><span class="lines">@@ -0,0 +1,194 @@
</span><ins>+// 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
+// &quot;AS IS&quot; 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 &quot;config.h&quot;
+
+#if ENABLE(WEB_AUTHN)
+
+#include &lt;WebCore/ApduCommand.h&gt;
+#include &lt;WebCore/ApduResponse.h&gt;
+
+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&lt;uint8_t&gt; message({ cla, ins, p1, p2 });
+    auto cmd = ApduCommand::createFromMessage(message);
+    ASSERT_TRUE(cmd);
+    EXPECT_EQ(0u, cmd-&gt;responseLength());
+    EXPECT_TRUE(cmd-&gt;data().isEmpty());
+    EXPECT_EQ(cla, cmd-&gt;cla());
+    EXPECT_EQ(ins, cmd-&gt;ins());
+    EXPECT_EQ(p1, cmd-&gt;p1());
+    EXPECT_EQ(p2, cmd-&gt;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&lt;uint8_t&gt; data(ApduCommand::kApduMaxDataLength - \
ApduCommand::kApduMaxHeader - 2, 0x7F); +    Vector&lt;uint8_t&gt; message = { cla, \
ins, p1, p2, 0 }; +    message.append((data.size() &gt;&gt; 8) &amp; 0xff);
+    message.append(data.size() &amp; 0xff);
+    message.appendVector(data);
+
+    // Create a message with no response expected.
+    auto cmdNoResponse = ApduCommand::createFromMessage(message);
+    ASSERT_TRUE(cmdNoResponse);
+    EXPECT_EQ(0u, cmdNoResponse-&gt;responseLength());
+    EXPECT_EQ(data, cmdNoResponse-&gt;data());
+    EXPECT_EQ(cla, cmdNoResponse-&gt;cla());
+    EXPECT_EQ(ins, cmdNoResponse-&gt;ins());
+    EXPECT_EQ(p1, cmdNoResponse-&gt;p1());
+    EXPECT_EQ(p2, cmdNoResponse-&gt;p2());
+
+    // Add response length to message.
+    message.append(0xF1);
+    message.append(0xD0);
+    auto cmd = ApduCommand::createFromMessage(message);
+    ASSERT_TRUE(cmd);
+    EXPECT_EQ(data, cmd-&gt;data());
+    EXPECT_EQ(cla, cmd-&gt;cla());
+    EXPECT_EQ(ins, cmd-&gt;ins());
+    EXPECT_EQ(p1, cmd-&gt;p1());
+    EXPECT_EQ(p2, cmd-&gt;p2());
+    EXPECT_EQ(static_cast&lt;size_t&gt;(0xF1D0), cmd-&gt;responseLength());
+}
+
+TEST(ApduTest, TestDeserializeResponse)
+{
+    ApduResponse::Status status;
+    Vector&lt;uint8_t&gt; testVector;
+    // Invalid length.
+    Vector&lt;uint8_t&gt; message({ 0xAA });
+    EXPECT_FALSE(ApduResponse::createFromMessage(message));
+    // Valid length and status.
+    status = ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED;
+    message = { static_cast&lt;uint8_t&gt;(static_cast&lt;uint16_t&gt;(status) \
&gt;&gt; 8), static_cast&lt;uint8_t&gt;(status) }; +    auto response = \
ApduResponse::createFromMessage(message); +    ASSERT_TRUE(response);
+    EXPECT_EQ(ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED, \
response-&gt;status()); +    EXPECT_EQ(response-&gt;data(), Vector&lt;uint8_t&gt;());
+    // Valid length and status.
+    status = ApduResponse::Status::SW_NO_ERROR;
+    message = { static_cast&lt;uint8_t&gt;(static_cast&lt;uint16_t&gt;(status) \
&gt;&gt; 8), static_cast&lt;uint8_t&gt;(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-&gt;status());
+    EXPECT_EQ(response-&gt;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&lt;uint8_t&gt; expected({ 0xA, 0xB, 0xC, 0xD });
+    ASSERT(expected == cmd.getEncodedCommand());
+    auto deserializedCmd = ApduCommand::createFromMessage(expected);
+    ASSERT_TRUE(deserializedCmd);
+    EXPECT_EQ(expected, deserializedCmd-&gt;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-&gt;getEncodedCommand());
+    // Data exists, response expected.
+    Vector&lt;uint8_t&gt; 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-&gt;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)-&gt;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&lt;uint8_t&gt; 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-&gt;getEncodedCommand());
+    // Maximum data size.
+    Vector&lt;uint8_t&gt; oversized(ApduCommand::kApduMaxDataLength);
+    cmd.setData(WTFMove(oversized));
+    deserializedCmd = ApduCommand::createFromMessage(cmd.getEncodedCommand());
+    ASSERT_TRUE(deserializedCmd);
+    EXPECT_EQ(cmd.getEncodedCommand(), deserializedCmd-&gt;getEncodedCommand());
+}
+
+} // namespace TestWebKitAPI
+
+#endif // ENABLE(WEB_AUTHN)
</ins></span></pre>
</div>
</div>

</body>
</html>



_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic