<!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>[209200] 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/209200">209200</a></dd>
<dt>Author</dt> <dd>jiewen_tan@apple.com</dd>
<dt>Date</dt> <dd>2016-12-01 13:45:31 -0800 (Thu, 01 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update SubtleCrypto::unwrapKey to match the latest spec
https://bugs.webkit.org/show_bug.cgi?id=164747
&lt;rdar://problem/29258198&gt;

Reviewed by Brent Fulgham.

LayoutTests/imported/w3c:

* WebCryptoAPI/idlharness-expected.txt:

Source/WebCore:

This patch does following few things:
1. It updates the SubtleCrypto::unwrapKey method to match the latest spec:
   https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey.
   It also refers to the latest Editor's Draft to a certain degree:
   https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-unwrapKey.
2. It implements unwrapKey operations of the following algorithms: AES-KW.

Tests: crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html
       crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html
       crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html
       crypto/subtle/aes-kw-import-key-unwrap-raw-key.html
       crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html
       crypto/subtle/unwrapKey-malformed-parameters.html
       crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html
       crypto/workers/subtle/aes-kw-import-key-unwrap-key.html
       crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html

* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::normalizeCryptoAlgorithmParameters):
(WebCore::jsSubtleCryptoFunctionWrapKeyPromise):
Add some comments.
(WebCore::jsSubtleCryptoFunctionUnwrapKeyPromise):
(WebCore::JSSubtleCrypto::unwrapKey):
* crypto/CryptoAlgorithm.cpp:
(WebCore::CryptoAlgorithm::unwrapKey):
* crypto/CryptoAlgorithm.h:
* crypto/SubtleCrypto.idl:
* crypto/algorithms/CryptoAlgorithmAES_KW.cpp:
(WebCore::CryptoAlgorithmAES_KW::unwrapKey):
* crypto/algorithms/CryptoAlgorithmAES_KW.h:
* crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp:
(WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey):
* crypto/mac/CryptoAlgorithmAES_KWMac.cpp:
(WebCore::unwrapKeyAES_KW):
(WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey):
(WebCore::CryptoAlgorithmAES_KW::platformDecrypt):

LayoutTests:

* crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt: Added.
* crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html: Added.
* crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt: Added.
* crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html: Added.
* crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt: Added.
* crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html: Added.
* crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt: Added.
* crypto/subtle/aes-kw-import-key-unwrap-raw-key.html: Added.
* crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt: Added.
* crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html: Added.
* crypto/subtle/unwrapKey-malformed-parameters-expected.txt: Added.
* crypto/subtle/unwrapKey-malformed-parameters.html: Added.
* crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt: Added.
* crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html: Added.
* crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt: Added.
* crypto/workers/subtle/aes-kw-import-key-unwrap-key.html: Added.
* crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js: Added.
* crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js: Added.
* crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js: Added.
* crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt: Added.
* crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cWebCryptoAPIidlharnessexpectedtxt">trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSSubtleCryptoCustomcpp">trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoCryptoAlgorithmcpp">trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoCryptoAlgorithmh">trunk/Source/WebCore/crypto/CryptoAlgorithm.h</a></li>
<li><a href="#trunkSourceWebCorecryptoSubtleCryptoidl">trunk/Source/WebCore/crypto/SubtleCrypto.idl</a></li>
<li><a href="#trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmAES_KWcpp">trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmAES_KWh">trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h</a></li>
<li><a href="#trunkSourceWebCorecryptognutlsCryptoAlgorithmAES_KWGnuTLScpp">trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptomacCryptoAlgorithmAES_KWMaccpp">trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscryptosubtleaescbcimportkeyunwrapjwkrsakeyprivateexpectedtxt">trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaescbcimportkeyunwrapjwkrsakeyprivatehtml">trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaescbcimportkeyuwrapjwkrsakeypublicexpectedtxt">trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaescbcimportkeyuwrapjwkrsakeypublichtml">trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaeskwgeneratekeywrapkeyunwrapkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaeskwgeneratekeywrapkeyunwrapkeyhtml">trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaeskwimportkeyunwraprawkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleaeskwimportkeyunwraprawkeyhtml">trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtlersaoaepimportkeyunwrapjwkoctkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtlersaoaepimportkeyunwrapjwkoctkeyhtml">trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleunwrapKeymalformedparametersexpectedtxt">trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleunwrapKeymalformedparametershtml">trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleaescbcimportkeyunwrapkeyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleaescbcimportkeyunwrapkeyhtml">trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleaeskwimportkeyunwrapkeyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleaeskwimportkeyunwrapkeyhtml">trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesaescbcimportkeyunwrapkeyjs">trunk/LayoutTests/crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesaeskwimportkeyunwrapkeyjs">trunk/LayoutTests/crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesrsaoaepimportkeyunwrapkeyjs">trunk/LayoutTests/crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtlersaoaepimportkeyunwrapkeyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtlersaoaepimportkeyunwrapkeyhtml">trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/LayoutTests/ChangeLog        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2016-12-01  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        Update SubtleCrypto::unwrapKey to match the latest spec
+        https://bugs.webkit.org/show_bug.cgi?id=164747
+        &lt;rdar://problem/29258198&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt: Added.
+        * crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html: Added.
+        * crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt: Added.
+        * crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html: Added.
+        * crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt: Added.
+        * crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html: Added.
+        * crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt: Added.
+        * crypto/subtle/aes-kw-import-key-unwrap-raw-key.html: Added.
+        * crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt: Added.
+        * crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html: Added.
+        * crypto/subtle/unwrapKey-malformed-parameters-expected.txt: Added.
+        * crypto/subtle/unwrapKey-malformed-parameters.html: Added.
+        * crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt: Added.
+        * crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html: Added.
+        * crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt: Added.
+        * crypto/workers/subtle/aes-kw-import-key-unwrap-key.html: Added.
+        * crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js: Added.
+        * crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js: Added.
+        * crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js: Added.
+        * crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt: Added.
+        * crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html: Added.
+
</ins><span class="cx"> 2016-12-01  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Parser] Fix font-variant parsing
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaescbcimportkeyunwrapjwkrsakeyprivateexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+Test unwrapping a JWK RSA private key with AES-CBC using an imported key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS unwrappedKey.kty is jwkKey.kty
+PASS unwrappedKey.alg is jwkKey.alg
+PASS unwrappedKey.key_ops is jwkKey.key_ops
+PASS unwrappedKey.ext is jwkKey.ext
+PASS unwrappedKey.n is jwkKey.n
+PASS unwrappedKey.e is jwkKey.e
+PASS unwrappedKey.p is jwkKey.p
+PASS unwrappedKey.q is jwkKey.q
+PASS unwrappedKey.dp is jwkKey.dp
+PASS unwrappedKey.dq is jwkKey.dq
+PASS unwrappedKey.qi is jwkKey.qi
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaescbcimportkeyunwrapjwkrsakeyprivatehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test unwrapping a JWK RSA private key with AES-CBC using an imported key&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkKey = {
+    kty: &quot;RSA&quot;,
+    alg: &quot;RSA-OAEP&quot;,
+    use: &quot;enc&quot;,
+    key_ops: [&quot;decrypt&quot;],
+    ext: true,
+    n: &quot;lxHN0N9VRZ0_pl0xv3-NXx70WnjkODSkQ5LjHXTFy3DOQsvkagFzD9HqYQezCmcewLjdK5PLwSesDoMdfL6tusBHcvyit1kvydYFQ3NLbENNkYsiBG5_nW4IQGL6JKbZ5iGdUop98QHKm6YZR1u4zrAtxM6bVEo05VvhjRS0M8yWoZVi-7Vdsc0LqI0Qdq_NoctX5Fu-AqiBN7Uo1HkYGcP2oC82J_J5cjw98BQiP5kDWThq9RK-X6S-EUALx_m4iG6iOYKTA3SQyf1xBqFaXXoEJjcckbOqkegecz5b-YWUh8iZPvhwnt-RZwpIbLJgKwz19ndkn9KvoEEw7YbEow&quot;,
+    e: &quot;AQAB&quot;,
+    d: &quot;cj5DkDakjM2bKduGWJREO-_zyEtuA1dD9doqKMd7IRuA0CDS7puEAS20-oXRDwfmyMXEdEUDrGGtCxh6fzDPvs_T-JA3GUK4EgHo3xZcrlXDXlKCeil6Fnr0gISZOIh5dkBrcdVL4quBJe4ZZc5mVuAC7Ld13et0TxMJ4iALGrPuqPVUOGSYIcZ9idx5zKKBWhY3tPggEdKpnHBmPfTRO4yZaf0Nw1QXrgSMZY9ejeuaurAh4Q8o4-6-r8O2LUe7ufMh_ccKkXISEh4KdOnT17EM9BQTn9UNS9GoK2ZZU0U3io5DSu_kpasr4uOVWcGlE2wczOv2nkGwG39F3sFF0Q&quot;,
+    p: &quot;x5vnco5j-TD6hTOzyN4DhkZ44m05NycxT6SUE2qTurT3-uze_L7TYutLRIRkovRMhTHZAr2pziRlasEs13PEz9Zvx1I_T68srsonrdbak-SFMecM7EjHc5C-J13gXhw9HIW28_Sx9rQ-JkGwEwE9PEdIUfuvdqpgh3SmXwPJrEs&quot;,
+    q: &quot;wb9vllg_2n-kNge0bThg_7xu1UwTzipM8vxSUkkV2IipJKIAekkU3aAB8LoPhUI0-17pSGw3ETOO27t163TI9qIPpzLbhTH9aUi7qLGbKlzPlgnqP43Z0LHxc3xKDgit-Ar29QLaX2uoJBX6VVWvhmh7BIPDHNVM5GZjwWORYgk&quot;,
+    dp: &quot;C2c8sa6wx2uk5Dcv7inAycr83PKgciYrCwG78-AC0IfGIu-lTYsZSG1ov2FQ3n5WYMWYQC_Vo5EwugiPJz_V3onBmQF53HOFefbSjXvYwNotQcyRUG5X9qIuOtGCH949H4QED6vK_u0NH-JgzLUlamwoFYbrXzwch6CCYKs2ukE&quot;,
+    dq: &quot;hbtRloDLclHwUqr2yvzDV0IFbozYjtF706x-VfXEcnXB6ls34TBYirFLJZIH7H9KeseEVkz7pY_k5555QlCV9kbebxYXl9RtiiJ-BW6yH4d4caPeYIfU9MweUQxVQWKUUkWfOHcDrCFvKZlR9Vzzjt7HKtKX9mr0bCKQcIf9baE&quot;,
+    qi: &quot;a-7hUTTnclUPKOfSgH8zEKGJ-AvdFEzxvZ5sq46Qf2MbORxVjN4dJamVvM-FoqcwN-9cuUlyr9bSFTwUBW4vXa8Xj9a8JfViuMCqzR-mL1rGIUQ5ARGhNcSsRlyKTqz5BlWlVKmXIx_p-DeVwPWiJJy4k_FqyBxrnxkzomHfrxk&quot;,
+};
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var aesCbcParams = {
+    name: &quot;aes-cbc&quot;,
+    iv: asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;),
+}
+var wrappedKey = hexStringToUint8Array( &quot;848aa2f70ee18e2953520132a79cf479b03a8732a3cc73f8c51c68456d3c2557e8be9d5911b2a74267e282a87ffeed88dfbac38a22c26ba621f83915d7539420a4dc0b2329c585b442967367c1ea6c1126f98c4f13b7c8cb7402b86a5844c19420ea333dc33d908be89172f8bac59b403fe202f32c8eed19f431cedfc3383f536f3557163b1311ae42ee5486c6dafee968640d6b6999c687f37fba8d65cc662f1c84f16245665e4af41c98e8b63632cc1d19e2bece2154c7eab1905f3f6ab17b495cefec3508e9b451f2ea1422b97f275dfdc118f46af02040250d0e55d8d8d172b969bbcf7314a257f10b98d2c47c6c72a727acaf4c96340d590ebcebc61f73b7a868b490f3c1e17c59ea479a3b8db5574153de46cfdbb07cfc5e95ebcf7ad3d5fa057ba946d6da872c4bef3af6d7013e222c227650d0022c94d306cb14e203aad378d171c7c24f824c31b81fd18265e0de2f4b415584ebc4adeb5880c4eddbc88b854699f7aa74d6a10ca5df8978f27b5d1372b31ea67a9c4841ae101ea6ad78df0580b70358e6933ac92f7faee5320af329d8349a7b98690708a388737604be0affaa0669410d8d93dc4e4f57e14583253f11e5b27c89b84f1f3038bae6d9b37e3eb64b63ad1880627aef3b19e3e851cfae639ec46dd
 06fd131b51f530b37260b836d9013d8ad7c8640096070f96984c528ee5e20b69f3cd98a269621cd886ccb16d9c526a87cd5c458541309bb7fa4f3337305d76fc050d39ca8b1fdb0675a11a40ffde9cebb33ddc485e5dc5e7667b08c2a3e0136d063a447aee5a8f650429c5e422a706c4c240a4d11f4a9b5782f2cba2575f0c32cb477a9f0cef97fa993977104181315ff90e46f3b12b8b00f4a7611c42b1bb53d0e6021ab21ee8ae606d9f06dfedb891763007e020977c28b46d5f33bc35c12061d90ebbe02cab58783c0cac0c6f14ed735204f23d0eb6a9fe9edea2aecb1ac213f58b42d5d96374ec70ca288a31016ba02adef43250d717e9fab8982a1a180b1f3944d450c159010fd23f354d88502ec702882ae3edd567c6a6edf3cb2e34edc13f410a25d97298ab9062ddb566576fa8b6599bba205bab55aa5f3f37edaf7733cf249e69c74da975ef249ca673da749d86babebdf55410a389720ac943f1e9d921f5d69c5789636cb904fb9263744236eade9acae889a01c237ab3436101463dfa9d92f936c1b652c80f3abba76023ebe5b9bfdd54735e3a3494de18a456967f58758e546021feef3fa3e6c239981aa06f1f7ddc415d957ff9919bbec5f36af092a81ba6c14fe644d2ee98a2fcdee2ed70b87a53ffa327b25b4569c5886b15f2bd583d6f5bd7e951a915142baa0
 8c6a9c343c200678a005fad22a337d2c5627f8c816db2525a7e121849b9da756eee68a240452849ffdb9651f998257c62e8fdcdc48dadfc3ebb18f7eb5461442008846a629ec8149c052f357bf5889095047b272bce0ff505953e7cd525b24c838ba6e9ed91922a30eeb858de8556f19f761d0287d768876346a5dcac3dbadd7a30072c9338162be5812166d961f4031f962ef668781d39d0fc69fe5f4494e31ec082d4a0140e368b69975beeba120ef9b651ead531b4d44296bd3cfe2ce7f97bb5bb4921061b12c2e1c4c10928c0980ff8d488a2282d0c056a40260167410e39664f75ff1f1249820e174eed978318a05e654b8aa6c60b70001a7a04f0aff17597dd9ab3ccc34f5ba2e352b7244dd3dccb462d7175b95ae3970ec5858e2312aac7c2c79a37b53d089f988720a4c04df6328a384004d0d51eafb9486623099a98e69be5169201c88824acc2bb0e1790889014a1797c168e98d19f0787c2935cfbc3bf24c4adad69a81e0e6adf8c21e3c4789064aa31a025dff5cc6eaba3f3e43f10a9d531f47963372120e2366b84c281ed968d9d11c1d103826c9362741e1267d1a3e8d2188761fa876b7b09617df14130c07209f1f1188ff40971b86607dee14d556a880447901c69d29cb16c027c3aae316ff00132bdfcd0e39c5e201252c9771483ccb275b0c67b3cb4dcd191
 98c7718634460254dfd6f8df4374b8bedee7dd20ce411b5f987cac2ce17492aa78f919c6d5e555000f47f7b8a9896d448bc4fc13e40a9e5c02258d509a7289f44d7250e89260233bf96702bb3d350451f03d802e0e37d9f01cce4c78869403493eb9890c2c09109d1f427f59cf091cd1c836e25a9bb065041407c2183f643bce2e72db1e7caeac42e2d8379f8b84df2cc7b1d055f42d6f62e0cb5771a14ae8872792350e5f770115a86564f60a785c53325c8c084afe214da3cac1783e2be9099d96ddbe9cc3ea3dd1d3ae50526b4afe24397420a3e4fa697613421&quot;);
