<!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>[214074] 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/214074">214074</a></dd>
<dt>Author</dt> <dd>jiewen_tan@apple.com</dd>
<dt>Date</dt> <dd>2017-03-16 15:32:20 -0700 (Thu, 16 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
https://bugs.webkit.org/show_bug.cgi?id=169318
&lt;rdar://problem/31081956&gt;

Reviewed by Brent Fulgham.

LayoutTests/imported/w3c:

* web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt:
* web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt:

Source/WebCore:

This patch adds SPKI/PKCS8 support for Elliptic Curve cryptos. We can now import/export
SPKI/PKCS8 Elliptic Curve keys after this change. Few things to note: 1) This patch
implements a loose DER encoder/decoder for hacking the underlying CommonCrypto library.
2) It only permits id-ecPublicKey as the AlgorithmIdentifier following OpenSSL/Chrome(BoringSSL).
3) It follows OpenSSL/Chrome(BoringSSL) to replace ECParameters in ECPrivateKey with custom
tags. Hence, we should fully comply with OpenSSL/Chrome(BoringSSL).

Tests: crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html
       crypto/subtle/ec-import-jwk-key-export-spki-key.html
       crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html
       crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html
       crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html
       crypto/subtle/ec-import-raw-key-export-spki-key.html
       crypto/subtle/ec-import-spki-key-export-jwk-key.html
       crypto/subtle/ec-import-spki-key-export-raw-key.html
       crypto/subtle/ec-import-spki-key-export-spki-key-p256.html
       crypto/subtle/ec-import-spki-key-export-spki-key-p384.html
       crypto/subtle/ecdh-generate-export-key-spki-p256.html
       crypto/subtle/ecdh-generate-export-key-spki-p384.html
       crypto/subtle/ecdh-generate-export-pkcs8-p256.html
       crypto/subtle/ecdh-generate-export-pkcs8-p384.html
       crypto/subtle/ecdh-import-pkcs8-key-p256.html
       crypto/subtle/ecdh-import-pkcs8-key-p384.html
       crypto/subtle/ecdh-import-spki-key-p256.html
       crypto/subtle/ecdh-import-spki-key-p384.html
       crypto/workers/subtle/ec-generate-export-pkcs8-key.html
       crypto/workers/subtle/ec-generate-export-spki-key.html
       crypto/workers/subtle/ec-import-pkcs8-key.html
       crypto/workers/subtle/ec-import-spki-key.html

* WebCore.xcodeproj/project.pbxproj:
* crypto/algorithms/CryptoAlgorithmECDH.cpp:
(WebCore::CryptoAlgorithmECDH::importKey):
(WebCore::CryptoAlgorithmECDH::exportKey):
* crypto/gnutls/CryptoKeyECGnuTLS.cpp:
(WebCore::CryptoKeyEC::platformExportRaw):
(WebCore::CryptoKeyEC::platformImportSpki):
(WebCore::CryptoKeyEC::platformExportSpki):
(WebCore::CryptoKeyEC::platformImportPkcs8):
(WebCore::CryptoKeyEC::platformExportPkcs8):
(WebCore::CryptoKeyEC::exportRaw): Deleted.
* crypto/keys/CryptoKeyEC.cpp:
(WebCore::CryptoKeyEC::importSpki):
(WebCore::CryptoKeyEC::importPkcs8):
(WebCore::CryptoKeyEC::exportRaw):
(WebCore::CryptoKeyEC::exportSpki):
(WebCore::CryptoKeyEC::exportPkcs8):
* crypto/keys/CryptoKeyEC.h:
* crypto/mac/CommonCryptoDERUtilities.h: Added.
(WebCore::bytesUsedToEncodedLength):
(WebCore::extraBytesNeededForEncodedLength):
(WebCore::addEncodedASN1Length):
(WebCore::bytesNeededForEncodedLength):
* crypto/mac/CryptoKeyECMac.cpp:
(WebCore::compareBytes):
(WebCore::CryptoKeyEC::platformExportRaw):
(WebCore::CryptoKeyEC::platformImportJWKPrivate):
(WebCore::getOID):
(WebCore::CryptoKeyEC::platformImportSpki):
(WebCore::CryptoKeyEC::platformExportSpki):
(WebCore::CryptoKeyEC::platformImportPkcs8):
(WebCore::CryptoKeyEC::platformExportPkcs8):
(WebCore::CryptoKeyEC::exportRaw): Deleted.
Enlarge the robust of exportRaw.
* crypto/mac/CryptoKeyRSAMac.cpp:
(WebCore::CryptoKeyRSA::exportSpki):
(WebCore::CryptoKeyRSA::exportPkcs8):
Enhance the implementation.
(WebCore::bytesUsedToEncodedLength): Deleted.
(WebCore::bytesNeededForEncodedLength): Deleted.
(WebCore::addEncodedASN1Length): Deleted.
Moved to CommonCryptoDERUtilities.h.

LayoutTests:

* crypto/subtle/ec-export-key-malformed-parameters-expected.txt:
* crypto/subtle/ec-export-key-malformed-parameters.html:
* crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt:
* crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html:
* crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt: Added.
* crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html: Added.
* crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt: Added.
* crypto/subtle/ec-import-jwk-key-export-spki-key.html: Added.
* crypto/subtle/ec-import-key-malformed-parameters-expected.txt:
* crypto/subtle/ec-import-key-malformed-parameters.html:
* crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt: Added.
* crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html: Added.
* crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt: Added.
* crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html: Added.
* crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt: Added.
* crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html: Added.
* crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt: Added.
* crypto/subtle/ec-import-raw-key-export-spki-key.html: Added.
* crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt: Added.
* crypto/subtle/ec-import-spki-key-export-jwk-key.html: Added.
* crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt: Added.
* crypto/subtle/ec-import-spki-key-export-raw-key.html: Added.
* crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt: Added.
* crypto/subtle/ec-import-spki-key-export-spki-key-p256.html: Added.
* crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt: Added.
* crypto/subtle/ec-import-spki-key-export-spki-key-p384.html: Added.
* crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt: Added.
* crypto/subtle/ecdh-generate-export-key-spki-p256.html: Added.
* crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt: Added.
* crypto/subtle/ecdh-generate-export-key-spki-p384.html: Added.
* crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt: Added.
* crypto/subtle/ecdh-generate-export-pkcs8-p256.html: Added.
* crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt: Added.
* crypto/subtle/ecdh-generate-export-pkcs8-p384.html: Added.
* crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt: Added.
* crypto/subtle/ecdh-import-pkcs8-key-p256.html: Added.
* crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt: Added.
* crypto/subtle/ecdh-import-pkcs8-key-p384.html: Added.
* crypto/subtle/ecdh-import-spki-key-p256-expected.txt: Added.
* crypto/subtle/ecdh-import-spki-key-p256.html: Added.
* crypto/subtle/ecdh-import-spki-key-p384-expected.txt: Added.
* crypto/subtle/ecdh-import-spki-key-p384.html: Added.
* crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt: Added.
* crypto/workers/subtle/ec-generate-export-pkcs8-key.html: Added.
* crypto/workers/subtle/ec-generate-export-spki-key-expected.txt: Added.
* crypto/workers/subtle/ec-generate-export-spki-key.html: Added.
* crypto/workers/subtle/ec-import-pkcs8-key-expected.txt: Added.
* crypto/workers/subtle/ec-import-pkcs8-key.html: Added.
* crypto/workers/subtle/ec-import-spki-key-expected.txt: Added.
* crypto/workers/subtle/ec-import-spki-key.html: Added.
* crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js: Added.
* crypto/workers/subtle/resources/ec-generate-export-spki-key.js: Added.
* crypto/workers/subtle/resources/ec-import-pkcs8-key.js: Added.
* crypto/workers/subtle/resources/ec-import-spki-key.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecexportkeymalformedparametersexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml">trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivateexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivatehtml">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportkeymalformedparametersexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportkeymalformedparametershtml">trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsWebCryptoAPIimport_exportec_importKeyworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsWebCryptoAPIimport_exporttest_ec_importKeyexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHcpp">trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptognutlsCryptoKeyECGnuTLScpp">trunk/Source/WebCore/crypto/gnutls/CryptoKeyECGnuTLS.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptokeysCryptoKeyECcpp">trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptokeysCryptoKeyECh">trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h</a></li>
<li><a href="#trunkSourceWebCorecryptomacCryptoKeyECMaccpp">trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptomacCryptoKeyRSAMaccpp">trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportpkcs8keyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportpkcs8keyhtml">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportspkikeyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportjwkkeyexportspkikeyhtml">trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportjwkkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportjwkkeyhtml">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp256expectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp256html">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp384expectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp384html">trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportrawkeyexportspkikeyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportrawkeyexportspkikeyhtml">trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportjwkkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportjwkkeyhtml">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportrawkeyexpectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportrawkeyhtml">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp256expectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp256html">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp384expectedtxt">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp384html">trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip256expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip256html">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip384expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip384html">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p256expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p256html">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p384expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p384html">trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportpkcs8keyp256expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportpkcs8keyp256html">trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportpkcs8keyp384expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportpkcs8keyp384html">trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportspkikeyp256expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportspkikeyp256html">trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportspkikeyp384expectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportspkikeyp384html">trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecgenerateexportpkcs8keyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecgenerateexportpkcs8keyhtml">trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecgenerateexportspkikeyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecgenerateexportspkikeyhtml">trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecimportpkcs8keyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecimportpkcs8keyhtml">trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecimportspkikeyexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecimportspkikeyhtml">trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesecgenerateexportpkcs8keyjs">trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesecgenerateexportspkikeyjs">trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-spki-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesecimportpkcs8keyjs">trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-pkcs8-key.js</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesecimportspkikeyjs">trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-spki-key.js</a></li>
<li><a href="#trunkSourceWebCorecryptomacCommonCryptoDERUtilitiesh">trunk/Source/WebCore/crypto/mac/CommonCryptoDERUtilities.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/ChangeLog        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -1,3 +1,66 @@
</span><ins>+2017-03-16  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
+        https://bugs.webkit.org/show_bug.cgi?id=169318
+        &lt;rdar://problem/31081956&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * crypto/subtle/ec-export-key-malformed-parameters-expected.txt:
+        * crypto/subtle/ec-export-key-malformed-parameters.html:
+        * crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt:
+        * crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html:
+        * crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt: Added.
+        * crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html: Added.
+        * crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt: Added.
+        * crypto/subtle/ec-import-jwk-key-export-spki-key.html: Added.
+        * crypto/subtle/ec-import-key-malformed-parameters-expected.txt:
+        * crypto/subtle/ec-import-key-malformed-parameters.html:
+        * crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt: Added.
+        * crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html: Added.
+        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt: Added.
+        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html: Added.
+        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt: Added.
+        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html: Added.
+        * crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt: Added.
+        * crypto/subtle/ec-import-raw-key-export-spki-key.html: Added.
+        * crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt: Added.
+        * crypto/subtle/ec-import-spki-key-export-jwk-key.html: Added.
+        * crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt: Added.
+        * crypto/subtle/ec-import-spki-key-export-raw-key.html: Added.
+        * crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt: Added.
+        * crypto/subtle/ec-import-spki-key-export-spki-key-p256.html: Added.
+        * crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt: Added.
+        * crypto/subtle/ec-import-spki-key-export-spki-key-p384.html: Added.
+        * crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt: Added.
+        * crypto/subtle/ecdh-generate-export-key-spki-p256.html: Added.
+        * crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt: Added.
+        * crypto/subtle/ecdh-generate-export-key-spki-p384.html: Added.
+        * crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt: Added.
+        * crypto/subtle/ecdh-generate-export-pkcs8-p256.html: Added.
+        * crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt: Added.
+        * crypto/subtle/ecdh-generate-export-pkcs8-p384.html: Added.
+        * crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt: Added.
+        * crypto/subtle/ecdh-import-pkcs8-key-p256.html: Added.
+        * crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt: Added.
+        * crypto/subtle/ecdh-import-pkcs8-key-p384.html: Added.
+        * crypto/subtle/ecdh-import-spki-key-p256-expected.txt: Added.
+        * crypto/subtle/ecdh-import-spki-key-p256.html: Added.
+        * crypto/subtle/ecdh-import-spki-key-p384-expected.txt: Added.
+        * crypto/subtle/ecdh-import-spki-key-p384.html: Added.
+        * crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt: Added.
+        * crypto/workers/subtle/ec-generate-export-pkcs8-key.html: Added.
+        * crypto/workers/subtle/ec-generate-export-spki-key-expected.txt: Added.
+        * crypto/workers/subtle/ec-generate-export-spki-key.html: Added.
+        * crypto/workers/subtle/ec-import-pkcs8-key-expected.txt: Added.
+        * crypto/workers/subtle/ec-import-pkcs8-key.html: Added.
+        * crypto/workers/subtle/ec-import-spki-key-expected.txt: Added.
+        * crypto/workers/subtle/ec-import-spki-key.html: Added.
+        * crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js: Added.
+        * crypto/workers/subtle/resources/ec-generate-export-spki-key.js: Added.
+        * crypto/workers/subtle/resources/ec-import-pkcs8-key.js: Added.
+        * crypto/workers/subtle/resources/ec-import-spki-key.js: Added.
+
</ins><span class="cx"> 2017-03-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simple line layout: Extend webkit-hyphenate-limit-lines to cover subsequent words.
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecexportkeymalformedparametersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters-expected.txt (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters-expected.txt        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -4,6 +4,8 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> PASS crypto.subtle.exportKey(&quot;raw&quot;, privateKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
</span><ins>+PASS crypto.subtle.exportKey(&quot;spki&quot;, privateKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
+PASS crypto.subtle.exportKey(&quot;pkcs8&quot;, publicKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -21,9 +21,16 @@
</span><span class="cx"> 
</span><span class="cx"> crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
</span><span class="cx">     privateKey = result.privateKey;
</span><ins>+    publicKey = result.publicKey;
</ins><span class="cx"> 
</span><span class="cx">     // Wrong key and format.
</span><span class="cx">     return shouldReject('crypto.subtle.exportKey(&quot;raw&quot;, privateKey)');
</span><ins>+}).then(function() {
+    // Wrong key and format.
+    return shouldReject('crypto.subtle.exportKey(&quot;spki&quot;, privateKey)');
+}).then(function() {
+    // Wrong key and format.
+    return shouldReject('crypto.subtle.exportKey(&quot;pkcs8&quot;, publicKey)');
</ins><span class="cx"> }).then(finishJSTest, finishJSTest);
</span><span class="cx"> 
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivateexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -4,13 +4,13 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> Importing a key...
</span><del>-PASS publicKey.kty is jwkKey.kty
-PASS publicKey.crv is jwkKey.crv
-PASS publicKey.x is jwkKey.x
-PASS publicKey.y is jwkKey.y
-PASS publicKey.d is jwkKey.d
-PASS publicKey.key_ops is jwkKey.key_ops
-PASS publicKey.ext is jwkKey.ext
</del><ins>+PASS privateKey.kty is jwkKey.kty
+PASS privateKey.crv is jwkKey.crv
+PASS privateKey.x is jwkKey.x
+PASS privateKey.y is jwkKey.y
+PASS privateKey.d is jwkKey.d
+PASS privateKey.key_ops is jwkKey.key_ops
+PASS privateKey.ext is jwkKey.ext
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivatehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -28,15 +28,15 @@
</span><span class="cx"> crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
</span><span class="cx">     return crypto.subtle.exportKey(&quot;jwk&quot;, result);
</span><span class="cx"> }).then(function(result) {
</span><del>-    publicKey = result;
</del><ins>+    privateKey = result;
</ins><span class="cx"> 
</span><del>-    shouldBe(&quot;publicKey.kty&quot;, &quot;jwkKey.kty&quot;);
-    shouldBe(&quot;publicKey.crv&quot;, &quot;jwkKey.crv&quot;);
-    shouldBe(&quot;publicKey.x&quot;, &quot;jwkKey.x&quot;);
-    shouldBe(&quot;publicKey.y&quot;, &quot;jwkKey.y&quot;);
-    shouldBe(&quot;publicKey.d&quot;, &quot;jwkKey.d&quot;);
-    shouldBe(&quot;publicKey.key_ops&quot;, &quot;jwkKey.key_ops&quot;);
-    shouldBe(&quot;publicKey.ext&quot;, &quot;jwkKey.ext&quot;);
</del><ins>+    shouldBe(&quot;privateKey.kty&quot;, &quot;jwkKey.kty&quot;);
+    shouldBe(&quot;privateKey.crv&quot;, &quot;jwkKey.crv&quot;);
+    shouldBe(&quot;privateKey.x&quot;, &quot;jwkKey.x&quot;);
+    shouldBe(&quot;privateKey.y&quot;, &quot;jwkKey.y&quot;);
+    shouldBe(&quot;privateKey.d&quot;, &quot;jwkKey.d&quot;);
+    shouldBe(&quot;privateKey.key_ops&quot;, &quot;jwkKey.key_ops&quot;);
+    shouldBe(&quot;privateKey.ext&quot;, &quot;jwkKey.ext&quot;);
</ins><span class="cx"> 
</span><span class="cx">     finishJSTest();
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportpkcs8keyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a jwk private ECDH key and then export it in PKCS8 format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(privateKey) is expectedPkcs8KeyHex
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportpkcs8keyhtmlfromrev214073trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivatehtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,43 @@
</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 importing a jwk private ECDH key and then export it in PKCS8 format&quot;);
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: &quot;EC&quot;,
+    ext: true,
+    key_ops: [&quot;deriveBits&quot;, &quot;deriveKey&quot;],
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+var expectedPkcs8KeyHex = &quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420a69c414a8bf737cfc051c8ac02ebe62d5e3213c7bf2ff04b13c6d96fd6755e38a14403420004d454955a2793be2905906d4d3b286450268c6dd421c701fa682bb8133fac46d0f6398d4cba8ce1c8c185d0271dc348f58415dcef0b166a3e11d65693c9ed01a2&quot;;
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, result);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;bytesToHexString(privateKey)&quot;, &quot;expectedPkcs8KeyHex&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 class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportspkikeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a JWK ECDH public key and export it in SPKI format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(publicKey) is expectedSpkiKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportjwkkeyexportspkikeyhtmlfromrev214073trunkLayoutTestscryptosubtleecimportjwkkeyexportjwkkeyprivatehtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,40 @@
</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 importing a JWK ECDH public key and export it in SPKI format&quot;);
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+var expectedSpkiKey = &quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004d454955a2793be2905906d4d3b286450268c6dd421c701fa682bb8133fac46d0f6398d4cba8ce1c8c185d0271dc348f58415dcef0b166a3e11d65693c9ed01a2&quot;;
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;spki&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;bytesToHexString(publicKey)&quot;, &quot;expectedSpkiKey&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="trunkLayoutTestscryptosubtleecimportkeymalformedparametersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters-expected.txt (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters-expected.txt        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -27,6 +27,42 @@
</span><span class="cx"> PASS crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x384, y:y}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
</span><span class="cx"> PASS crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x, y:y384}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
</span><span class="cx"> PASS crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x384, y:y384, d:d}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
</span><ins>+PASS crypto.subtle.importKey(&quot;spki&quot;, spkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key4, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key5, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key6, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key7, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key8, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, spkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, spkiP384Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;spki&quot;, corruptedSpkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;encrypt&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;decrypt&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;sign&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;verify&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;wrapKey&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;unwrapKey&quot;]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key4, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key5, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key6, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key7, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key8, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key9, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key10, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key11, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P384Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P384Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, longPkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey(&quot;pkcs8&quot;, corruptedPkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportkeymalformedparametershtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters.html (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters.html        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -19,6 +19,37 @@
</span><span class="cx"> var d = &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;; // P-256
</span><span class="cx"> var x384 = &quot;1bHwFrsaPRjYq-zFOyLXK8Ugv3EqbVF075ct7ouTl_pwyhjeBu03JHjKTsyVbNWK&quot;;
</span><span class="cx"> var y384 = &quot;1bHwFrsaPRjYq-zFOyLXK8Ugv3EqbVF075ct7ouTl_pwyhjeBu03JHjKTsyVbNWK&quot;;
</span><ins>+var spkiP256Key = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var spkiP384Key = hexStringToUint8Array(&quot;3076301006072a8648ce3d020106052b8104002203620004478f6119747475f94b742654be32ab6ebbdc371afa34fbee6d12c32fe2d586231262b17d13a1f271f19c8008c034d8716b7df0ce1d987990c5b175ecae1aa40f2fb89e4778528e1234e56d69638db135d103fa68448fee2b4f58ecc86d7f4b7a&quot;);
+var truncatedSpkiP256Key1 = hexStringToUint8Array(&quot;30&quot;);
+var truncatedSpkiP256Key2 = hexStringToUint8Array(&quot;305930&quot;);
+var truncatedSpkiP256Key3 = hexStringToUint8Array(&quot;305930130607&quot;);
+var truncatedSpkiP256Key4 = hexStringToUint8Array(&quot;3059301306072b8648ce3d0201&quot;);
+var truncatedSpkiP256Key5 = hexStringToUint8Array(&quot;3059301306072a8648ce3d02010608&quot;);
+var truncatedSpkiP256Key6 = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d030108&quot;);
+var truncatedSpkiP256Key7 = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d030107034200&quot;);
+var truncatedSpkiP256Key8 = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae7&quot;);
+var truncatedSpkiP384Key1 = hexStringToUint8Array(&quot;3076301006072a8648ce3d02010605&quot;);
+var truncatedSpkiP384Key2 = hexStringToUint8Array(&quot;3076301006072a8648ce3d020106052b81040022&quot;);
+var truncatedSpkiP384Key3 = hexStringToUint8Array(&quot;3076301006072a8648ce3d020106052b8104002203620004478f6119747475f94b742654be32ab6ebbdc371afa34fbee6d12c32fe2d586231262b17d13a1f271f19c8008c034d8716b7df0ce1d987990c5b175ecae1aa40f2fb89e4778528e1234e56d69638db135d103fa68448fee2b4f58ecc86d7f4b&quot;);
+var corruptedSpkiP256Key = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420000c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var pkcs8P256Key = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2&quot;);
+var pkcs8P384Key = hexStringToUint8Array(&quot;3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430c38e34a7cd58961c8deda9c9118548724945d3f3b3bd71f03c93247304c1f7d86b8507501e4e05a0fbae76e44bbe8cc2a16403620004cb75013d8ba42edd022e9de8dfe856a2ee3f48ec28a666c4a73cf3d16e09c7d5747e6c5b5795a656e175c71feed01ec5e282b19e6650f6ea31970114f3e1e6e2275dd6811f87e7f7128c48806a9763785ac31bd345436e57eae23a1151355ef2&quot;);
+var truncatedPkcs8P256Key1 = hexStringToUint8Array(&quot;30&quot;);
+var truncatedPkcs8P256Key2 = hexStringToUint8Array(&quot;30818702010030&quot;);
+var truncatedPkcs8P256Key3 = hexStringToUint8Array(&quot;3081870201003013&quot;);
+var truncatedPkcs8P256Key4 = hexStringToUint8Array(&quot;308187020100301306072b8648ce3d0201&quot;);
+var truncatedPkcs8P256Key5 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d0201&quot;);
+var truncatedPkcs8P256Key6 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082b8648ce3d030107&quot;);
+var truncatedPkcs8P256Key7 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d03010704&quot;);
+var truncatedPkcs8P256Key8 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d30&quot;);
+var truncatedPkcs8P256Key9 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104&quot;);
+var truncatedPkcs8P256Key10 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420&quot;);
+var truncatedPkcs8P256Key11 = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403&quot;);
+var longPkcs8P256Key = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2badbad&quot;);
+var corruptedPkcs8P256Key = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420005d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2&quot;);
+var truncatedPkcs8P384Key1 = hexStringToUint8Array(&quot;3081b6020100301006072a8648ce3d0201&quot;);
+var truncatedPkcs8P384Key2 = hexStringToUint8Array(&quot;3081b6020100301006072a8648ce3d020106052b81040023&quot;);
</ins><span class="cx"> 
</span><span class="cx"> // Named curves mismatch raw keys
</span><span class="cx"> shouldReject('crypto.subtle.importKey(&quot;raw&quot;, rawP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
</span><span class="lines">@@ -57,6 +88,50 @@
</span><span class="cx"> shouldReject('crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x384, y:y}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
</span><span class="cx"> shouldReject('crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x, y:y384}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
</span><span class="cx"> shouldReject('crypto.subtle.importKey(&quot;jwk&quot;, {kty: &quot;EC&quot;, crv: &quot;P-384&quot;, x:x384, y:y384, d:d}, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
</span><ins>+// Spki: Non-empty usages
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, spkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;])');
+// Spki: Truncated keys
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key4, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key5, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key6, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key7, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP256Key8, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, truncatedSpkiP384Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
+// Spki: Missmatched Curves
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, spkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ])');
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, spkiP384Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+// Spki: Corrupted Key Data
+shouldReject('crypto.subtle.importKey(&quot;spki&quot;, corruptedSpkiP256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ])');
+// Pkcs8: Wrong usages
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;encrypt&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;decrypt&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;sign&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;verify&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;wrapKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;unwrapKey&quot;])');
+// Pkcs8: Truncated keys
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key3, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key4, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key5, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key6, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key7, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key8, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key9, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key10, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P256Key11, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P384Key1, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [&quot;deriveKey&quot;])');
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, truncatedPkcs8P384Key2, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [&quot;deriveKey&quot;])');
+// Pkcs8: Long key
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, longPkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
+// Pkcs8: Corrupted Key Data
+shouldReject('crypto.subtle.importKey(&quot;pkcs8&quot;, corruptedPkcs8P256Key, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;])');
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportpkcs8keyexportjwkkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+Test importing a P-384 PKCS8 ECDH key and exporting it in JWK format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS privateKey.kty is expectedJwkKey.kty
+PASS privateKey.crv is expectedJwkKey.crv
+PASS privateKey.x is expectedJwkKey.x
+PASS privateKey.y is expectedJwkKey.y
+PASS privateKey.d is expectedJwkKey.d
+PASS privateKey.key_ops is expectedJwkKey.key_ops
+PASS privateKey.ext is expectedJwkKey.ext
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportpkcs8keyexportjwkkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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 importing a P-384 PKCS8 ECDH key and exporting it in JWK format&quot;);
+
+jsTestIsAsync = true;
+
+var pkcs8Key = hexStringToUint8Array(&quot;3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104307fdf264b53c1a5e0c6be32f6736a73591f6a2d536c5ac6906b19ebe371ab71ec84c2b102def67aa0db451382604fb21aa1640362000413dcd0e8352158ca1ee5807c3f91d3b7331942baf7a48b0e3ad28fb6b665b1d8188dc01415058dbdb141f81e7cbf595861b1617b3deb5360b7e3dd0e48b92cdf957117cdefa77bc8f797b5b73a614028a83fc123a48c74eec9ca3c3e89322d57&quot;);
+var expectedJwkKey = {
+    kty: &quot;EC&quot;,
+    ext: true,
+    key_ops: [&quot;deriveBits&quot;, &quot;deriveKey&quot;],
+    crv: &quot;P-384&quot;,
+    x: &quot;E9zQ6DUhWMoe5YB8P5HTtzMZQrr3pIsOOtKPtrZlsdgYjcAUFQWNvbFB-B58v1lY&quot;,
+    y: &quot;YbFhez3rU2C3490OSLks35VxF83vp3vI95e1tzphQCioP8EjpIx07snKPD6JMi1X&quot;,
+    d: &quot;f98mS1PBpeDGvjL2c2pzWR9qLVNsWsaQaxnr43GrceyEwrEC3vZ6oNtFE4JgT7Ia&quot;,
+};
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, key);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;privateKey.kty&quot;, &quot;expectedJwkKey.kty&quot;);
+    shouldBe(&quot;privateKey.crv&quot;, &quot;expectedJwkKey.crv&quot;);
+    shouldBe(&quot;privateKey.x&quot;, &quot;expectedJwkKey.x&quot;);
+    shouldBe(&quot;privateKey.y&quot;, &quot;expectedJwkKey.y&quot;);
+    shouldBe(&quot;privateKey.d&quot;, &quot;expectedJwkKey.d&quot;);
+    shouldBe(&quot;privateKey.key_ops&quot;, &quot;expectedJwkKey.key_ops&quot;);
+    shouldBe(&quot;privateKey.ext&quot;, &quot;expectedJwkKey.ext&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="trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a P-256 PKCS8 ECDH key and exporting it in PKCS8 format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(privateKey) is pkcs8KeyHex
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp256html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing a P-256 PKCS8 ECDH key and exporting it in PKCS8 format&quot;);
+
+jsTestIsAsync = true;
+
+var pkcs8KeyHex = &quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2&quot;;
+var pkcs8Key = hexStringToUint8Array(pkcs8KeyHex);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, key);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;bytesToHexString(privateKey)&quot;, &quot;pkcs8KeyHex&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="trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a P-384 PKCS8 ECDH key and exporting it in PKCS8 format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(privateKey) is pkcs8KeyHex
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportpkcs8keyexportpkcs8keyp384html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing a P-384 PKCS8 ECDH key and exporting it in PKCS8 format&quot;);
+
+jsTestIsAsync = true;
+
+var pkcs8KeyHex = &quot;3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104307fdf264b53c1a5e0c6be32f6736a73591f6a2d536c5ac6906b19ebe371ab71ec84c2b102def67aa0db451382604fb21aa1640362000413dcd0e8352158ca1ee5807c3f91d3b7331942baf7a48b0e3ad28fb6b665b1d8188dc01415058dbdb141f81e7cbf595861b1617b3deb5360b7e3dd0e48b92cdf957117cdefa77bc8f797b5b73a614028a83fc123a48c74eec9ca3c3e89322d57&quot;;
+var pkcs8Key = hexStringToUint8Array(pkcs8KeyHex);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, key);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;bytesToHexString(privateKey)&quot;, &quot;pkcs8KeyHex&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="trunkLayoutTestscryptosubtleecimportrawkeyexportspkikeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing an ECDH raw key and then export it in SPKI format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(publicKey) is expectedSpkiKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportrawkeyexportspkikeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-raw-key-export-spki-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing an ECDH raw key and then export it in SPKI format&quot;);
+
+jsTestIsAsync = true;
+
+var rawKey = hexStringToUint8Array(&quot;04dc08d9bf603333eab1ad29cef41a6203ab6ecce03c5a4a9bf5771a3fb9f971d89a09664bfb87c61199b3453220eadec714c49ad1e24bf5d7ec5bddeca6420893&quot;);
+var expectedSpkiKey = &quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004dc08d9bf603333eab1ad29cef41a6203ab6ecce03c5a4a9bf5771a3fb9f971d89a09664bfb87c61199b3453220eadec714c49ad1e24bf5d7ec5bddeca6420893&quot;;
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;spki&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;bytesToHexString(publicKey)&quot;, &quot;expectedSpkiKey&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="trunkLayoutTestscryptosubtleecimportspkikeyexportjwkkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test importing a SPKI ECDH key and exporting it in JWK format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS publicKey.kty is expectedJwkKey.kty
+PASS publicKey.crv is expectedJwkKey.crv
+PASS publicKey.x is expectedJwkKey.x
+PASS publicKey.y is expectedJwkKey.y
+PASS publicKey.key_ops is [ ]
+PASS publicKey.ext is expectedJwkKey.ext
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportspkikeyexportjwkkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-jwk-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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 importing a SPKI ECDH key and exporting it in JWK format&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKey = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var expectedJwkKey = {
+    kty: &quot;EC&quot;,
+    use: &quot;enc&quot;,
+    ext: true,
+    crv: &quot;P-256&quot;,
+    x: &quot;w-46LDOAByubKln-0sraZRIYBuIsT0-KJedA_D5U110&quot;,
+    y: &quot;hsIAKY5t_BYR0YXu29s8JmGw6wRB9_1XyQ0IES6a5xw&quot;,
+};
+
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;jwk&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+
+    shouldBe(&quot;publicKey.kty&quot;, &quot;expectedJwkKey.kty&quot;);
+    shouldBe(&quot;publicKey.crv&quot;, &quot;expectedJwkKey.crv&quot;);
+    shouldBe(&quot;publicKey.x&quot;, &quot;expectedJwkKey.x&quot;);
+    shouldBe(&quot;publicKey.y&quot;, &quot;expectedJwkKey.y&quot;);
+    shouldBe(&quot;publicKey.key_ops&quot;, &quot;[ ]&quot;);
+    shouldBe(&quot;publicKey.ext&quot;, &quot;expectedJwkKey.ext&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="trunkLayoutTestscryptosubtleecimportspkikeyexportrawkeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a SPKI ECDH key and exporting it in raw format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(publicKey) is expectedRawKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportspkikeyexportrawkeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-raw-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing a SPKI ECDH key and exporting it in raw format&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKey = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var expectedRawKey = &quot;04c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;;
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;raw&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;bytesToHexString(publicKey)&quot;, &quot;expectedRawKey&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="trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a P-256 SPKI ECDH key and exporting it in SPKI format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(publicKey) is spkiKeyHex
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp256html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing a P-256 SPKI ECDH key and exporting it in SPKI format&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKeyHex = &quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;;
+var spkiKey = hexStringToUint8Array(spkiKeyHex);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;spki&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;bytesToHexString(publicKey)&quot;, &quot;spkiKeyHex&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="trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test importing a P-384 SPKI ECDH key and exporting it in SPKI format
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS bytesToHexString(publicKey) is spkiKeyHex
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecimportspkikeyexportspkikeyp384html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ec-import-spki-key-export-spki-key-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,35 @@
</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 importing a P-384 SPKI ECDH key and exporting it in SPKI format&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKeyHex = &quot;3076301006072a8648ce3d020106052b8104002203620004478f6119747475f94b742654be32ab6ebbdc371afa34fbee6d12c32fe2d586231262b17d13a1f271f19c8008c034d8716b7df0ce1d987990c5b175ecae1aa40f2fb89e4778528e1234e56d69638db135d103fa68448fee2b4f58ecc86d7f4b7a&quot;;
+var spkiKey = hexStringToUint8Array(spkiKeyHex);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [ ]).then(function(key) {
+    return crypto.subtle.exportKey(&quot;spki&quot;, key);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;bytesToHexString(publicKey)&quot;, &quot;spkiKeyHex&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="trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test exporting a P-256 ECDH public key with SPKI format.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.byteLength is 91
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip256htmlfromrev214073trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,39 @@
</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 exporting a P-256 ECDH public key with SPKI format.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-256&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;spki&quot;, keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.byteLength&quot;, &quot;91&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="trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test exporting a P-384 ECDH public key with SPKI format.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.byteLength is 120
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgenerateexportkeyspkip384htmlfromrev214073trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,39 @@
</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 exporting a P-384 ECDH public key with SPKI format.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-384&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;spki&quot;, keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.byteLength&quot;, &quot;120&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="trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test exporting a P-256 ECDH private key with PKCS8 format.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Generating a key pair...
+Exporting the public key...
+PASS privateKey.byteLength is 138
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p256htmlfromrev214073trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,39 @@
</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 exporting a P-256 ECDH private key with PKCS8 format.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-256&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;privateKey.byteLength&quot;, &quot;138&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="trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test exporting a P-384 ECDH private key with PKCS8 format.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Generating a key pair...
+Exporting the public key...
+PASS privateKey.byteLength is 185
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgenerateexportpkcs8p384htmlfromrev214073trunkLayoutTestscryptosubtleecexportkeymalformedparametershtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384.html (from rev 214073, trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html) (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,39 @@
</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 exporting a P-384 ECDH private key with PKCS8 format.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-384&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;privateKey.byteLength&quot;, &quot;185&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="trunkLayoutTestscryptosubtleecdhimportpkcs8keyp256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test importing a P-256 PKCS8 ECDH key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'private'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'ECDH'
+PASS publicKey.algorithm.namedCurve is 'P-256'
+PASS publicKey.usages is [ 'deriveBits', 'deriveKey' ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportpkcs8keyp256html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</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 importing a P-256 PKCS8 ECDH key&quot;);
+
+jsTestIsAsync = true;
+
+var pkcs8Key = hexStringToUint8Array(&quot;308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'private'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-256'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ 'deriveBits', 'deriveKey' ]&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="trunkLayoutTestscryptosubtleecdhimportpkcs8keyp384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test importing a P-384 PKCS8 ECDH key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'private'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'ECDH'
+PASS publicKey.algorithm.namedCurve is 'P-384'
+PASS publicKey.usages is [ 'deriveBits', 'deriveKey' ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportpkcs8keyp384html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-pkcs8-key-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,38 @@
</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 importing a P-384 PKCS8 ECDH key&quot;);
+
+jsTestIsAsync = true;
+
+// From OpenSSL
+var pkcs8Key = Base64URL.parse(&quot;MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCmchQf8pIqW87DnVZ/hRK5k4ueQK58pYL9KZ5pRl0HIl/Y9NOOy9SQydZKjZclxRihZANiAARP6PR5oBstUk0PY3rdA5G3MzRKnspHAjWdQq1CrP0GMud8hVU06JaCj+x2MYs6p/l0XtlKGaVRUqRBjP3yd9PXBt3z1EPuBxCscXzoW6YOj+KefYs9/geXx+tH0sGahso&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'private'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-384'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ 'deriveBits', 'deriveKey' ]&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="trunkLayoutTestscryptosubtleecdhimportspkikeyp256expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test importing a P-256 SPKI ECDH key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'ECDH'
+PASS publicKey.algorithm.namedCurve is 'P-256'
+PASS publicKey.usages is [ ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportspkikeyp256html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p256.html        2017-03-16 22:32:20 UTC (rev 214074)
</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 importing a P-256 SPKI ECDH key&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKey = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [ ]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'public'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-256'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ ]&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="trunkLayoutTestscryptosubtleecdhimportspkikeyp384expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test importing a P-384 SPKI ECDH key
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'ECDH'
+PASS publicKey.algorithm.namedCurve is 'P-384'
+PASS publicKey.usages is [ ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportspkikeyp384html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-spki-key-p384.html        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,38 @@
</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 importing a P-384 SPKI ECDH key&quot;);
+
+jsTestIsAsync = true;
+
+// From OpenSSL
+var spkiKey = Base64URL.parse(&quot;MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAET+j0eaAbLVJND2N63QORtzM0Sp7KRwI1nUKtQqz9BjLnfIVVNOiWgo/sdjGLOqf5dF7ZShmlUVKkQYz98nfT1wbd89RD7gcQrHF86FumDo/inn2LPf4Hl8frR9LBmobK&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [ ]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'public'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-384'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ ]&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="trunkLayoutTestscryptoworkerssubtleecgenerateexportpkcs8keyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+[Worker] Test exporting a ECDH private key with PKCS8 format.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/ec-generate-export-pkcs8-key.js
+[Worker] Generating a key pair...
+[Worker] Exporting the public key...
+PASS [Worker] privateKey.byteLength is 185
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecgenerateexportpkcs8keyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-pkcs8-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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/ec-generate-export-pkcs8-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="trunkLayoutTestscryptoworkerssubtleecgenerateexportspkikeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+[Worker] Test exporting an ECDH public key with SPKI format in workers.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/ec-generate-export-spki-key.js
+[Worker] Generating a key pair...
+[Worker] Exporting the public key...
+PASS [Worker] publicKey.byteLength is 91
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecgenerateexportspkikeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-generate-export-spki-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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/ec-generate-export-spki-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="trunkLayoutTestscryptoworkerssubtleecimportpkcs8keyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+[Worker] Test importing a PKCS8 ECDH key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/ec-import-pkcs8-key.js
+[Worker] Importing a key...
+PASS [Worker] publicKey.toString() is '[object CryptoKey]'
+PASS [Worker] publicKey.type is 'private'
+PASS [Worker] publicKey.extractable is true
+PASS [Worker] publicKey.algorithm.name is 'ECDH'
+PASS [Worker] publicKey.algorithm.namedCurve is 'P-384'
+PASS [Worker] publicKey.usages is [ 'deriveBits', 'deriveKey' ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecimportpkcs8keyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-import-pkcs8-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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/ec-import-pkcs8-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="trunkLayoutTestscryptoworkerssubtleecimportspkikeyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key-expected.txt (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+[Worker] Test importing a SPKI ECDH key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/ec-import-spki-key.js
+[Worker] Importing a key...
+PASS [Worker] publicKey.toString() is '[object CryptoKey]'
+PASS [Worker] publicKey.type is 'public'
+PASS [Worker] publicKey.extractable is true
+PASS [Worker] publicKey.algorithm.name is 'ECDH'
+PASS [Worker] publicKey.algorithm.namedCurve is 'P-256'
+PASS [Worker] publicKey.usages is [ ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecimportspkikeyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key.html (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ec-import-spki-key.html        2017-03-16 22:32:20 UTC (rev 214074)
</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/ec-import-spki-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="trunkLayoutTestscryptoworkerssubtleresourcesecgenerateexportpkcs8keyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts(&quot;../../../resources/common.js&quot;);
+
+description(&quot;Test exporting a ECDH private key with PKCS8 format.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-384&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;pkcs8&quot;, keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe(&quot;privateKey.byteLength&quot;, &quot;185&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesecgenerateexportspkikeyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-spki-key.js (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-spki-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/ec-generate-export-spki-key.js        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts(&quot;../../../resources/common.js&quot;);
+
+description(&quot;Test exporting an ECDH public key with SPKI format in workers.&quot;);
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: &quot;ECDH&quot;,
+    namedCurve: &quot;P-256&quot;
+};
+var extractable = true;
+
+var keyPair;
+debug(&quot;Generating a key pair...&quot;);
+crypto.subtle.generateKey(algorithmKeyGen, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    keyPair = result;
+    debug(&quot;Exporting the public key...&quot;);
+    return crypto.subtle.exportKey(&quot;spki&quot;, keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.byteLength&quot;, &quot;91&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesecimportpkcs8keyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-pkcs8-key.js (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-pkcs8-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-pkcs8-key.js        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts(&quot;../../../resources/common.js&quot;);
+
+description(&quot;Test importing a PKCS8 ECDH key in workers&quot;);
+
+jsTestIsAsync = true;
+
+// From OpenSSL
+var pkcs8Key = Base64URL.parse(&quot;MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCmchQf8pIqW87DnVZ/hRK5k4ueQK58pYL9KZ5pRl0HIl/Y9NOOy9SQydZKjZclxRihZANiAARP6PR5oBstUk0PY3rdA5G3MzRKnspHAjWdQq1CrP0GMud8hVU06JaCj+x2MYs6p/l0XtlKGaVRUqRBjP3yd9PXBt3z1EPuBxCscXzoW6YOj+KefYs9/geXx+tH0sGahso&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;pkcs8&quot;, pkcs8Key, {name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot;}, extractable, [&quot;deriveKey&quot;, &quot;deriveBits&quot;]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'private'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-384'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ 'deriveBits', 'deriveKey' ]&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesecimportspkikeyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-spki-key.js (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-spki-key.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/ec-import-spki-key.js        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts(&quot;../../../resources/common.js&quot;);
+
+description(&quot;Test importing a SPKI ECDH key in workers&quot;);
+
+jsTestIsAsync = true;
+
+var spkiKey = hexStringToUint8Array(&quot;3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c&quot;);
+var extractable = true;
+
+debug(&quot;Importing a key...&quot;);
+crypto.subtle.importKey(&quot;spki&quot;, spkiKey, {name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot;}, extractable, [ ]).then(function(result) {
+    publicKey = result;
+
+    shouldBe(&quot;publicKey.toString()&quot;, &quot;'[object CryptoKey]'&quot;);
+    shouldBe(&quot;publicKey.type&quot;, &quot;'public'&quot;);
+    shouldBe(&quot;publicKey.extractable&quot;, &quot;true&quot;);
+    shouldBe(&quot;publicKey.algorithm.name&quot;, &quot;'ECDH'&quot;);
+    shouldBe(&quot;publicKey.algorithm.namedCurve&quot;, &quot;'P-256'&quot;);
+    shouldBe(&quot;publicKey.usages&quot;, &quot;[ ]&quot;);
+
+    finishJSTest();
+});
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2017-03-16  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
+        https://bugs.webkit.org/show_bug.cgi?id=169318
+        &lt;rdar://problem/31081956&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt:
+        * web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt:
+
</ins><span class="cx"> 2017-03-14  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Import web-platform-tests/cors
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsWebCryptoAPIimport_exportec_importKeyworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -23,52 +23,52 @@
</span><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><span class="cx"> FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDSA, namedCurve: P-521}, false, [sign]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDSA, namedCurve: P-521}, false, [sign]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><del>-FAIL Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, []) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, true, []) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) 
</span><del>-FAIL Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, []) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, false, []) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) 
</span><del>-FAIL Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, []) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, true, []) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) 
</span><del>-FAIL Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, []) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, false, []) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) 
</span><del>-FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsWebCryptoAPIimport_exporttest_ec_importKeyexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -23,52 +23,52 @@
</span><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDSA, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><span class="cx"> FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDSA, namedCurve: P-521}, false, [sign]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDSA, namedCurve: P-521}, false, [sign]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The operation is not supported. Reached unreachable code
</span><del>-FAIL Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, []) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, true, []) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits]) 
</span><del>-FAIL Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, []) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, false, []) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits]) 
</span><del>-FAIL Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, []) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, true, []) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits]) 
</span><del>-FAIL Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, []) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, false, []) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey]) 
</span><del>-FAIL Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) 
</ins><span class="cx"> PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits]) 
</span><del>-FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, true, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, false, []) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><del>-FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: NotSupportedError (DOM Exception 9): The algorithm is not supported Reached unreachable code
</del><ins>+FAIL Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</ins><span class="cx"> FAIL Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, false, [deriveBits]) assert_unreached: Threw an unexpected error: DataError (DOM Exception 30): Data provided to an operation does not meet requirements Reached unreachable code
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/ChangeLog        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -1,3 +1,84 @@
</span><ins>+2017-03-16  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
+        https://bugs.webkit.org/show_bug.cgi?id=169318
+        &lt;rdar://problem/31081956&gt;
+
+        Reviewed by Brent Fulgham.
+
+        This patch adds SPKI/PKCS8 support for Elliptic Curve cryptos. We can now import/export
+        SPKI/PKCS8 Elliptic Curve keys after this change. Few things to note: 1) This patch
+        implements a loose DER encoder/decoder for hacking the underlying CommonCrypto library.
+        2) It only permits id-ecPublicKey as the AlgorithmIdentifier following OpenSSL/Chrome(BoringSSL).
+        3) It follows OpenSSL/Chrome(BoringSSL) to replace ECParameters in ECPrivateKey with custom
+        tags. Hence, we should fully comply with OpenSSL/Chrome(BoringSSL).
+
+        Tests: crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html
+               crypto/subtle/ec-import-jwk-key-export-spki-key.html
+               crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html
+               crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html
+               crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html
+               crypto/subtle/ec-import-raw-key-export-spki-key.html
+               crypto/subtle/ec-import-spki-key-export-jwk-key.html
+               crypto/subtle/ec-import-spki-key-export-raw-key.html
+               crypto/subtle/ec-import-spki-key-export-spki-key-p256.html
+               crypto/subtle/ec-import-spki-key-export-spki-key-p384.html
+               crypto/subtle/ecdh-generate-export-key-spki-p256.html
+               crypto/subtle/ecdh-generate-export-key-spki-p384.html
+               crypto/subtle/ecdh-generate-export-pkcs8-p256.html
+               crypto/subtle/ecdh-generate-export-pkcs8-p384.html
+               crypto/subtle/ecdh-import-pkcs8-key-p256.html
+               crypto/subtle/ecdh-import-pkcs8-key-p384.html
+               crypto/subtle/ecdh-import-spki-key-p256.html
+               crypto/subtle/ecdh-import-spki-key-p384.html
+               crypto/workers/subtle/ec-generate-export-pkcs8-key.html
+               crypto/workers/subtle/ec-generate-export-spki-key.html
+               crypto/workers/subtle/ec-import-pkcs8-key.html
+               crypto/workers/subtle/ec-import-spki-key.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * crypto/algorithms/CryptoAlgorithmECDH.cpp:
+        (WebCore::CryptoAlgorithmECDH::importKey):
+        (WebCore::CryptoAlgorithmECDH::exportKey):
+        * crypto/gnutls/CryptoKeyECGnuTLS.cpp:
+        (WebCore::CryptoKeyEC::platformExportRaw):
+        (WebCore::CryptoKeyEC::platformImportSpki):
+        (WebCore::CryptoKeyEC::platformExportSpki):
+        (WebCore::CryptoKeyEC::platformImportPkcs8):
+        (WebCore::CryptoKeyEC::platformExportPkcs8):
+        (WebCore::CryptoKeyEC::exportRaw): Deleted.
+        * crypto/keys/CryptoKeyEC.cpp:
+        (WebCore::CryptoKeyEC::importSpki):
+        (WebCore::CryptoKeyEC::importPkcs8):
+        (WebCore::CryptoKeyEC::exportRaw):
+        (WebCore::CryptoKeyEC::exportSpki):
+        (WebCore::CryptoKeyEC::exportPkcs8):
+        * crypto/keys/CryptoKeyEC.h:
+        * crypto/mac/CommonCryptoDERUtilities.h: Added.
+        (WebCore::bytesUsedToEncodedLength):
+        (WebCore::extraBytesNeededForEncodedLength):
+        (WebCore::addEncodedASN1Length):
+        (WebCore::bytesNeededForEncodedLength):
+        * crypto/mac/CryptoKeyECMac.cpp:
+        (WebCore::compareBytes):
+        (WebCore::CryptoKeyEC::platformExportRaw):
+        (WebCore::CryptoKeyEC::platformImportJWKPrivate):
+        (WebCore::getOID):
+        (WebCore::CryptoKeyEC::platformImportSpki):
+        (WebCore::CryptoKeyEC::platformExportSpki):
+        (WebCore::CryptoKeyEC::platformImportPkcs8):
+        (WebCore::CryptoKeyEC::platformExportPkcs8):
+        (WebCore::CryptoKeyEC::exportRaw): Deleted.
+        Enlarge the robust of exportRaw.
+        * crypto/mac/CryptoKeyRSAMac.cpp:
+        (WebCore::CryptoKeyRSA::exportSpki):
+        (WebCore::CryptoKeyRSA::exportPkcs8):
+        Enhance the implementation.
+        (WebCore::bytesUsedToEncodedLength): Deleted.
+        (WebCore::bytesNeededForEncodedLength): Deleted.
+        (WebCore::addEncodedASN1Length): Deleted.
+        Moved to CommonCryptoDERUtilities.h.
+
</ins><span class="cx"> 2017-03-16  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Don't use an optional for didReceiveSocketStreamData's length
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -2582,6 +2582,7 @@
</span><span class="cx">                 57E657EC1E7162EA00F941CA /* CryptoAlgorithmPbkdf2Params.h in Headers */ = {isa = PBXBuildFile; fileRef = 57E657EB1E7162EA00F941CA /* CryptoAlgorithmPbkdf2Params.h */; };
</span><span class="cx">                 57E657EF1E71665400F941CA /* JSPbkdf2Params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57E657ED1E71665400F941CA /* JSPbkdf2Params.cpp */; };
</span><span class="cx">                 57E657F01E71665400F941CA /* JSPbkdf2Params.h in Headers */ = {isa = PBXBuildFile; fileRef = 57E657EE1E71665400F941CA /* JSPbkdf2Params.h */; };
</span><ins>+                57E664FC1E73703300765536 /* CommonCryptoDERUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */; };
</ins><span class="cx">                 57EF5E601D20C83900171E60 /* TextCodecReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */; };
</span><span class="cx">                 57EF5E621D20D28700171E60 /* TextCodecReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */; };
</span><span class="cx">                 57FEDD3F1DB6D59200EB96F5 /* CryptoAlgorithmRsaKeyGenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 57FEDD3E1DB6D59200EB96F5 /* CryptoAlgorithmRsaKeyGenParams.h */; };
</span><span class="lines">@@ -10257,6 +10258,7 @@
</span><span class="cx">                 57E657EB1E7162EA00F941CA /* CryptoAlgorithmPbkdf2Params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmPbkdf2Params.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 57E657ED1E71665400F941CA /* JSPbkdf2Params.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPbkdf2Params.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 57E657EE1E71665400F941CA /* JSPbkdf2Params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPbkdf2Params.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonCryptoDERUtilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecReplacement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecReplacement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 57F827391DB72C22009D2BF4 /* RsaHashedKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaHashedKeyGenParams.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -24200,6 +24202,7 @@
</span><span class="cx">                 E172AF71180F343400FBADB9 /* mac */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */,
</ins><span class="cx">                                 E125F843182425C900D84CD9 /* CryptoAlgorithmAES_CBCMac.cpp */,
</span><span class="cx">                                 570440571E53851600356601 /* CryptoAlgorithmAES_CFBMac.cpp */,
</span><span class="cx">                                 57B5F80D1E5D2F2D00F34F90 /* CryptoAlgorithmAES_GCMMac.cpp */,
</span><span class="lines">@@ -27068,6 +27071,7 @@
</span><span class="cx">                                 2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */,
</span><span class="cx">                                 930908910AF7EDE40081DF01 /* HitTestRequest.h in Headers */,
</span><span class="cx">                                 9307F1D80AF2D59000DBA31A /* HitTestResult.h in Headers */,
</span><ins>+                                57E664FC1E73703300765536 /* CommonCryptoDERUtilities.h in Headers */,
</ins><span class="cx">                                 BC3BC29C0E91AB0F00835588 /* HostWindow.h in Headers */,
</span><span class="cx">                                 FD31609912B026F700C1A359 /* HRTFDatabase.h in Headers */,
</span><span class="cx">                                 FD31609B12B026F700C1A359 /* HRTFDatabaseLoader.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -153,9 +153,20 @@
</span><span class="cx">         }
</span><span class="cx">         result = CryptoKeyEC::importRaw(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get&lt;Vector&lt;uint8_t&gt;&gt;(data)), extractable, usages);
</span><span class="cx">         break;
</span><del>-    default:
-        exceptionCallback(NOT_SUPPORTED_ERR);
-        return;
</del><ins>+    case SubtleCrypto::KeyFormat::Spki:
+        if (usages) {
+            exceptionCallback(SYNTAX_ERR);
+            return;
+        }
+        result = CryptoKeyEC::importSpki(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get&lt;Vector&lt;uint8_t&gt;&gt;(data)), extractable, usages);
+        break;
+    case SubtleCrypto::KeyFormat::Pkcs8:
+        if (usages &amp;&amp; (usages ^ CryptoKeyUsageDeriveKey) &amp;&amp; (usages ^ CryptoKeyUsageDeriveBits) &amp;&amp; (usages ^ (CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits))) {
+            exceptionCallback(SYNTAX_ERR);
+            return;
+        }
+        result = CryptoKeyEC::importPkcs8(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get&lt;Vector&lt;uint8_t&gt;&gt;(data)), extractable, usages);
+        break;
</ins><span class="cx">     }
</span><span class="cx">     if (!result) {
</span><span class="cx">         exceptionCallback(DataError);
</span><span class="lines">@@ -176,22 +187,37 @@
</span><span class="cx"> 
</span><span class="cx">     KeyData result;
</span><span class="cx">     switch (format) {
</span><del>-    case SubtleCrypto::KeyFormat::Jwk: {
</del><ins>+    case SubtleCrypto::KeyFormat::Jwk:
</ins><span class="cx">         result = ecKey.exportJwk();
</span><span class="cx">         break;
</span><del>-    }
</del><span class="cx">     case SubtleCrypto::KeyFormat::Raw: {
</span><del>-        if (ecKey.type() != CryptoKey::Type::Public) {
-            exceptionCallback(INVALID_ACCESS_ERR);
</del><ins>+        auto raw = ecKey.exportRaw();
+        if (raw.hasException()) {
+            exceptionCallback(raw.releaseException().code());
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        result = ecKey.exportRaw();
</del><ins>+        result = raw.releaseReturnValue();
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><del>-    default:
-        exceptionCallback(NOT_SUPPORTED_ERR);
-        return;
</del><ins>+    case SubtleCrypto::KeyFormat::Spki: {
+        auto spki = ecKey.exportSpki();
+        if (spki.hasException()) {
+            exceptionCallback(spki.releaseException().code());
+            return;
+        }
+        result = spki.releaseReturnValue();
+        break;
</ins><span class="cx">     }
</span><ins>+    case SubtleCrypto::KeyFormat::Pkcs8: {
+        auto pkcs8 = ecKey.exportPkcs8();
+        if (pkcs8.hasException()) {
+            exceptionCallback(pkcs8.releaseException().code());
+            return;
+        }
+        result = pkcs8.releaseReturnValue();
+        break;
+    }
+    }
</ins><span class="cx"> 
</span><span class="cx">     callback(format, WTFMove(result));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecryptognutlsCryptoKeyECGnuTLScpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/gnutls/CryptoKeyECGnuTLS.cpp (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/gnutls/CryptoKeyECGnuTLS.cpp        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/gnutls/CryptoKeyECGnuTLS.cpp        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Vector&lt;uint8_t&gt; CryptoKeyEC::exportRaw() const
</del><ins>+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportRaw() const
</ins><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="cx"> 
</span><span class="lines">@@ -88,6 +88,34 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp;, bool, CryptoKeyUsageBitmap)
+{
+    notImplemented();
+
+    return nullptr;
+}
+
+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportSpki() const
+{
+    notImplemented();
+
+    return { };
+}
+
+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp;, bool, CryptoKeyUsageBitmap)
+{
+    notImplemented();
+
+    return nullptr;
+}
+
+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportPkcs8() const
+{
+    notImplemented();
+
+    return { };
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SUBTLE_CRYPTO)
</span></span></pre></div>
<a id="trunkSourceWebCorecryptokeysCryptoKeyECcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -113,6 +113,32 @@
</span><span class="cx">     return platformImportJWKPrivate(identifier, *namedCurve, WTFMove(x), WTFMove(y), WTFMove(d), extractable, usages);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::importSpki(CryptoAlgorithmIdentifier identifier, const String&amp; curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+    auto namedCurve = toNamedCurve(curve);
+    if (!namedCurve)
+        return nullptr;
+
+    return platformImportSpki(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
+}
+
+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::importPkcs8(CryptoAlgorithmIdentifier identifier, const String&amp; curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+    auto namedCurve = toNamedCurve(curve);
+    if (!namedCurve)
+        return nullptr;
+
+    return platformImportPkcs8(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
+}
+
+ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; CryptoKeyEC::exportRaw() const
+{
+    if (type() != CryptoKey::Type::Public)
+        return Exception { INVALID_ACCESS_ERR };
+
+    return platformExportRaw();
+}
+
</ins><span class="cx"> JsonWebKey CryptoKeyEC::exportJwk() const
</span><span class="cx"> {
</span><span class="cx">     JsonWebKey result;
</span><span class="lines">@@ -131,6 +157,22 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; CryptoKeyEC::exportSpki() const
+{
+    if (type() != CryptoKey::Type::Public)
+        return Exception { INVALID_ACCESS_ERR };
+
+    return platformExportSpki();
+}
+
+ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; CryptoKeyEC::exportPkcs8() const
+{
+    if (type() != CryptoKey::Type::Private)
+        return Exception { INVALID_ACCESS_ERR };
+
+    return platformExportPkcs8();
+}
+
</ins><span class="cx"> std::unique_ptr&lt;KeyAlgorithm&gt; CryptoKeyEC::buildAlgorithm() const
</span><span class="cx"> {
</span><span class="cx">     String name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
</span></span></pre></div>
<a id="trunkSourceWebCorecryptokeysCryptoKeyECh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -79,9 +79,13 @@
</span><span class="cx">     static ExceptionOr&lt;CryptoKeyPair&gt; generatePair(CryptoAlgorithmIdentifier, const String&amp; curve, bool extractable, CryptoKeyUsageBitmap);
</span><span class="cx">     static RefPtr&lt;CryptoKeyEC&gt; importRaw(CryptoAlgorithmIdentifier, const String&amp; curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
</span><span class="cx">     static RefPtr&lt;CryptoKeyEC&gt; importJwk(CryptoAlgorithmIdentifier, const String&amp; curve, JsonWebKey&amp;&amp;, bool extractable, CryptoKeyUsageBitmap);
</span><ins>+    static RefPtr&lt;CryptoKeyEC&gt; importSpki(CryptoAlgorithmIdentifier, const String&amp; curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
+    static RefPtr&lt;CryptoKeyEC&gt; importPkcs8(CryptoAlgorithmIdentifier, const String&amp; curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
</ins><span class="cx"> 
</span><del>-    Vector&lt;uint8_t&gt; exportRaw() const;
</del><ins>+    ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; exportRaw() const;
</ins><span class="cx">     JsonWebKey exportJwk() const;
</span><ins>+    ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; exportSpki() const;
+    ExceptionOr&lt;Vector&lt;uint8_t&gt;&gt; exportPkcs8() const;
</ins><span class="cx"> 
</span><span class="cx">     size_t keySizeInBits() const;
</span><span class="cx">     NamedCurve namedCurve() const { return m_curve; }
</span><span class="lines">@@ -99,7 +103,12 @@
</span><span class="cx">     static RefPtr&lt;CryptoKeyEC&gt; platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
</span><span class="cx">     static RefPtr&lt;CryptoKeyEC&gt; platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp; x, Vector&lt;uint8_t&gt;&amp;&amp; y, bool extractable, CryptoKeyUsageBitmap);
</span><span class="cx">     static RefPtr&lt;CryptoKeyEC&gt; platformImportJWKPrivate(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp; x, Vector&lt;uint8_t&gt;&amp;&amp; y, Vector&lt;uint8_t&gt;&amp;&amp; d, bool extractable, CryptoKeyUsageBitmap);
</span><ins>+    static RefPtr&lt;CryptoKeyEC&gt; platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
+    static RefPtr&lt;CryptoKeyEC&gt; platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap);
+    Vector&lt;uint8_t&gt; platformExportRaw() const;
</ins><span class="cx">     void platformAddFieldElements(JsonWebKey&amp;) const;
</span><ins>+    Vector&lt;uint8_t&gt; platformExportSpki() const;
+    Vector&lt;uint8_t&gt; platformExportPkcs8() const;
</ins><span class="cx"> 
</span><span class="cx">     PlatformECKey m_platformKey;
</span><span class="cx">     NamedCurve m_curve;
</span></span></pre></div>
<a id="trunkSourceWebCorecryptomacCommonCryptoDERUtilitiesh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/crypto/mac/CommonCryptoDERUtilities.h (0 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/mac/CommonCryptoDERUtilities.h                                (rev 0)
+++ trunk/Source/WebCore/crypto/mac/CommonCryptoDERUtilities.h        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -0,0 +1,86 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+// Per X.690 08/2015: https://www.itu.int/rec/T-REC-X.680-X.693/en
+static const unsigned char BitStringMark = 0x03;
+static const unsigned char OctetStringMark = 0x04;
+static const unsigned char SequenceMark = 0x30;
+// Version 0. Per https://tools.ietf.org/html/rfc5208#section-5
+static const unsigned char Version[] = {0x02, 0x01, 0x00};
+
+static const unsigned char InitialOctet = 0x00;
+static const size_t MaxLengthInOneByte = 128;
+
+static size_t bytesUsedToEncodedLength(uint8_t octet)
+{
+    if (octet &lt; MaxLengthInOneByte)
+        return 1;
+    return octet - MaxLengthInOneByte + 1;
+}
+
+static size_t extraBytesNeededForEncodedLength(size_t length)
+{
+    if (!length)
+        return 0;
+    size_t result = 1;
+    while (result &lt; sizeof(length) &amp;&amp; length &gt;= (1 &lt;&lt; (result * 8)))
+        result += 1;
+    return result;
+}
+
+static void addEncodedASN1Length(Vector&lt;uint8_t&gt;&amp; in, size_t length)
+{
+    if (length &lt; MaxLengthInOneByte) {
+        in.append(length);
+        return;
+    }
+
+    size_t extraBytes = extraBytesNeededForEncodedLength(length);
+    in.append(128 + extraBytes); // 128 is used to set the first bit of this byte.
+
+    size_t lastPosition = in.size() + extraBytes - 1;
+    in.grow(in.size() + extraBytes);
+    for (size_t i = 0; i &lt; extraBytes; i++) {
+        in[lastPosition - i] = length &amp; 0xff;
+        length = length &gt;&gt; 8;
+    }
+}
+
+static size_t bytesNeededForEncodedLength(size_t length)
+{
+    if (length &lt; MaxLengthInOneByte)
+        return 1;
+    return 1 + extraBytesNeededForEncodedLength(length);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
</ins></span></pre></div>
<a id="trunkSourceWebCorecryptomacCryptoKeyECMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SUBTLE_CRYPTO)
</span><span class="cx"> 
</span><ins>+#include &quot;CommonCryptoDERUtilities.h&quot;
</ins><span class="cx"> #include &quot;CommonCryptoUtilities.h&quot;
</span><span class="cx"> #include &quot;JsonWebKey.h&quot;
</span><span class="cx"> #include &lt;wtf/text/Base64.h&gt;
</span><span class="lines">@@ -34,7 +35,19 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static unsigned char InitialOctet = 0x04; // Per Section 2.3.3 of http://www.secg.org/sec1-v2.pdf
</del><ins>+static const unsigned char InitialOctetEC = 0x04; // Per Section 2.3.3 of http://www.secg.org/sec1-v2.pdf
+// OID id-ecPublicKey 1.2.840.10045.2.1.
+static const unsigned char IdEcPublicKey[] = {0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
+// OID secp256r1 1.2.840.10045.3.1.7.
+static constexpr unsigned char Secp256r1[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
+// OID secp384r1 1.3.132.0.34
+static constexpr unsigned char Secp384r1[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22};
+// Version 1. Per https://tools.ietf.org/html/rfc5915#section-3
+static const unsigned char PrivateKeyVersion[] = {0x02, 0x01, 0x01};
+// Custom OpenSSL ECParameters Tags
+static const size_t CustomTagSize = 2;
+static constexpr unsigned char EcP256[] = {0xa1, 0x44};
+static constexpr unsigned char EcP384[] = {0xa1, 0x64};
</ins><span class="cx"> 
</span><span class="cx"> // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
</span><span class="cx"> // We only support uncompressed point format.
</span><span class="lines">@@ -89,7 +102,7 @@
</span><span class="cx">     return result ? result : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Vector&lt;uint8_t&gt; CryptoKeyEC::exportRaw() const
</del><ins>+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportRaw() const
</ins><span class="cx"> {
</span><span class="cx">     Vector&lt;uint8_t&gt; result(keySizeInBits() / 4 + 1); // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
</span><span class="cx">     size_t size = result.size();
</span><span class="lines">@@ -141,9 +154,9 @@
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     // A hack to CommonCrypto since it doesn't provide API for creating private keys directly from x, y, d.
</span><del>-    // BinaryInput = InitialOctet + X + Y + D
</del><ins>+    // BinaryInput = InitialOctetEC + X + Y + D
</ins><span class="cx">     Vector&lt;uint8_t&gt; binaryInput;
</span><del>-    binaryInput.append(InitialOctet);
</del><ins>+    binaryInput.append(InitialOctetEC);
</ins><span class="cx">     binaryInput.appendVector(x);
</span><span class="cx">     binaryInput.appendVector(y);
</span><span class="cx">     binaryInput.appendVector(d);
</span><span class="lines">@@ -173,6 +186,214 @@
</span><span class="cx">         jwk.d = base64URLEncode(d);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static size_t getOID(CryptoKeyEC::NamedCurve curve, const uint8_t*&amp; oid)
+{
+    size_t oidSize;
+    switch (curve) {
+    case CryptoKeyEC::NamedCurve::P256:
+        oid = Secp256r1;
+        oidSize = sizeof(Secp256r1);
+        break;
+    case CryptoKeyEC::NamedCurve::P384:
+        oid = Secp384r1;
+        oidSize = sizeof(Secp384r1);
+    }
+    return oidSize;
+}
+
+// Per https://www.ietf.org/rfc/rfc5280.txt
+// SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }
+// AlgorithmIdentifier  ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL }
+// Per https://www.ietf.org/rfc/rfc5480.txt
+// id-ecPublicKey OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+// secp256r1 OBJECT IDENTIFIER      ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 }
+// secp384r1 OBJECT IDENTIFIER      ::= { iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+    // The following is a loose check on the provided SPKI key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
+    // Once the underlying crypto library is updated to accept SPKI EC Key, we should remove this hack.
+    // &lt;rdar://problem/30987628&gt;
+    size_t index = 1; // Read SEQUENCE
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]); // Read length
+    if (keyData.size() &lt; index + sizeof(IdEcPublicKey))
+        return nullptr;
+    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
+        return nullptr;
+    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
+    const uint8_t* oid;
+    size_t oidSize = getOID(curve, oid);
+    if (keyData.size() &lt; index + oidSize)
+        return nullptr;
+    if (memcmp(keyData.data() + index, oid, oidSize))
+        return nullptr;
+    index += oidSize + 1; // Read named curve OID, BIT STRING
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet
+
+    if (!doesUncompressedPointMatchNamedCurve(curve, keyData.size() - index))
+        return nullptr;
+
+    CCECCryptorRef ccPublicKey;
+    if (CCECCryptorImportKey(kCCImportKeyBinary, keyData.data() + index, keyData.size() - index, ccECKeyPublic, &amp;ccPublicKey))
+        return nullptr;
+
+    return create(identifier, curve, CryptoKeyType::Public, ccPublicKey, extractable, usages);
+}
+
+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportSpki() const
+{
+    Vector&lt;uint8_t&gt; keyBytes(keySizeInBits() / 4 + 1); // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
+    size_t keySize = keyBytes.size();
+    CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &amp;keySize, ccECKeyPublic, m_platformKey);
+
+    // The following addes SPKI header to a raw EC public key.
+    // Once the underlying crypto library is updated to output SPKI EC Key, we should remove this hack.
+    // &lt;rdar://problem/30987628&gt;
+    const uint8_t* oid;
+    size_t oidSize = getOID(namedCurve(), oid);
+
+    // SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1 + BIT STRING + length(?) + InitialOctet + Key size
+    size_t totalSize = sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(keySize + 1) + keySize + 4;
+
+    Vector&lt;uint8_t&gt; result;
+    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
+    result.append(SequenceMark);
+    addEncodedASN1Length(result, totalSize);
+    result.append(SequenceMark);
+    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
+    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
+    result.append(oid, oidSize);
+    result.append(BitStringMark);
+    addEncodedASN1Length(result, keySize + 1);
+    result.append(InitialOctet);
+    result.append(keyBytes.data(), keyBytes.size());
+
+    return result;
+}
+
+// Per https://www.ietf.org/rfc/rfc5208.txt
+// PrivateKeyInfo ::= SEQUENCE { version INTEGER, privateKeyAlgorithm AlgorithmIdentifier, privateKey OCTET STRING { ECPrivateKey } }
+// Per https://www.ietf.org/rfc/rfc5915.txt
+// ECPrivateKey ::= SEQUENCE { version INTEGER { ecPrivkeyVer1(1) }, privateKey OCTET STRING, parameters CustomECParameters, publicKey BIT STRING }
+// OpenSSL uses custom ECParameters. We follow OpenSSL as a compatibility concern.
+RefPtr&lt;CryptoKeyEC&gt; CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector&lt;uint8_t&gt;&amp;&amp; keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+    // The following is a loose check on the provided PKCS8 key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
+    // Once the underlying crypto library is updated to accept PKCS8 EC Key, we should remove this hack.
+    // &lt;rdar://problem/30987628&gt;
+    size_t index = 1; // Read SEQUENCE
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, SEQUENCE
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]); // Read length
+    if (keyData.size() &lt; index + sizeof(IdEcPublicKey))
+        return nullptr;
+    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
+        return nullptr;
+    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
+    const uint8_t* oid;
+    size_t oidSize = getOID(curve, oid);
+    if (keyData.size() &lt; index + oidSize)
+        return nullptr;
+    if (memcmp(keyData.data() + index, oid, oidSize))
+        return nullptr;
+    index += oidSize + 1; // Read named curve OID, OCTET STRING
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, OCTET STRING
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]); // Read length
+
+    if (keyData.size() &lt; index + getKeySizeFromNamedCurve(curve) / 8)
+        return nullptr;
+    size_t privateKeyPos = index;
+    index += getKeySizeFromNamedCurve(curve) / 8 + CustomTagSize + 1; // Read privateKey, CustomECParameters, BIT STRING
+    if (keyData.size() &lt; index + 1)
+        return nullptr;
+    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet
+
+    // KeyBinary = uncompressed point + private key
+    Vector&lt;uint8_t&gt; keyBinary;
+    keyBinary.append(keyData.data() + index, keyData.size() - index);
+    if (!doesUncompressedPointMatchNamedCurve(curve, keyBinary.size()))
+        return nullptr;
+    keyBinary.append(keyData.data() + privateKeyPos, getKeySizeFromNamedCurve(curve) / 8);
+
+    CCECCryptorRef ccPrivateKey;
+    if (CCECCryptorImportKey(kCCImportKeyBinary, keyBinary.data(), keyBinary.size(), ccECKeyPrivate, &amp;ccPrivateKey))
+        return nullptr;
+
+    return create(identifier, curve, CryptoKeyType::Private, ccPrivateKey, extractable, usages);
+}
+
+Vector&lt;uint8_t&gt; CryptoKeyEC::platformExportPkcs8() const
+{
+    size_t keySizeInBytes = keySizeInBits() / 8;
+    Vector&lt;uint8_t&gt; keyBytes(keySizeInBytes * 3 + 1); // 04 + X + Y + private key
+    size_t keySize = keyBytes.size();
+    CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &amp;keySize, ccECKeyPrivate, m_platformKey);
+
+    // The following addes PKCS8 header to a raw EC private key.
+    // Once the underlying crypto library is updated to output PKCS8 EC Key, we should remove this hack.
+    // &lt;rdar://problem/30987628&gt;
+    const uint8_t* oid;
+    size_t oidSize = getOID(namedCurve(), oid);
+    const uint8_t* customTag;
+    switch (namedCurve()) {
+    case NamedCurve::P256:
+        customTag = EcP256;
+        break;
+    case NamedCurve::P384:
+        customTag = EcP384;
+    }
+
+    // InitialOctet + 04 + X + Y
+    size_t publicKeySize = keySizeInBytes * 2 + 2;
+    // VERSION + OCTET STRING + length(1) + private key + CustomECParameters(2) + BIT STRING + length(?) + publicKeySize
+    size_t ecPrivateKeySize = sizeof(Version) + keySizeInBytes + CustomTagSize + bytesNeededForEncodedLength(publicKeySize) + publicKeySize + 3;
+    // SEQUENCE + length(?) + ecPrivateKeySize
+    size_t privateKeySize = bytesNeededForEncodedLength(ecPrivateKeySize) + ecPrivateKeySize + 1;
+    // VERSION + SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1 + OCTET STRING + length(?) + privateKeySize
+    size_t totalSize = sizeof(Version) + sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(privateKeySize) + privateKeySize + 3;
+
+    Vector&lt;uint8_t&gt; result;
+    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
+    result.append(SequenceMark);
+    addEncodedASN1Length(result, totalSize);
+    result.append(Version, sizeof(Version));
+    result.append(SequenceMark);
+    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
+    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
+    result.append(oid, oidSize);
+    result.append(OctetStringMark);
+    addEncodedASN1Length(result, privateKeySize);
+    result.append(SequenceMark);
+    addEncodedASN1Length(result, ecPrivateKeySize);
+    result.append(PrivateKeyVersion, sizeof(PrivateKeyVersion));
+    result.append(OctetStringMark);
+    addEncodedASN1Length(result, keySizeInBytes);
+    result.append(keyBytes.data() + publicKeySize - 1, keySizeInBytes);
+    result.append(customTag, CustomTagSize);
+    result.append(BitStringMark);
+    addEncodedASN1Length(result, publicKeySize);
+    result.append(InitialOctet);
+    result.append(keyBytes.data(), publicKeySize - 1);
+
+    return result;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SUBTLE_CRYPTO)
</span></span></pre></div>
<a id="trunkSourceWebCorecryptomacCryptoKeyRSAMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp (214073 => 214074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp        2017-03-16 22:15:58 UTC (rev 214073)
+++ trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp        2017-03-16 22:32:20 UTC (rev 214074)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SUBTLE_CRYPTO)
</span><span class="cx"> 
</span><ins>+#include &quot;CommonCryptoDERUtilities.h&quot;
</ins><span class="cx"> #include &quot;CommonCryptoUtilities.h&quot;
</span><span class="cx"> #include &quot;CryptoAlgorithmRegistry.h&quot;
</span><span class="cx"> #include &quot;CryptoKeyDataRSAComponents.h&quot;
</span><span class="lines">@@ -39,17 +40,8 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> // OID rsaEncryption: 1.2.840.113549.1.1.1. Per https://tools.ietf.org/html/rfc3279#section-2.3.1
</span><del>-static unsigned char RSAOIDHeader[] = {0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00};
-// Version 0. Per https://tools.ietf.org/html/rfc5208#section-5
-static unsigned char Version[] = {0x02, 0x01, 0x00};
</del><ins>+static const unsigned char RSAOIDHeader[] = {0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00};
</ins><span class="cx"> 
</span><del>-// Per X.690 08/2015: https://www.itu.int/rec/T-REC-X.680-X.693/en
-static unsigned char BitStringMark = 0x03;
-static unsigned char OctetStringMark = 0x04;
-static unsigned char SequenceMark = 0x30;
-
-static unsigned char InitialOctet = 0x00;
-
</del><span class="cx"> // FIXME: We should get rid of magic number 16384. It assumes that the length of provided key will not exceed 16KB.
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=164942
</span><span class="cx"> static CCCryptorStatus getPublicKeyComponents(CCRSACryptorRef rsaKey, Vector&lt;uint8_t&gt;&amp; modulus, Vector&lt;uint8_t&gt;&amp; publicExponent)
</span><span class="lines">@@ -253,41 +245,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static size_t bytesUsedToEncodedLength(uint8_t octet)
-{
-    if (octet &lt; 128)
-        return 1;
-    return octet - 127;
-}
-
-static size_t bytesNeededForEncodedLength(size_t length)
-{
-    if (!length)
-        return 0;
-    size_t result = 1;
-    while (result &lt; sizeof(length) &amp;&amp; length &gt;= (1 &lt;&lt; (result * 8)))
-        result += 1;
-    return result;
-}
-
-static void addEncodedASN1Length(Vector&lt;uint8_t&gt;&amp; in, size_t length)
-{
-    if (length &lt; 128) {
-        in.append(length);
-        return;
-    }
-
-    size_t extraBytes = bytesNeededForEncodedLength(length);
-    in.append(128 + extraBytes);
-
-    size_t lastPosition = in.size() + extraBytes - 1;
-    in.grow(in.size() + extraBytes);
-    for (size_t i = 0; i &lt; extraBytes; i++) {
-        in[lastPosition - i] = length &amp; 0xff;
-        length = length &gt;&gt; 8;
-    }
-}
-
</del><span class="cx"> // FIXME: We should use WorkQueue here instead of dispatch_async once WebKitSubtleCrypto is deprecated.
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=164943
</span><span class="cx"> void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector&lt;uint8_t&gt;&amp; publicExponent, bool extractable, CryptoKeyUsageBitmap usage, KeyPairCallback&amp;&amp; callback, VoidCallback&amp;&amp; failureCallback, ScriptExecutionContext* context)
</span><span class="lines">@@ -373,10 +330,11 @@
</span><span class="cx">     keyBytes.shrink(keySize);
</span><span class="cx"> 
</span><span class="cx">     // RSAOIDHeader + BitStringMark + Length + keySize + InitialOctet
</span><del>-    size_t totalSize = sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize + 1) + keySize + 3;
</del><ins>+    size_t totalSize = sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize + 1) + keySize + 2;
</ins><span class="cx"> 
</span><span class="cx">     // Per https://tools.ietf.org/html/rfc5280#section-4.1. subjectPublicKeyInfo.
</span><span class="cx">     Vector&lt;uint8_t&gt; result;
</span><ins>+    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
</ins><span class="cx">     result.append(SequenceMark);
</span><span class="cx">     addEncodedASN1Length(result, totalSize);
</span><span class="cx">     result.append(RSAOIDHeader, sizeof(RSAOIDHeader));
</span><span class="lines">@@ -431,10 +389,11 @@
</span><span class="cx">     keyBytes.shrink(keySize);
</span><span class="cx"> 
</span><span class="cx">     // Version + RSAOIDHeader + OctetStringMark + Length + keySize
</span><del>-    size_t totalSize = sizeof(Version) + sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize) + keySize + 2;
</del><ins>+    size_t totalSize = sizeof(Version) + sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize) + keySize + 1;
</ins><span class="cx"> 
</span><span class="cx">     // Per https://tools.ietf.org/html/rfc5208#section-5. PrivateKeyInfo.
</span><span class="cx">     Vector&lt;uint8_t&gt; result;
</span><ins>+    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
</ins><span class="cx">     result.append(SequenceMark);
</span><span class="cx">     addEncodedASN1Length(result, totalSize);
</span><span class="cx">     result.append(Version, sizeof(Version));
</span></span></pre>
</div>
</div>

</body>
</html>