+
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-cbc&quot;, extractable, [&quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedKey, unwrappingKey, aesCbcParams, {name: &quot;rsa-oaep&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;unwrappedKey.kty&quot;, &quot;jwkKey.kty&quot;);
+    shouldBe(&quot;unwrappedKey.alg&quot;, &quot;jwkKey.alg&quot;);
+    shouldBe(&quot;unwrappedKey.key_ops&quot;, &quot;jwkKey.key_ops&quot;);
+    shouldBe(&quot;unwrappedKey.ext&quot;, &quot;jwkKey.ext&quot;);
+    shouldBe(&quot;unwrappedKey.n&quot;, &quot;jwkKey.n&quot;);
+    shouldBe(&quot;unwrappedKey.e&quot;, &quot;jwkKey.e&quot;);
+    // FIXME: Since we actually recaculate the private exponent based on modulus, public exponent, first prime factor, and second prime factor,
+    // this exported private exponent may not match the imported one.
+    // shouldBe(&quot;exportedJwkKey.d&quot;, &quot;jwkKey.d&quot;);
+    shouldBe(&quot;unwrappedKey.p&quot;, &quot;jwkKey.p&quot;);
+    shouldBe(&quot;unwrappedKey.q&quot;, &quot;jwkKey.q&quot;);
+    shouldBe(&quot;unwrappedKey.dp&quot;, &quot;jwkKey.dp&quot;);
+    shouldBe(&quot;unwrappedKey.dq&quot;, &quot;jwkKey.dq&quot;);
+    shouldBe(&quot;unwrappedKey.qi&quot;, &quot;jwkKey.qi&quot;);
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaescbcimportkeyuwrapjwkrsakeypublicexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+Test unwrapping a JWK RSA public key with AES-CBC using an imported key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS unwrappedKey.kty is jwkKey.kty
+PASS unwrappedKey.alg is jwkKey.alg
+PASS unwrappedKey.key_ops is jwkKey.key_ops
+PASS unwrappedKey.ext is jwkKey.ext
+PASS unwrappedKey.n is jwkKey.n
+PASS unwrappedKey.e is jwkKey.e
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaescbcimportkeyuwrapjwkrsakeypublichtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test unwrapping a JWK RSA public key with AES-CBC using an imported key&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkKey = {
+    kty: &quot;RSA&quot;,
+    alg: &quot;RSA-OAEP&quot;,
+    use: &quot;enc&quot;,
+    key_ops: [&quot;encrypt&quot;],
+    ext: true,
+    n: &quot;rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw&quot;,
+    e: &quot;AQAB&quot;
+};
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var aesCbcParams = {
+    name: &quot;aes-cbc&quot;,
+    iv: asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;),
+}
+var wrappedKey = hexStringToUint8Array( &quot;848aa2f70ee18e2953520132a79cf47946e00c99362340bb690edc9ab5315757462c128278c6232e770e7437c56ed722a8e1703855f7f3e565394e1a6a0305c4ef1b30fa4c7f72d1a239cc6c6ba067898798a36a75132c66b4a2d3fb942886affd3ea3b2756b0ddc886c01e3b93107469b82124468408ef8ab548b85aa8f206c312d74ce4f2c679eb147a275cefda64d5bdc4a2b5b90a4ac9ad3eb5f2cf19f5f87653211f59b4731ba61125582a233951097dea65db05899d587d1dcfccab9ab7410ab3010b89066506dbacbc6b73e4b564792751388fa0f58d55c59c14a08c9dfb0f78100b0f5cc29d62328822636d30a6a153ec5cd4727ad5e47b419c48544565637ac5789863d43b7da78cf4383d09d66e9d458e436dbfbee75e382b2bab49eec2c7491ff93cf099fe92feaf4658e30889fd12d3ae61cd5e8c8e1e56a079b662f90cd10cdbdbb4d12eefb36d825e1a043e82f5a98f8960d655d3f9ed5af31e581fa846cc582f6cee5c25e0b3c32050534ae957ce27860d470ba26da2c7d6fa621b0faa8becad58e9e55bb2a9d984b042f25df21482529870d271cbf5508a0edfc3cb37316c11f16b342bc1f1f98aa&quot;);
+
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-cbc&quot;, extractable, [&quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedKey, unwrappingKey, aesCbcParams, {name: &quot;rsa-oaep&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;encrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;unwrappedKey.kty&quot;, &quot;jwkKey.kty&quot;);
+    shouldBe(&quot;unwrappedKey.alg&quot;, &quot;jwkKey.alg&quot;);
+    shouldBe(&quot;unwrappedKey.key_ops&quot;, &quot;jwkKey.key_ops&quot;);
+    shouldBe(&quot;unwrappedKey.ext&quot;, &quot;jwkKey.ext&quot;);
+    shouldBe(&quot;unwrappedKey.n&quot;, &quot;jwkKey.n&quot;);
+    shouldBe(&quot;unwrappedKey.e&quot;, &quot;jwkKey.e&quot;);
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaeskwgeneratekeywrapkeyunwrapkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+Test wrapKey/unwrapKey with AES-KW using a generated key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Generating...
+Wrapping...
+PASS bytesToASCIIString(wrappedKey) is not &quot;jnOw99oOZFLIEPMr&quot;
+Unwrapping...
+PASS bytesToASCIIString(unwrappedKey) is rawKeyASCII
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaeskwgeneratekeywrapkeyunwrapkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test wrapKey/unwrapKey with AES-KW using a generated key&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKeyASCII = &quot;jnOw99oOZFLIEPMr&quot;;
+var rawKey = asciiToUint8Array(rawKeyASCII);
+var wrappedKey = hexStringToUint8Array(&quot;d64787ab3e048dbdc30bb62781c9f18e58ad7dbfc64aab16&quot;);
+
+debug(&quot;Generating...&quot;);
+crypto.subtle.generateKey({ name: &quot;aes-kw&quot;, length: 256 }, extractable, [&quot;wrapKey&quot;, &quot;unwrapKey&quot;]).then(function(result) {
+    wrapKey = result;
+    return crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-cbc&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(key) {
+    debug(&quot;Wrapping...&quot;);
+    return crypto.subtle.wrapKey(&quot;raw&quot;, key, wrapKey, &quot;AES-KW&quot;);
+}).then(function(result) {
+    wrappedKey = result;
+
+    shouldNotBeEqualToString(&quot;bytesToASCIIString(wrappedKey)&quot;, rawKeyASCII);
+
+    debug(&quot;Unwrapping...&quot;);
+    return crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedKey, wrapKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;raw&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;bytesToASCIIString(unwrappedKey)&quot;, &quot;rawKeyASCII&quot;);
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaeskwimportkeyunwraprawkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Test unwrapping a raw key with AES-KW using an imported key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS bytesToASCIIString(unwrappedKey) is rawKeyASCII
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleaeskwimportkeyunwraprawkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-kw-import-key-unwrap-raw-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test unwrapping a raw key with AES-KW using an imported key&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKeyASCII = &quot;jnOw99oOZFLIEPMr&quot;;
+var rawKey = asciiToUint8Array(rawKeyASCII);
+var wrappedKey = hexStringToUint8Array(&quot;d64787ab3e048dbdc30bb62781c9f18e58ad7dbfc64aab16&quot;);
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-kw&quot;, extractable, [&quot;wrapKey&quot;, &quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;raw&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;bytesToASCIIString(unwrappedKey)&quot;, &quot;rawKeyASCII&quot;);
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtlersaoaepimportkeyunwrapjwkoctkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+Test unwrapping a JWK oct key with RSA-OAEP using an imported key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS unwrappedKey.kty is 'oct'
+PASS Base64URL.parse(unwrappedKey.k) is rawKey
+PASS unwrappedKey.alg is 'A128CBC'
+PASS unwrappedKey.key_ops is ['decrypt', 'encrypt']
+PASS unwrappedKey.ext is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtlersaoaepimportkeyunwrapjwkoctkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test unwrapping a JWK oct key with RSA-OAEP using an imported key&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var jwkKey = {
+    kty: &quot;RSA&quot;,
+    alg: &quot;RSA-OAEP&quot;,
+    use: &quot;enc&quot;,
+    key_ops: [&quot;unwrapKey&quot;],
+    ext: true,
+    n: &quot;lxHN0N9VRZ0_pl0xv3-NXx70WnjkODSkQ5LjHXTFy3DOQsvkagFzD9HqYQezCmcewLjdK5PLwSesDoMdfL6tusBHcvyit1kvydYFQ3NLbENNkYsiBG5_nW4IQGL6JKbZ5iGdUop98QHKm6YZR1u4zrAtxM6bVEo05VvhjRS0M8yWoZVi-7Vdsc0LqI0Qdq_NoctX5Fu-AqiBN7Uo1HkYGcP2oC82J_J5cjw98BQiP5kDWThq9RK-X6S-EUALx_m4iG6iOYKTA3SQyf1xBqFaXXoEJjcckbOqkegecz5b-YWUh8iZPvhwnt-RZwpIbLJgKwz19ndkn9KvoEEw7YbEow&quot;,
+    e: &quot;AQAB&quot;,
+    d: &quot;cj5DkDakjM2bKduGWJREO-_zyEtuA1dD9doqKMd7IRuA0CDS7puEAS20-oXRDwfmyMXEdEUDrGGtCxh6fzDPvs_T-JA3GUK4EgHo3xZcrlXDXlKCeil6Fnr0gISZOIh5dkBrcdVL4quBJe4ZZc5mVuAC7Ld13et0TxMJ4iALGrPuqPVUOGSYIcZ9idx5zKKBWhY3tPggEdKpnHBmPfTRO4yZaf0Nw1QXrgSMZY9ejeuaurAh4Q8o4-6-r8O2LUe7ufMh_ccKkXISEh4KdOnT17EM9BQTn9UNS9GoK2ZZU0U3io5DSu_kpasr4uOVWcGlE2wczOv2nkGwG39F3sFF0Q&quot;,
+    p: &quot;x5vnco5j-TD6hTOzyN4DhkZ44m05NycxT6SUE2qTurT3-uze_L7TYutLRIRkovRMhTHZAr2pziRlasEs13PEz9Zvx1I_T68srsonrdbak-SFMecM7EjHc5C-J13gXhw9HIW28_Sx9rQ-JkGwEwE9PEdIUfuvdqpgh3SmXwPJrEs&quot;,
+    q: &quot;wb9vllg_2n-kNge0bThg_7xu1UwTzipM8vxSUkkV2IipJKIAekkU3aAB8LoPhUI0-17pSGw3ETOO27t163TI9qIPpzLbhTH9aUi7qLGbKlzPlgnqP43Z0LHxc3xKDgit-Ar29QLaX2uoJBX6VVWvhmh7BIPDHNVM5GZjwWORYgk&quot;,
+    dp: &quot;C2c8sa6wx2uk5Dcv7inAycr83PKgciYrCwG78-AC0IfGIu-lTYsZSG1ov2FQ3n5WYMWYQC_Vo5EwugiPJz_V3onBmQF53HOFefbSjXvYwNotQcyRUG5X9qIuOtGCH949H4QED6vK_u0NH-JgzLUlamwoFYbrXzwch6CCYKs2ukE&quot;,
+    dq: &quot;hbtRloDLclHwUqr2yvzDV0IFbozYjtF706x-VfXEcnXB6ls34TBYirFLJZIH7H9KeseEVkz7pY_k5555QlCV9kbebxYXl9RtiiJ-BW6yH4d4caPeYIfU9MweUQxVQWKUUkWfOHcDrCFvKZlR9Vzzjt7HKtKX9mr0bCKQcIf9baE&quot;,
+    qi: &quot;a-7hUTTnclUPKOfSgH8zEKGJ-AvdFEzxvZ5sq46Qf2MbORxVjN4dJamVvM-FoqcwN-9cuUlyr9bSFTwUBW4vXa8Xj9a8JfViuMCqzR-mL1rGIUQ5ARGhNcSsRlyKTqz5BlWlVKmXIx_p-DeVwPWiJJy4k_FqyBxrnxkzomHfrxk&quot;,
+};
+var wrappedJwkKey = hexStringToUint8Array(&quot;5bf8b98ac4f00c04fbe85900296e4b411acede31c57d1689d6a9678966bf4eb2019da921deb7a410cc0ef1ebecfbd2db6105168d133a5dbeb29f69efc61b4d63d37feb8460bbd319459b180f8661d01d087a929413cfa4fd94e355137fbb54413837e47c4e114e82337261a5bbfe20637b6b08dc4974ef1fbefcaac5a4f463021b810ddf7c9a2ddecb119e82602dc14135a3787ed8ab40aedca74755d3518b35dc38ebe85dd13b5500bae3bd5e2f25b6dfcf8c9265ddd0473bf4f69d3d40f2409462d35a7be7902029bd8f7c2ea1d879b07eda52638e93722cece9658e1acd6768d78d00b214349555853511762919854b4991fa110a08b6e6b9e6d93484f143&quot;);
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, {name: &quot;rsa-oaep&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedJwkKey, unwrappingKey, &quot;rsa-oaep&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;unwrappedKey.kty&quot;, &quot;'oct'&quot;);
+    shouldBe(&quot;Base64URL.parse(unwrappedKey.k)&quot;, &quot;rawKey&quot;);
+    shouldBe(&quot;unwrappedKey.alg&quot;, &quot;'A128CBC'&quot;);
+    shouldBe(&quot;unwrappedKey.key_ops&quot;, &quot;['decrypt', 'encrypt']&quot;);
+    shouldBe(&quot;unwrappedKey.ext&quot;, &quot;true&quot;);
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleunwrapKeymalformedparametersexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+Test UnwrapKey operation with malformed parameters
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS crypto.subtle.unwrapKey() rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1, 2) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1, 2, 3) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1, 2, 3, 4) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1, 2, 3, 4, 5) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(1, 2, 3, 4, 5, 6) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;HMAC&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, aesCbcParams, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]) rejected promise  with InvalidAccessError (DOM Exception 15): Unwrapping CryptoKey doesn't match unwrap AlgorithmIdentifier.
+PASS crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]) rejected promise  with DataError (DOM Exception 30): WrappedKey cannot be converted to a JSON object.
+PASS crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [ ]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedJwkKey, unwrappingKey, aesCbcParams, {name: &quot;RSA-OAEP&quot;, hash: &quot;SHA-1&quot;}, extractable, [ ]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]) rejected promise  with InvalidAccessError (DOM Exception 15): Unwrapping CryptoKey doesn't support unwrapKey operation.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleunwrapKeymalformedparametershtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/unwrapKey-malformed-parameters.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test UnwrapKey operation with malformed parameters&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var aesCbcParams = {
+    name: &quot;aes-cbc&quot;,
+    iv: asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;),
+}
+var wrappedRawKey = hexStringToUint8Array(&quot;d64787ab3e048dbdc30bb62781c9f18e58ad7dbfc64aab16&quot;);
+var wrappedJwkKey = hexStringToUint8Array( &quot;848aa2f70ee18e2953520132a79cf479b03a8732a3cc73f8c51c68456d3c2557e8be9d5911b2a74267e282a87ffeed88dfbac38a22c26ba621f83915d7539420a4dc0b2329c585b442967367c1ea6c1126f98c4f13b7c8cb7402b86a5844c19420ea333dc33d908be89172f8bac59b403fe202f32c8eed19f431cedfc3383f536f3557163b1311ae42ee5486c6dafee968640d6b6999c687f37fba8d65cc662f1c84f16245665e4af41c98e8b63632cc1d19e2bece2154c7eab1905f3f6ab17b495cefec3508e9b451f2ea1422b97f275dfdc118f46af02040250d0e55d8d8d172b969bbcf7314a257f10b98d2c47c6c72a727acaf4c96340d590ebcebc61f73b7a868b490f3c1e17c59ea479a3b8db5574153de46cfdbb07cfc5e95ebcf7ad3d5fa057ba946d6da872c4bef3af6d7013e222c227650d0022c94d306cb14e203aad378d171c7c24f824c31b81fd18265e0de2f4b415584ebc4adeb5880c4eddbc88b854699f7aa74d6a10ca5df8978f27b5d1372b31ea67a9c4841ae101ea6ad78df0580b70358e6933ac92f7faee5320af329d8349a7b98690708a388737604be0affaa0669410d8d93dc4e4f57e14583253f11e5b27c89b84f1f3038bae6d9b37e3eb64b63ad1880627aef3b19e3e851cfae639ec4
 6dd06fd131b51f530b37260b836d9013d8ad7c8640096070f96984c528ee5e20b69f3cd98a269621cd886ccb16d9c526a87cd5c458541309bb7fa4f3337305d76fc050d39ca8b1fdb0675a11a40ffde9cebb33ddc485e5dc5e7667b08c2a3e0136d063a447aee5a8f650429c5e422a706c4c240a4d11f4a9b5782f2cba2575f0c32cb477a9f0cef97fa993977104181315ff90e46f3b12b8b00f4a7611c42b1bb53d0e6021ab21ee8ae606d9f06dfedb891763007e020977c28b46d5f33bc35c12061d90ebbe02cab58783c0cac0c6f14ed735204f23d0eb6a9fe9edea2aecb1ac213f58b42d5d96374ec70ca288a31016ba02adef43250d717e9fab8982a1a180b1f3944d450c159010fd23f354d88502ec702882ae3edd567c6a6edf3cb2e34edc13f410a25d97298ab9062ddb566576fa8b6599bba205bab55aa5f3f37edaf7733cf249e69c74da975ef249ca673da749d86babebdf55410a389720ac943f1e9d921f5d69c5789636cb904fb9263744236eade9acae889a01c237ab3436101463dfa9d92f936c1b652c80f3abba76023ebe5b9bfdd54735e3a3494de18a456967f58758e546021feef3fa3e6c239981aa06f1f7ddc415d957ff9919bbec5f36af092a81ba6c14fe644d2ee98a2fcdee2ed70b87a53ffa327b25b4569c5886b15f2bd583d6f5bd7e951a915142b
 aa08c6a9c343c200678a005fad22a337d2c5627f8c816db2525a7e121849b9da756eee68a240452849ffdb9651f998257c62e8fdcdc48dadfc3ebb18f7eb5461442008846a629ec8149c052f357bf5889095047b272bce0ff505953e7cd525b24c838ba6e9ed91922a30eeb858de8556f19f761d0287d768876346a5dcac3dbadd7a30072c9338162be5812166d961f4031f962ef668781d39d0fc69fe5f4494e31ec082d4a0140e368b69975beeba120ef9b651ead531b4d44296bd3cfe2ce7f97bb5bb4921061b12c2e1c4c10928c0980ff8d488a2282d0c056a40260167410e39664f75ff1f1249820e174eed978318a05e654b8aa6c60b70001a7a04f0aff17597dd9ab3ccc34f5ba2e352b7244dd3dccb462d7175b95ae3970ec5858e2312aac7c2c79a37b53d089f988720a4c04df6328a384004d0d51eafb9486623099a98e69be5169201c88824acc2bb0e1790889014a1797c168e98d19f0787c2935cfbc3bf24c4adad69a81e0e6adf8c21e3c4789064aa31a025dff5cc6eaba3f3e43f10a9d531f47963372120e2366b84c281ed968d9d11c1d103826c9362741e1267d1a3e8d2188761fa876b7b09617df14130c07209f1f1188ff40971b86607dee14d556a880447901c69d29cb16c027c3aae316ff00132bdfcd0e39c5e201252c9771483ccb275b0c67b3cb4dcd
 19198c7718634460254dfd6f8df4374b8bedee7dd20ce411b5f987cac2ce17492aa78f919c6d5e555000f47f7b8a9896d448bc4fc13e40a9e5c02258d509a7289f44d7250e89260233bf96702bb3d350451f03d802e0e37d9f01cce4c78869403493eb9890c2c09109d1f427f59cf091cd1c836e25a9bb065041407c2183f643bce2e72db1e7caeac42e2d8379f8b84df2cc7b1d055f42d6f62e0cb5771a14ae8872792350e5f770115a86564f60a785c53325c8c084afe214da3cac1783e2be9099d96ddbe9cc3ea3dd1d3ae50526b4afe24397420a3e4fa697613421&quot;);
+
+// Not enough arguments.
+shouldReject('crypto.subtle.unwrapKey()');
+shouldReject('crypto.subtle.unwrapKey(1)');
+shouldReject('crypto.subtle.unwrapKey(1, 2)');
+shouldReject('crypto.subtle.unwrapKey(1, 2, 3)');
+shouldReject('crypto.subtle.unwrapKey(1, 2, 3, 4)');
+shouldReject('crypto.subtle.unwrapKey(1, 2, 3, 4, 5)');
+shouldReject('crypto.subtle.unwrapKey(1, 2, 3, 4, 5, 6)');
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-kw&quot;, extractable, [&quot;wrapKey&quot;, &quot;unwrapKey&quot;]).then(function(result) {
+    unwrappingKey = result;
+
+    // Wrong AlgorithmIdentifier
+    shouldReject('crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;HMAC&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;])');
+    shouldReject('crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, aesCbcParams, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;])');
+    // Wrong format
+    return shouldReject('crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;])');
+}).then(function() {
+    // Empty usages
+    return shouldReject('crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [ ])');
+}).then(function() {
+    return crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-cbc&quot;, extractable, [&quot;wrapKey&quot;, &quot;unwrapKey&quot;]);
+}).then(function(result) {
+    unwrappingKey = result;
+
+    // Empty usages
+    return shouldReject('crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedJwkKey, unwrappingKey, aesCbcParams, {name: &quot;RSA-OAEP&quot;, hash: &quot;SHA-1&quot;}, extractable, [ ])');
+}).then(function() {
+    return crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-kw&quot;, extractable, [&quot;wrapKey&quot;]);
+}).then(function(result) {
+    unwrappingKey = result;
+
+    // Wrong usage
+    shouldReject('crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedRawKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;])').then(finishJSTest);
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleaescbcimportkeyunwrapkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+[Worker] Test unwrapping a JWK RSA public key with AES-CBC using an imported key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/aes-cbc-import-key-unwrap-key.js
+PASS [Worker] unwrappedKey.kty is jwkKey.kty
+PASS [Worker] unwrappedKey.alg is jwkKey.alg
+PASS [Worker] unwrappedKey.key_ops is jwkKey.key_ops
+PASS [Worker] unwrappedKey.ext is jwkKey.ext
+PASS [Worker] unwrappedKey.n is jwkKey.n
+PASS [Worker] unwrappedKey.e is jwkKey.e
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleaescbcimportkeyunwrapkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        worker = startWorker('resources/aes-cbc-import-key-unwrap-key.js');
+    &lt;/script&gt;
+    &lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleaeskwimportkeyunwrapkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+[Worker] Test unwrapping a raw key with AES-KW using an imported key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/aes-kw-import-key-unwrap-key.js
+PASS [Worker] bytesToASCIIString(unwrappedKey) is rawKeyASCII
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleaeskwimportkeyunwrapkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/aes-kw-import-key-unwrap-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        worker = startWorker('resources/aes-kw-import-key-unwrap-key.js');
+    &lt;/script&gt;
+    &lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesaescbcimportkeyunwrapkeyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts('../../../resources/common.js');
+
+description(&quot;Test unwrapping a JWK RSA public key with AES-CBC using an imported key in workers&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkKey = {
+    kty: &quot;RSA&quot;,
+    alg: &quot;RSA-OAEP&quot;,
+    use: &quot;enc&quot;,
+    key_ops: [&quot;encrypt&quot;],
+    ext: true,
+    n: &quot;rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw&quot;,
+    e: &quot;AQAB&quot;
+};
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var aesCbcParams = {
+    name: &quot;aes-cbc&quot;,
+    iv: asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;),
+}
+var wrappedKey = hexStringToUint8Array( &quot;848aa2f70ee18e2953520132a79cf47946e00c99362340bb690edc9ab5315757462c128278c6232e770e7437c56ed722a8e1703855f7f3e565394e1a6a0305c4ef1b30fa4c7f72d1a239cc6c6ba067898798a36a75132c66b4a2d3fb942886affd3ea3b2756b0ddc886c01e3b93107469b82124468408ef8ab548b85aa8f206c312d74ce4f2c679eb147a275cefda64d5bdc4a2b5b90a4ac9ad3eb5f2cf19f5f87653211f59b4731ba61125582a233951097dea65db05899d587d1dcfccab9ab7410ab3010b89066506dbacbc6b73e4b564792751388fa0f58d55c59c14a08c9dfb0f78100b0f5cc29d62328822636d30a6a153ec5cd4727ad5e47b419c48544565637ac5789863d43b7da78cf4383d09d66e9d458e436dbfbee75e382b2bab49eec2c7491ff93cf099fe92feaf4658e30889fd12d3ae61cd5e8c8e1e56a079b662f90cd10cdbdbb4d12eefb36d825e1a043e82f5a98f8960d655d3f9ed5af31e581fa846cc582f6cee5c25e0b3c32050534ae957ce27860d470ba26da2c7d6fa621b0faa8becad58e9e55bb2a9d984b042f25df21482529870d271cbf5508a0edfc3cb37316c11f16b342bc1f1f98aa&quot;);
+
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-cbc&quot;, extractable, [&quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedKey, unwrappingKey, aesCbcParams, {name: &quot;rsa-oaep&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;encrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;unwrappedKey.kty&quot;, &quot;jwkKey.kty&quot;);
+    shouldBe(&quot;unwrappedKey.alg&quot;, &quot;jwkKey.alg&quot;);
+    shouldBe(&quot;unwrappedKey.key_ops&quot;, &quot;jwkKey.key_ops&quot;);
+    shouldBe(&quot;unwrappedKey.ext&quot;, &quot;jwkKey.ext&quot;);
+    shouldBe(&quot;unwrappedKey.n&quot;, &quot;jwkKey.n&quot;);
+    shouldBe(&quot;unwrappedKey.e&quot;, &quot;jwkKey.e&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesaeskwimportkeyunwrapkeyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts('../../../resources/common.js');
+
+description(&quot;Test unwrapping a raw key with AES-KW using an imported key in workers&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKeyASCII = &quot;jnOw99oOZFLIEPMr&quot;;
+var rawKey = asciiToUint8Array(rawKeyASCII);
+var wrappedKey = hexStringToUint8Array(&quot;d64787ab3e048dbdc30bb62781c9f18e58ad7dbfc64aab16&quot;);
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, &quot;aes-kw&quot;, extractable, [&quot;wrapKey&quot;, &quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;raw&quot;, wrappedKey, unwrappingKey, &quot;AES-KW&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;raw&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;bytesToASCIIString(unwrappedKey)&quot;, &quot;rawKeyASCII&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesrsaoaepimportkeyunwrapkeyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts('../../../resources/common.js');
+
+description(&quot;Test unwrapping a JWK oct key with RSA-OAEP using an imported key in workers&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var jwkKey = {
+    kty: &quot;RSA&quot;,
+    alg: &quot;RSA-OAEP&quot;,
+    use: &quot;enc&quot;,
+    key_ops: [&quot;unwrapKey&quot;],
+    ext: true,
+    n: &quot;lxHN0N9VRZ0_pl0xv3-NXx70WnjkODSkQ5LjHXTFy3DOQsvkagFzD9HqYQezCmcewLjdK5PLwSesDoMdfL6tusBHcvyit1kvydYFQ3NLbENNkYsiBG5_nW4IQGL6JKbZ5iGdUop98QHKm6YZR1u4zrAtxM6bVEo05VvhjRS0M8yWoZVi-7Vdsc0LqI0Qdq_NoctX5Fu-AqiBN7Uo1HkYGcP2oC82J_J5cjw98BQiP5kDWThq9RK-X6S-EUALx_m4iG6iOYKTA3SQyf1xBqFaXXoEJjcckbOqkegecz5b-YWUh8iZPvhwnt-RZwpIbLJgKwz19ndkn9KvoEEw7YbEow&quot;,
+    e: &quot;AQAB&quot;,
+    d: &quot;cj5DkDakjM2bKduGWJREO-_zyEtuA1dD9doqKMd7IRuA0CDS7puEAS20-oXRDwfmyMXEdEUDrGGtCxh6fzDPvs_T-JA3GUK4EgHo3xZcrlXDXlKCeil6Fnr0gISZOIh5dkBrcdVL4quBJe4ZZc5mVuAC7Ld13et0TxMJ4iALGrPuqPVUOGSYIcZ9idx5zKKBWhY3tPggEdKpnHBmPfTRO4yZaf0Nw1QXrgSMZY9ejeuaurAh4Q8o4-6-r8O2LUe7ufMh_ccKkXISEh4KdOnT17EM9BQTn9UNS9GoK2ZZU0U3io5DSu_kpasr4uOVWcGlE2wczOv2nkGwG39F3sFF0Q&quot;,
+    p: &quot;x5vnco5j-TD6hTOzyN4DhkZ44m05NycxT6SUE2qTurT3-uze_L7TYutLRIRkovRMhTHZAr2pziRlasEs13PEz9Zvx1I_T68srsonrdbak-SFMecM7EjHc5C-J13gXhw9HIW28_Sx9rQ-JkGwEwE9PEdIUfuvdqpgh3SmXwPJrEs&quot;,
+    q: &quot;wb9vllg_2n-kNge0bThg_7xu1UwTzipM8vxSUkkV2IipJKIAekkU3aAB8LoPhUI0-17pSGw3ETOO27t163TI9qIPpzLbhTH9aUi7qLGbKlzPlgnqP43Z0LHxc3xKDgit-Ar29QLaX2uoJBX6VVWvhmh7BIPDHNVM5GZjwWORYgk&quot;,
+    dp: &quot;C2c8sa6wx2uk5Dcv7inAycr83PKgciYrCwG78-AC0IfGIu-lTYsZSG1ov2FQ3n5WYMWYQC_Vo5EwugiPJz_V3onBmQF53HOFefbSjXvYwNotQcyRUG5X9qIuOtGCH949H4QED6vK_u0NH-JgzLUlamwoFYbrXzwch6CCYKs2ukE&quot;,
+    dq: &quot;hbtRloDLclHwUqr2yvzDV0IFbozYjtF706x-VfXEcnXB6ls34TBYirFLJZIH7H9KeseEVkz7pY_k5555QlCV9kbebxYXl9RtiiJ-BW6yH4d4caPeYIfU9MweUQxVQWKUUkWfOHcDrCFvKZlR9Vzzjt7HKtKX9mr0bCKQcIf9baE&quot;,
+    qi: &quot;a-7hUTTnclUPKOfSgH8zEKGJ-AvdFEzxvZ5sq46Qf2MbORxVjN4dJamVvM-FoqcwN-9cuUlyr9bSFTwUBW4vXa8Xj9a8JfViuMCqzR-mL1rGIUQ5ARGhNcSsRlyKTqz5BlWlVKmXIx_p-DeVwPWiJJy4k_FqyBxrnxkzomHfrxk&quot;,
+};
+var wrappedJwkKey = hexStringToUint8Array(&quot;5bf8b98ac4f00c04fbe85900296e4b411acede31c57d1689d6a9678966bf4eb2019da921deb7a410cc0ef1ebecfbd2db6105168d133a5dbeb29f69efc61b4d63d37feb8460bbd319459b180f8661d01d087a929413cfa4fd94e355137fbb54413837e47c4e114e82337261a5bbfe20637b6b08dc4974ef1fbefcaac5a4f463021b810ddf7c9a2ddecb119e82602dc14135a3787ed8ab40aedca74755d3518b35dc38ebe85dd13b5500bae3bd5e2f25b6dfcf8c9265ddd0473bf4f69d3d40f2409462d35a7be7902029bd8f7c2ea1d879b07eda52638e93722cece9658e1acd6768d78d00b214349555853511762919854b4991fa110a08b6e6b9e6d93484f143&quot;);
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, {name: &quot;rsa-oaep&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;unwrapKey&quot;]).then(function(unwrappingKey) {
+    return crypto.subtle.unwrapKey(&quot;jwk&quot;, wrappedJwkKey, unwrappingKey, &quot;rsa-oaep&quot;, &quot;AES-CBC&quot;, extractable, [&quot;encrypt&quot;, &quot;decrypt&quot;]);
+}).then(function(cryptoKey) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, cryptoKey);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe(&quot;unwrappedKey.kty&quot;, &quot;'oct'&quot;);
+    shouldBe(&quot;Base64URL.parse(unwrappedKey.k)&quot;, &quot;rawKey&quot;);
+    shouldBe(&quot;unwrappedKey.alg&quot;, &quot;'A128CBC'&quot;);
+    shouldBe(&quot;unwrappedKey.key_ops&quot;, &quot;['decrypt', 'encrypt']&quot;);
+    shouldBe(&quot;unwrappedKey.ext&quot;, &quot;true&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtlersaoaepimportkeyunwrapkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+[Worker] Test unwrapping a JWK oct key with RSA-OAEP using an imported key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/rsa-oaep-import-key-unwrap-key.js
+PASS [Worker] unwrappedKey.kty is 'oct'
+PASS [Worker] Base64URL.parse(unwrappedKey.k) is rawKey
+PASS [Worker] unwrappedKey.alg is 'A128CBC'
+PASS [Worker] unwrappedKey.key_ops is ['decrypt', 'encrypt']
+PASS [Worker] unwrappedKey.ext is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtlersaoaepimportkeyunwrapkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html (0 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        worker = startWorker('resources/rsa-oaep-import-key-unwrap-key.js');
+    &lt;/script&gt;
+    &lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -1,5 +1,15 @@
</span><span class="cx"> 2016-12-01  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Update SubtleCrypto::unwrapKey to match the latest spec
+        https://bugs.webkit.org/show_bug.cgi?id=164747
+        &lt;rdar://problem/29258198&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * WebCryptoAPI/idlharness-expected.txt:
+
+2016-12-01  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
</ins><span class="cx">         SubtleCrypto::deriveBits always return NOT_SUPPORTED_ERR for now
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=164745
</span><span class="cx">         &lt;rdar://problem/29258118&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cWebCryptoAPIidlharnessexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -65,6 +65,6 @@
</span><span class="cx"> PASS SubtleCrypto interface: calling exportKey(KeyFormat,CryptoKey) on crypto.subtle with too few arguments must throw TypeError 
</span><span class="cx"> PASS SubtleCrypto interface: crypto.subtle must inherit property &quot;wrapKey&quot; with the proper type (10) 
</span><span class="cx"> PASS SubtleCrypto interface: calling wrapKey(KeyFormat,CryptoKey,CryptoKey,AlgorithmIdentifier) on crypto.subtle with too few arguments must throw TypeError 
</span><del>-FAIL SubtleCrypto interface: crypto.subtle must inherit property &quot;unwrapKey&quot; with the proper type (11) assert_inherits: property &quot;unwrapKey&quot; not found in prototype chain
-FAIL SubtleCrypto interface: calling unwrapKey(KeyFormat,BufferSource,CryptoKey,AlgorithmIdentifier,AlgorithmIdentifier,boolean,[object Object]) on crypto.subtle with too few arguments must throw TypeError assert_inherits: property &quot;unwrapKey&quot; not found in prototype chain
</del><ins>+PASS SubtleCrypto interface: crypto.subtle must inherit property &quot;unwrapKey&quot; with the proper type (11) 
+PASS SubtleCrypto interface: calling unwrapKey(KeyFormat,BufferSource,CryptoKey,AlgorithmIdentifier,AlgorithmIdentifier,boolean,[object Object]) on crypto.subtle with too few arguments must throw TypeError 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/ChangeLog        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2016-12-01  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        Update SubtleCrypto::unwrapKey to match the latest spec
+        https://bugs.webkit.org/show_bug.cgi?id=164747
+        &lt;rdar://problem/29258198&gt;
+
+        Reviewed by Brent Fulgham.
+
+        This patch does following few things:
+        1. It updates the SubtleCrypto::unwrapKey method to match the latest spec:
+           https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey.
+           It also refers to the latest Editor's Draft to a certain degree:
+           https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-unwrapKey.
+        2. It implements unwrapKey operations of the following algorithms: AES-KW.
+
+        Tests: crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html
+               crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html
+               crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html
+               crypto/subtle/aes-kw-import-key-unwrap-raw-key.html
+               crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html
+               crypto/subtle/unwrapKey-malformed-parameters.html
+               crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html
+               crypto/workers/subtle/aes-kw-import-key-unwrap-key.html
+               crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html
+
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::normalizeCryptoAlgorithmParameters):
+        (WebCore::jsSubtleCryptoFunctionWrapKeyPromise):
+        Add some comments.
+        (WebCore::jsSubtleCryptoFunctionUnwrapKeyPromise):
+        (WebCore::JSSubtleCrypto::unwrapKey):
+        * crypto/CryptoAlgorithm.cpp:
+        (WebCore::CryptoAlgorithm::unwrapKey):
+        * crypto/CryptoAlgorithm.h:
+        * crypto/SubtleCrypto.idl:
+        * crypto/algorithms/CryptoAlgorithmAES_KW.cpp:
+        (WebCore::CryptoAlgorithmAES_KW::unwrapKey):
+        * crypto/algorithms/CryptoAlgorithmAES_KW.h:
+        * crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp:
+        (WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey):
+        * crypto/mac/CryptoAlgorithmAES_KWMac.cpp:
+        (WebCore::unwrapKeyAES_KW):
+        (WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey):
+        (WebCore::CryptoAlgorithmAES_KW::platformDecrypt):
+
</ins><span class="cx"> 2016-12-01  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Parser] Fix font-variant parsing
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSSubtleCryptoCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &quot;JSCryptoKey.h&quot;
</span><span class="cx"> #include &quot;JSCryptoKeyPair.h&quot;
</span><span class="cx"> #include &quot;JSDOMPromise.h&quot;
</span><ins>+#include &quot;JSDOMWrapper.h&quot;
</ins><span class="cx"> #include &quot;JSHmacKeyParams.h&quot;
</span><span class="cx"> #include &quot;JSJsonWebKey.h&quot;
</span><span class="cx"> #include &quot;JSRsaHashedImportParams.h&quot;
</span><span class="lines">@@ -63,6 +64,7 @@
</span><span class="cx">     GenerateKey,
</span><span class="cx">     ImportKey,
</span><span class="cx">     WrapKey,
</span><ins>+    UnwrapKey
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static std::unique_ptr&lt;CryptoAlgorithmParameters&gt; normalizeCryptoAlgorithmParameters(ExecState&amp;, JSValue, Operations);
</span><span class="lines">@@ -232,6 +234,7 @@
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         case Operations::WrapKey:
</span><ins>+        case Operations::UnwrapKey:
</ins><span class="cx">             switch (*identifier) {
</span><span class="cx">             case CryptoAlgorithmIdentifier::AES_KW:
</span><span class="cx">                 result = std::make_unique&lt;CryptoAlgorithmParameters&gt;(params);
</span><span class="lines">@@ -953,6 +956,7 @@
</span><span class="cx">             wrapAlgorithm-&gt;wrapKey(wrappingKey.releaseNonNull(), WTFMove(bytes), WTFMove(callback), WTFMove(exceptionCallback));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><ins>+        // The following operation should be performed asynchronously.
</ins><span class="cx">         wrapAlgorithm-&gt;encrypt(WTFMove(wrapParams), wrappingKey.releaseNonNull(), WTFMove(bytes), WTFMove(callback), WTFMove(exceptionCallback), *context, workQueue);
</span><span class="cx">     };
</span><span class="cx">     auto exceptionCallback = [capturedPromise = WTFMove(promise)](ExceptionCode ec) mutable {
</span><span class="lines">@@ -959,9 +963,120 @@
</span><span class="cx">         rejectWithException(WTFMove(capturedPromise), ec);
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    // The following operation should be performed synchronously.
</ins><span class="cx">     exportAlgorithm-&gt;exportKey(format, key.releaseNonNull(), WTFMove(callback), WTFMove(exceptionCallback));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void jsSubtleCryptoFunctionUnwrapKeyPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
+{
+    VM&amp; vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (UNLIKELY(state.argumentCount() &lt; 7)) {
+        promise-&gt;reject&lt;JSValue&gt;(createNotEnoughArgumentsError(&amp;state));
+        return;
+    }
+
+    auto format = convertEnumeration&lt;SubtleCrypto::KeyFormat&gt;(state, state.uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto wrappedKey = toVector(state, state.uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto unwrappingKey = toCryptoKey(state, state.uncheckedArgument(2));
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto catchScope = DECLARE_CATCH_SCOPE(vm);
+    bool isDecryption = false;
+    auto unwrapParams = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(3), Operations::UnwrapKey);
+    if (catchScope.exception()) {
+        catchScope.clearException();
+        unwrapParams = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(3), Operations::Decrypt);
+        RETURN_IF_EXCEPTION(scope, void());
+        isDecryption = true;
+    }
+
+    auto unwrappedKeyAlgorithm = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(4), Operations::ImportKey);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto extractable = state.uncheckedArgument(5).toBoolean(&amp;state);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto keyUsages = cryptoKeyUsageBitmapFromJSValue(state, state.uncheckedArgument(6));
+    RETURN_IF_EXCEPTION(scope, void());
+
+    if (unwrapParams-&gt;identifier != unwrappingKey-&gt;algorithmIdentifier()) {
+        promise-&gt;reject(INVALID_ACCESS_ERR, ASCIILiteral(&quot;Unwrapping CryptoKey doesn't match unwrap AlgorithmIdentifier&quot;));
+        return;
+    }
+
+    if (!unwrappingKey-&gt;allows(CryptoKeyUsageUnwrapKey)) {
+        promise-&gt;reject(INVALID_ACCESS_ERR, ASCIILiteral(&quot;Unwrapping CryptoKey doesn't support unwrapKey operation&quot;));
+        return;
+    }
+
+    auto importAlgorithm = createAlgorithm(state, unwrappedKeyAlgorithm-&gt;identifier);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto unwrapAlgorithm = createAlgorithm(state, unwrappingKey-&gt;algorithmIdentifier());
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto callback = [promise = promise.copyRef(), format, importAlgorithm, unwrappedKeyAlgorithm = WTFMove(unwrappedKeyAlgorithm), extractable, keyUsages](const Vector&lt;uint8_t&gt;&amp; bytes) mutable {
+        ExecState&amp; state = *(promise-&gt;globalObject()-&gt;globalExec());
+        VM&amp; vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        KeyData keyData;
+        switch (format) {
+        case SubtleCrypto::KeyFormat::Spki:
+        case SubtleCrypto::KeyFormat::Pkcs8:
+        case SubtleCrypto::KeyFormat::Raw:
+            keyData = bytes;
+            break;
+        case SubtleCrypto::KeyFormat::Jwk: {
+            String jwkString(reinterpret_cast_ptr&lt;const char*&gt;(bytes.data()), bytes.size());
+            JSC::JSLockHolder locker(vm);
+            auto jwk = JSONParse(&amp;state, jwkString);
+            if (!jwk) {
+                promise-&gt;reject(DataError, ASCIILiteral(&quot;WrappedKey cannot be converted to a JSON object&quot;));
+                return;
+            }
+            keyData = toKeyData(state, format, jwk);
+            RETURN_IF_EXCEPTION(scope, void());
+        }
+        }
+
+        auto callback = [promise = promise.copyRef()](CryptoKey&amp; key) mutable {
+            if ((key.type() == CryptoKeyType::Private || key.type() == CryptoKeyType::Secret) &amp;&amp; !key.usagesBitmap()) {
+                rejectWithException(WTFMove(promise), SYNTAX_ERR);
+                return;
+            }
+            promise-&gt;resolve(key);
+        };
+        auto exceptionCallback = [promise = WTFMove(promise)](ExceptionCode ec) mutable {
+            rejectWithException(WTFMove(promise), ec);
+        };
+
+        // The following operation should be performed synchronously.
+        importAlgorithm-&gt;importKey(format, WTFMove(keyData), WTFMove(unwrappedKeyAlgorithm), extractable, keyUsages, WTFMove(callback), WTFMove(exceptionCallback));
+    };
+    auto exceptionCallback = [capturedPromise = WTFMove(promise)](ExceptionCode ec) mutable {
+        rejectWithException(WTFMove(capturedPromise), ec);
+    };
+
+    if (!isDecryption) {
+        // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
+        // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey
+        // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
+        unwrapAlgorithm-&gt;unwrapKey(unwrappingKey.releaseNonNull(), WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback));
+        return;
+    }
+    auto subtle = jsDynamicDowncast&lt;JSSubtleCrypto*&gt;(state.thisValue());
+    ASSERT(subtle);
+    // The following operation should be performed asynchronously.
+    unwrapAlgorithm-&gt;decrypt(WTFMove(unwrapParams), unwrappingKey.releaseNonNull(), WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&amp;state), subtle-&gt;wrapped().workQueue());
+}
+
</ins><span class="cx"> JSValue JSSubtleCrypto::encrypt(ExecState&amp; state)
</span><span class="cx"> {
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionEncryptPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span><span class="lines">@@ -1017,6 +1132,11 @@
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionWrapKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSValue JSSubtleCrypto::unwrapKey(ExecState&amp; state)
+{
+    return callPromiseFunction&lt;jsSubtleCryptoFunctionUnwrapKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCryptoAlgorithmcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -77,6 +77,11 @@
</span><span class="cx">     exceptionCallback(NOT_SUPPORTED_ERR);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithm::unwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp; exceptionCallback)
+{
+    exceptionCallback(NOT_SUPPORTED_ERR);
+}
+
</ins><span class="cx"> ExceptionOr&lt;void&gt; CryptoAlgorithm::encrypt(const CryptoAlgorithmParametersDeprecated&amp;, const CryptoKey&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp;)
</span><span class="cx"> {
</span><span class="cx">     return Exception { NOT_SUPPORTED_ERR };
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCryptoAlgorithmh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.h (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CryptoAlgorithm.h        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.h        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     virtual void importKey(SubtleCrypto::KeyFormat, KeyData&amp;&amp;, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, bool extractable, CryptoKeyUsageBitmap, KeyCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span><span class="cx">     virtual void exportKey(SubtleCrypto::KeyFormat, Ref&lt;CryptoKey&gt;&amp;&amp;, KeyDataCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span><span class="cx">     virtual void wrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span><ins>+    virtual void unwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // The following will be deprecated.
</span><span class="cx">     virtual ExceptionOr&lt;void&gt; encrypt(const CryptoAlgorithmParametersDeprecated&amp;, const CryptoKey&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp; failureCallback);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoSubtleCryptoidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/SubtleCrypto.idl (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/SubtleCrypto.idl        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/SubtleCrypto.idl        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -43,4 +43,5 @@
</span><span class="cx">     [Custom] Promise&lt;CryptoKey&gt; importKey(KeyFormat format, (BufferSource or JsonWebKey) keyData, AlgorithmIdentifier algorithm, boolen extractable, sequence&lt;CryptoKeyUsage&gt; keyUsages);
</span><span class="cx">     [Custom] Promise&lt;any&gt; exportKey(KeyFormat format, CryptoKey key);
</span><span class="cx">     [Custom] Promise&lt;any&gt; wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm);
</span><ins>+    [Custom] Promise&lt;CryptoKey&gt; unwrapKey(KeyFormat format, BufferSource wrappedKey, CryptoKey unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier unwrappedKeyAlgorithm, boolean extractable, sequence&lt;KeyUsage&gt; keyUsages);
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmAES_KWcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -167,6 +167,11 @@
</span><span class="cx">     platformWrapKey(WTFMove(key), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithmAES_KW::unwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp; key, Vector&lt;uint8_t&gt;&amp;&amp; data, VectorCallback&amp;&amp; callback, ExceptionCallback&amp;&amp; exceptionCallback)
+{
+    platformUnwrapKey(WTFMove(key), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback));
+}
+
</ins><span class="cx"> ExceptionOr&lt;void&gt; CryptoAlgorithmAES_KW::encryptForWrapKey(const CryptoAlgorithmParametersDeprecated&amp;, const CryptoKey&amp; key, const CryptoOperationData&amp; data, VectorCallback&amp;&amp; callback, VoidCallback&amp;&amp; failureCallback)
</span><span class="cx"> {
</span><span class="cx">     if (!keyAlgorithmMatches(key))
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmAES_KWh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">     void importKey(SubtleCrypto::KeyFormat, KeyData&amp;&amp;, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, bool extractable, CryptoKeyUsageBitmap, KeyCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</span><span class="cx">     void exportKey(SubtleCrypto::KeyFormat, Ref&lt;CryptoKey&gt;&amp;&amp;, KeyDataCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</span><span class="cx">     void wrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</span><ins>+    void unwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</ins><span class="cx"> 
</span><span class="cx">     ExceptionOr&lt;void&gt; encryptForWrapKey(const CryptoAlgorithmParametersDeprecated&amp;, const CryptoKey&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp; failureCallback) final;
</span><span class="cx">     ExceptionOr&lt;void&gt; decryptForUnwrapKey(const CryptoAlgorithmParametersDeprecated&amp;, const CryptoKey&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp; failureCallback) final;
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool keyAlgorithmMatches(const CryptoKey&amp;) const;
</span><span class="cx">     void platformWrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span><ins>+    void platformUnwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</ins><span class="cx">     ExceptionOr&lt;void&gt; platformEncrypt(const CryptoKeyAES&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp; failureCallback);
</span><span class="cx">     ExceptionOr&lt;void&gt; platformDecrypt(const CryptoKeyAES&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp; failureCallback);
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorecryptognutlsCryptoAlgorithmAES_KWGnuTLScpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -38,6 +38,11 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithmAES_KW::platformUnwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;)
+{
+    notImplemented();
+}
+
</ins><span class="cx"> ExceptionOr&lt;void&gt; CryptoAlgorithmAES_KW::platformEncrypt(const CryptoKeyAES&amp;, const CryptoOperationData&amp;, VectorCallback&amp;&amp;, VoidCallback&amp;&amp;)
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span></span></pre></div>
<a id="trunkSourceWebCorecryptomacCryptoAlgorithmAES_KWMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp (209199 => 209200)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp        2016-12-01 21:41:28 UTC (rev 209199)
+++ trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp        2016-12-01 21:45:31 UTC (rev 209200)
</span><span class="lines">@@ -47,6 +47,23 @@
</span><span class="cx">     return WTFMove(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// FIXME: We should change data to Vector&lt;uint8_t&gt; type once WebKitSubtleCrypto is deprecated.
+// https://bugs.webkit.org/show_bug.cgi?id=164939
+static ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; unwrapKeyAES_KW(const Vector&lt;uint8_t&gt;&amp; key, const uint8_t* data, size_t dataLength)
+{
+    Vector&lt;uint8_t&gt; result(CCSymmetricUnwrappedSize(kCCWRAPAES, dataLength));
+    size_t resultSize = result.size();
+
+    if (resultSize % 8)
+        return Exception { OperationError };
+
+    if (CCSymmetricKeyUnwrap(kCCWRAPAES, CCrfc3394_iv, CCrfc3394_ivLen, key.data(), key.size(), data, dataLength, result.data(), &amp;resultSize))
+        return Exception { OperationError };
+
+    result.shrink(resultSize);
+    return WTFMove(result);
+}
+
</ins><span class="cx"> void CryptoAlgorithmAES_KW::platformWrapKey(Ref&lt;CryptoKey&gt;&amp;&amp; key, Vector&lt;uint8_t&gt;&amp;&amp; data, VectorCallback&amp;&amp; callback, ExceptionCallback&amp;&amp; exceptionCallback)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; aesKey = downcast&lt;CryptoKeyAES&gt;(key.get());
</span><span class="lines">@@ -58,6 +75,17 @@
</span><span class="cx">     callback(result.releaseReturnValue());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithmAES_KW::platformUnwrapKey(Ref&lt;CryptoKey&gt;&amp;&amp; key, Vector&lt;uint8_t&gt;&amp;&amp; data, VectorCallback&amp;&amp; callback, ExceptionCallback&amp;&amp; exceptionCallback)
+{
+    auto&amp; aesKey = downcast&lt;CryptoKeyAES&gt;(key.get());
+    auto result = unwrapKeyAES_KW(aesKey.key(), data.data(), data.size());
+    if (result.hasException()) {
+        exceptionCallback(result.releaseException().code());
+        return;
+    }
+    callback(result.releaseReturnValue());
+}
+
</ins><span class="cx"> ExceptionOr&lt;void&gt; CryptoAlgorithmAES_KW::platformEncrypt(const CryptoKeyAES&amp; key, const CryptoOperationData&amp; data, VectorCallback&amp;&amp; callback, VoidCallback&amp;&amp; failureCallback)
</span><span class="cx"> {
</span><span class="cx">     if (data.second % 8) {
</span><span class="lines">@@ -78,24 +106,14 @@
</span><span class="cx"> 
</span><span class="cx"> ExceptionOr&lt;void&gt; CryptoAlgorithmAES_KW::platformDecrypt(const CryptoKeyAES&amp; key, const CryptoOperationData&amp; data, VectorCallback&amp;&amp; callback, VoidCallback&amp;&amp; failureCallback)
</span><span class="cx"> {
</span><del>-    Vector&lt;uint8_t&gt; result(CCSymmetricUnwrappedSize(kCCWRAPAES, data.second));
-    size_t resultSize = result.size();
-
-    if (resultSize % 8) {
</del><ins>+    auto result = unwrapKeyAES_KW(key.key(), data.first, data.second);
+    if (result.hasException()) {
</ins><span class="cx">         failureCallback();
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><ins>+    callback(result.releaseReturnValue());
+    return { };}
</ins><span class="cx"> 
</span><del>-    int status = CCSymmetricKeyUnwrap(kCCWRAPAES, CCrfc3394_iv, CCrfc3394_ivLen, key.key().data(), key.key().size(), data.first, data.second, result.data(), &amp;resultSize);
-    if (status) {
-        failureCallback();
-        return { };
-    }
-    result.shrink(resultSize);
-    callback(result);
-    return { };
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SUBTLE_CRYPTO)
</span></span></pre>
</div>
</div>

</body>
</html>