Changeset 214074 in webkit


Ignore:
Timestamp:
Mar 16, 2017 3:32:20 PM (7 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
https://bugs.webkit.org/show_bug.cgi?id=169318
<rdar://problem/31081956>

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.
Location:
trunk
Files:
43 added
18 edited
6 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r214072 r214074  
     12017-03-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
     4        https://bugs.webkit.org/show_bug.cgi?id=169318
     5        <rdar://problem/31081956>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * crypto/subtle/ec-export-key-malformed-parameters-expected.txt:
     10        * crypto/subtle/ec-export-key-malformed-parameters.html:
     11        * crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt:
     12        * crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html:
     13        * crypto/subtle/ec-import-jwk-key-export-pkcs8-key-expected.txt: Added.
     14        * crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html: Added.
     15        * crypto/subtle/ec-import-jwk-key-export-spki-key-expected.txt: Added.
     16        * crypto/subtle/ec-import-jwk-key-export-spki-key.html: Added.
     17        * crypto/subtle/ec-import-key-malformed-parameters-expected.txt:
     18        * crypto/subtle/ec-import-key-malformed-parameters.html:
     19        * crypto/subtle/ec-import-pkcs8-key-export-jwk-key-expected.txt: Added.
     20        * crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html: Added.
     21        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256-expected.txt: Added.
     22        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html: Added.
     23        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384-expected.txt: Added.
     24        * crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html: Added.
     25        * crypto/subtle/ec-import-raw-key-export-spki-key-expected.txt: Added.
     26        * crypto/subtle/ec-import-raw-key-export-spki-key.html: Added.
     27        * crypto/subtle/ec-import-spki-key-export-jwk-key-expected.txt: Added.
     28        * crypto/subtle/ec-import-spki-key-export-jwk-key.html: Added.
     29        * crypto/subtle/ec-import-spki-key-export-raw-key-expected.txt: Added.
     30        * crypto/subtle/ec-import-spki-key-export-raw-key.html: Added.
     31        * crypto/subtle/ec-import-spki-key-export-spki-key-p256-expected.txt: Added.
     32        * crypto/subtle/ec-import-spki-key-export-spki-key-p256.html: Added.
     33        * crypto/subtle/ec-import-spki-key-export-spki-key-p384-expected.txt: Added.
     34        * crypto/subtle/ec-import-spki-key-export-spki-key-p384.html: Added.
     35        * crypto/subtle/ecdh-generate-export-key-spki-p256-expected.txt: Added.
     36        * crypto/subtle/ecdh-generate-export-key-spki-p256.html: Added.
     37        * crypto/subtle/ecdh-generate-export-key-spki-p384-expected.txt: Added.
     38        * crypto/subtle/ecdh-generate-export-key-spki-p384.html: Added.
     39        * crypto/subtle/ecdh-generate-export-pkcs8-p256-expected.txt: Added.
     40        * crypto/subtle/ecdh-generate-export-pkcs8-p256.html: Added.
     41        * crypto/subtle/ecdh-generate-export-pkcs8-p384-expected.txt: Added.
     42        * crypto/subtle/ecdh-generate-export-pkcs8-p384.html: Added.
     43        * crypto/subtle/ecdh-import-pkcs8-key-p256-expected.txt: Added.
     44        * crypto/subtle/ecdh-import-pkcs8-key-p256.html: Added.
     45        * crypto/subtle/ecdh-import-pkcs8-key-p384-expected.txt: Added.
     46        * crypto/subtle/ecdh-import-pkcs8-key-p384.html: Added.
     47        * crypto/subtle/ecdh-import-spki-key-p256-expected.txt: Added.
     48        * crypto/subtle/ecdh-import-spki-key-p256.html: Added.
     49        * crypto/subtle/ecdh-import-spki-key-p384-expected.txt: Added.
     50        * crypto/subtle/ecdh-import-spki-key-p384.html: Added.
     51        * crypto/workers/subtle/ec-generate-export-pkcs8-key-expected.txt: Added.
     52        * crypto/workers/subtle/ec-generate-export-pkcs8-key.html: Added.
     53        * crypto/workers/subtle/ec-generate-export-spki-key-expected.txt: Added.
     54        * crypto/workers/subtle/ec-generate-export-spki-key.html: Added.
     55        * crypto/workers/subtle/ec-import-pkcs8-key-expected.txt: Added.
     56        * crypto/workers/subtle/ec-import-pkcs8-key.html: Added.
     57        * crypto/workers/subtle/ec-import-spki-key-expected.txt: Added.
     58        * crypto/workers/subtle/ec-import-spki-key.html: Added.
     59        * crypto/workers/subtle/resources/ec-generate-export-pkcs8-key.js: Added.
     60        * crypto/workers/subtle/resources/ec-generate-export-spki-key.js: Added.
     61        * crypto/workers/subtle/resources/ec-import-pkcs8-key.js: Added.
     62        * crypto/workers/subtle/resources/ec-import-spki-key.js: Added.
     63
    1642017-03-16  Zalan Bujtas  <zalan@apple.com>
    265
  • trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters-expected.txt

    r213560 r214074  
    55
    66PASS crypto.subtle.exportKey("raw", privateKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
     7PASS crypto.subtle.exportKey("spki", privateKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
     8PASS crypto.subtle.exportKey("pkcs8", publicKey) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
    79PASS successfullyParsed is true
    810
  • trunk/LayoutTests/crypto/subtle/ec-export-key-malformed-parameters.html

    r213560 r214074  
    2222crypto.subtle.generateKey(algorithmKeyGen, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    2323    privateKey = result.privateKey;
     24    publicKey = result.publicKey;
    2425
    2526    // Wrong key and format.
    2627    return shouldReject('crypto.subtle.exportKey("raw", privateKey)');
     28}).then(function() {
     29    // Wrong key and format.
     30    return shouldReject('crypto.subtle.exportKey("spki", privateKey)');
     31}).then(function() {
     32    // Wrong key and format.
     33    return shouldReject('crypto.subtle.exportKey("pkcs8", publicKey)');
    2734}).then(finishJSTest, finishJSTest);
    2835
  • trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private-expected.txt

    r213560 r214074  
    55
    66Importing a key...
    7 PASS publicKey.kty is jwkKey.kty
    8 PASS publicKey.crv is jwkKey.crv
    9 PASS publicKey.x is jwkKey.x
    10 PASS publicKey.y is jwkKey.y
    11 PASS publicKey.d is jwkKey.d
    12 PASS publicKey.key_ops is jwkKey.key_ops
    13 PASS publicKey.ext is jwkKey.ext
     7PASS privateKey.kty is jwkKey.kty
     8PASS privateKey.crv is jwkKey.crv
     9PASS privateKey.x is jwkKey.x
     10PASS privateKey.y is jwkKey.y
     11PASS privateKey.d is jwkKey.d
     12PASS privateKey.key_ops is jwkKey.key_ops
     13PASS privateKey.ext is jwkKey.ext
    1414PASS successfullyParsed is true
    1515
  • trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-jwk-key-private.html

    r213560 r214074  
    2929    return crypto.subtle.exportKey("jwk", result);
    3030}).then(function(result) {
    31     publicKey = result;
     31    privateKey = result;
    3232
    33     shouldBe("publicKey.kty", "jwkKey.kty");
    34     shouldBe("publicKey.crv", "jwkKey.crv");
    35     shouldBe("publicKey.x", "jwkKey.x");
    36     shouldBe("publicKey.y", "jwkKey.y");
    37     shouldBe("publicKey.d", "jwkKey.d");
    38     shouldBe("publicKey.key_ops", "jwkKey.key_ops");
    39     shouldBe("publicKey.ext", "jwkKey.ext");
     33    shouldBe("privateKey.kty", "jwkKey.kty");
     34    shouldBe("privateKey.crv", "jwkKey.crv");
     35    shouldBe("privateKey.x", "jwkKey.x");
     36    shouldBe("privateKey.y", "jwkKey.y");
     37    shouldBe("privateKey.d", "jwkKey.d");
     38    shouldBe("privateKey.key_ops", "jwkKey.key_ops");
     39    shouldBe("privateKey.ext", "jwkKey.ext");
    4040
    4141    finishJSTest();
  • trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test importing a jwk private ECDH key and then export it in jwk format");
     12description("Test importing a jwk private ECDH key and then export it in PKCS8 format");
    1313
    1414jsTestIsAsync = true;
     
    2323    d: "ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg",
    2424};
     25var expectedPkcs8KeyHex = "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420a69c414a8bf737cfc051c8ac02ebe62d5e3213c7bf2ff04b13c6d96fd6755e38a14403420004d454955a2793be2905906d4d3b286450268c6dd421c701fa682bb8133fac46d0f6398d4cba8ce1c8c185d0271dc348f58415dcef0b166a3e11d65693c9ed01a2";
    2526var extractable = true;
    2627
    2728debug("Importing a key...");
    2829crypto.subtle.importKey("jwk", jwkKey, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    29     return crypto.subtle.exportKey("jwk", result);
     30    return crypto.subtle.exportKey("pkcs8", result);
    3031}).then(function(result) {
    31     publicKey = result;
     32    privateKey = result;
    3233
    33     shouldBe("publicKey.kty", "jwkKey.kty");
    34     shouldBe("publicKey.crv", "jwkKey.crv");
    35     shouldBe("publicKey.x", "jwkKey.x");
    36     shouldBe("publicKey.y", "jwkKey.y");
    37     shouldBe("publicKey.d", "jwkKey.d");
    38     shouldBe("publicKey.key_ops", "jwkKey.key_ops");
    39     shouldBe("publicKey.ext", "jwkKey.ext");
     34    shouldBe("bytesToHexString(privateKey)", "expectedPkcs8KeyHex");
    4035
    4136    finishJSTest();
  • trunk/LayoutTests/crypto/subtle/ec-import-jwk-key-export-spki-key.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test importing a jwk private ECDH key and then export it in jwk format");
     12description("Test importing a JWK ECDH public key and export it in SPKI format");
    1313
    1414jsTestIsAsync = true;
     
    1616var jwkKey = {
    1717    kty: "EC",
    18     ext: true,
    19     key_ops: ["deriveBits", "deriveKey"],
    2018    crv: "P-256",
    2119    x: "1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA",
    2220    y: "9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI",
    23     d: "ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg",
    2421};
     22var expectedSpkiKey = "3059301306072a8648ce3d020106082a8648ce3d03010703420004d454955a2793be2905906d4d3b286450268c6dd421c701fa682bb8133fac46d0f6398d4cba8ce1c8c185d0271dc348f58415dcef0b166a3e11d65693c9ed01a2";
    2523var extractable = true;
    2624
    2725debug("Importing a key...");
    28 crypto.subtle.importKey("jwk", jwkKey, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    29     return crypto.subtle.exportKey("jwk", result);
     26crypto.subtle.importKey("jwk", jwkKey, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]).then(function(key) {
     27    return crypto.subtle.exportKey("spki", key);
    3028}).then(function(result) {
    3129    publicKey = result;
    3230
    33     shouldBe("publicKey.kty", "jwkKey.kty");
    34     shouldBe("publicKey.crv", "jwkKey.crv");
    35     shouldBe("publicKey.x", "jwkKey.x");
    36     shouldBe("publicKey.y", "jwkKey.y");
    37     shouldBe("publicKey.d", "jwkKey.d");
    38     shouldBe("publicKey.key_ops", "jwkKey.key_ops");
    39     shouldBe("publicKey.ext", "jwkKey.ext");
     31    shouldBe("bytesToHexString(publicKey)", "expectedSpkiKey");
    4032
    4133    finishJSTest();
  • trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters-expected.txt

    r213560 r214074  
    2828PASS crypto.subtle.importKey("jwk", {kty: "EC", crv: "P-384", x:x, y:y384}, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
    2929PASS crypto.subtle.importKey("jwk", {kty: "EC", crv: "P-384", x:x384, y:y384, d:d}, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     30PASS crypto.subtle.importKey("spki", spkiP256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveBits"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     31PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key1, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     32PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key2, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     33PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key3, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     34PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key4, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     35PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key5, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     36PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key6, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     37PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key7, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     38PASS crypto.subtle.importKey("spki", truncatedSpkiP256Key8, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     39PASS crypto.subtle.importKey("spki", truncatedSpkiP384Key1, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     40PASS crypto.subtle.importKey("spki", truncatedSpkiP384Key2, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     41PASS crypto.subtle.importKey("spki", truncatedSpkiP384Key3, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     42PASS crypto.subtle.importKey("spki", spkiP256Key, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     43PASS crypto.subtle.importKey("spki", spkiP384Key, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     44PASS crypto.subtle.importKey("spki", corruptedSpkiP256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     45PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["encrypt"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     46PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["decrypt"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     47PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["sign"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     48PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["verify"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     49PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["wrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     50PASS crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["unwrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
     51PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key1, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     52PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key2, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     53PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key3, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     54PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key4, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     55PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key5, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     56PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key6, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     57PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key7, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     58PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key8, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     59PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key9, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     60PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key10, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     61PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key11, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     62PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P384Key1, { name: "ECDH", namedCurve: "P-384" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     63PASS crypto.subtle.importKey("pkcs8", truncatedPkcs8P384Key2, { name: "ECDH", namedCurve: "P-384" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     64PASS crypto.subtle.importKey("pkcs8", longPkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
     65PASS crypto.subtle.importKey("pkcs8", corruptedPkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
    3066PASS successfullyParsed is true
    3167
  • trunk/LayoutTests/crypto/subtle/ec-import-key-malformed-parameters.html

    r213560 r214074  
    2020var x384 = "1bHwFrsaPRjYq-zFOyLXK8Ugv3EqbVF075ct7ouTl_pwyhjeBu03JHjKTsyVbNWK";
    2121var y384 = "1bHwFrsaPRjYq-zFOyLXK8Ugv3EqbVF075ct7ouTl_pwyhjeBu03JHjKTsyVbNWK";
     22var spkiP256Key = hexStringToUint8Array("3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c");
     23var spkiP384Key = hexStringToUint8Array("3076301006072a8648ce3d020106052b8104002203620004478f6119747475f94b742654be32ab6ebbdc371afa34fbee6d12c32fe2d586231262b17d13a1f271f19c8008c034d8716b7df0ce1d987990c5b175ecae1aa40f2fb89e4778528e1234e56d69638db135d103fa68448fee2b4f58ecc86d7f4b7a");
     24var truncatedSpkiP256Key1 = hexStringToUint8Array("30");
     25var truncatedSpkiP256Key2 = hexStringToUint8Array("305930");
     26var truncatedSpkiP256Key3 = hexStringToUint8Array("305930130607");
     27var truncatedSpkiP256Key4 = hexStringToUint8Array("3059301306072b8648ce3d0201");
     28var truncatedSpkiP256Key5 = hexStringToUint8Array("3059301306072a8648ce3d02010608");
     29var truncatedSpkiP256Key6 = hexStringToUint8Array("3059301306072a8648ce3d020106082a8648ce3d030108");
     30var truncatedSpkiP256Key7 = hexStringToUint8Array("3059301306072a8648ce3d020106082a8648ce3d030107034200");
     31var truncatedSpkiP256Key8 = hexStringToUint8Array("3059301306072a8648ce3d020106082a8648ce3d03010703420004c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae7");
     32var truncatedSpkiP384Key1 = hexStringToUint8Array("3076301006072a8648ce3d02010605");
     33var truncatedSpkiP384Key2 = hexStringToUint8Array("3076301006072a8648ce3d020106052b81040022");
     34var truncatedSpkiP384Key3 = hexStringToUint8Array("3076301006072a8648ce3d020106052b8104002203620004478f6119747475f94b742654be32ab6ebbdc371afa34fbee6d12c32fe2d586231262b17d13a1f271f19c8008c034d8716b7df0ce1d987990c5b175ecae1aa40f2fb89e4778528e1234e56d69638db135d103fa68448fee2b4f58ecc86d7f4b");
     35var corruptedSpkiP256Key = hexStringToUint8Array("3059301306072a8648ce3d020106082a8648ce3d03010703420000c3ee3a2c3380072b9b2a59fed2cada65121806e22c4f4f8a25e740fc3e54d75d86c200298e6dfc1611d185eedbdb3c2661b0eb0441f7fd57c90d08112e9ae71c");
     36var pkcs8P256Key = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2");
     37var pkcs8P384Key = hexStringToUint8Array("3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430c38e34a7cd58961c8deda9c9118548724945d3f3b3bd71f03c93247304c1f7d86b8507501e4e05a0fbae76e44bbe8cc2a16403620004cb75013d8ba42edd022e9de8dfe856a2ee3f48ec28a666c4a73cf3d16e09c7d5747e6c5b5795a656e175c71feed01ec5e282b19e6650f6ea31970114f3e1e6e2275dd6811f87e7f7128c48806a9763785ac31bd345436e57eae23a1151355ef2");
     38var truncatedPkcs8P256Key1 = hexStringToUint8Array("30");
     39var truncatedPkcs8P256Key2 = hexStringToUint8Array("30818702010030");
     40var truncatedPkcs8P256Key3 = hexStringToUint8Array("3081870201003013");
     41var truncatedPkcs8P256Key4 = hexStringToUint8Array("308187020100301306072b8648ce3d0201");
     42var truncatedPkcs8P256Key5 = hexStringToUint8Array("308187020100301306072a8648ce3d0201");
     43var truncatedPkcs8P256Key6 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082b8648ce3d030107");
     44var truncatedPkcs8P256Key7 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d03010704");
     45var truncatedPkcs8P256Key8 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d30");
     46var truncatedPkcs8P256Key9 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104");
     47var truncatedPkcs8P256Key10 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420");
     48var truncatedPkcs8P256Key11 = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403");
     49var longPkcs8P256Key = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420004d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2badbad");
     50var corruptedPkcs8P256Key = hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104200a21f3f048b893b0f2b5a8459bd6d2bc112614aa86437f8fa2496a0e27f5b0a8a14403420005d726bd565878f24ee3616890d3668503334b84da3434b2774a44d6e4b9c536dd60e9181e1d1469ba3e6aba8987225f6e797d01a0dc400a4a298c902bae66abe2");
     51var truncatedPkcs8P384Key1 = hexStringToUint8Array("3081b6020100301006072a8648ce3d0201");
     52var truncatedPkcs8P384Key2 = hexStringToUint8Array("3081b6020100301006072a8648ce3d020106052b81040023");
    2253
    2354// Named curves mismatch raw keys
     
    5889shouldReject('crypto.subtle.importKey("jwk", {kty: "EC", crv: "P-384", x:x, y:y384}, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
    5990shouldReject('crypto.subtle.importKey("jwk", {kty: "EC", crv: "P-384", x:x384, y:y384, d:d}, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
     91// Spki: Non-empty usages
     92shouldReject('crypto.subtle.importKey("spki", spkiP256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveBits"])');
     93// Spki: Truncated keys
     94shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key1, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     95shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key2, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     96shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key3, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     97shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key4, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     98shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key5, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     99shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key6, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     100shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key7, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     101shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP256Key8, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     102shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP384Key1, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
     103shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP384Key2, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
     104shouldReject('crypto.subtle.importKey("spki", truncatedSpkiP384Key3, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
     105// Spki: Missmatched Curves
     106shouldReject('crypto.subtle.importKey("spki", spkiP256Key, { name: "ECDH", namedCurve: "P-384" }, extractable, [ ])');
     107shouldReject('crypto.subtle.importKey("spki", spkiP384Key, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     108// Spki: Corrupted Key Data
     109shouldReject('crypto.subtle.importKey("spki", corruptedSpkiP256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, [ ])');
     110// Pkcs8: Wrong usages
     111shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["encrypt"])');
     112shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["decrypt"])');
     113shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["sign"])');
     114shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["verify"])');
     115shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["wrapKey"])');
     116shouldReject('crypto.subtle.importKey("pkcs8", pkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["unwrapKey"])');
     117// Pkcs8: Truncated keys
     118shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key1, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     119shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key2, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     120shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key3, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     121shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key4, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     122shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key5, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     123shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key6, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     124shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key7, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     125shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key8, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     126shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key9, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     127shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key10, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     128shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P256Key11, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     129shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P384Key1, { name: "ECDH", namedCurve: "P-384" }, extractable, ["deriveKey"])');
     130shouldReject('crypto.subtle.importKey("pkcs8", truncatedPkcs8P384Key2, { name: "ECDH", namedCurve: "P-384" }, extractable, ["deriveKey"])');
     131// Pkcs8: Long key
     132shouldReject('crypto.subtle.importKey("pkcs8", longPkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
     133// Pkcs8: Corrupted Key Data
     134shouldReject('crypto.subtle.importKey("pkcs8", corruptedPkcs8P256Key, { name: "ECDH", namedCurve: "P-256" }, extractable, ["deriveKey"])');
    60135</script>
    61136
  • trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p256.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test exporting an EC key with malformed parameters");
     12description("Test exporting a P-256 ECDH public key with SPKI format.");
    1313
    1414jsTestIsAsync = true;
     
    2020var extractable = true;
    2121
     22var keyPair;
     23debug("Generating a key pair...");
    2224crypto.subtle.generateKey(algorithmKeyGen, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    23     privateKey = result.privateKey;
     25    keyPair = result;
     26    debug("Exporting the public key...");
     27    return crypto.subtle.exportKey("spki", keyPair.publicKey);
     28}).then(function(result) {
     29    publicKey = result;
    2430
    25     // Wrong key and format.
    26     return shouldReject('crypto.subtle.exportKey("raw", privateKey)');
    27 }).then(finishJSTest, finishJSTest);
     31    shouldBe("publicKey.byteLength", "91");
    2832
     33    finishJSTest();
     34});
    2935</script>
    3036
  • trunk/LayoutTests/crypto/subtle/ecdh-generate-export-key-spki-p384.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test exporting an EC key with malformed parameters");
     12description("Test exporting a P-384 ECDH public key with SPKI format.");
    1313
    1414jsTestIsAsync = true;
     
    1616var algorithmKeyGen = {
    1717    name: "ECDH",
    18     namedCurve: "P-256"
     18    namedCurve: "P-384"
    1919};
    2020var extractable = true;
    2121
     22var keyPair;
     23debug("Generating a key pair...");
    2224crypto.subtle.generateKey(algorithmKeyGen, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    23     privateKey = result.privateKey;
     25    keyPair = result;
     26    debug("Exporting the public key...");
     27    return crypto.subtle.exportKey("spki", keyPair.publicKey);
     28}).then(function(result) {
     29    publicKey = result;
    2430
    25     // Wrong key and format.
    26     return shouldReject('crypto.subtle.exportKey("raw", privateKey)');
    27 }).then(finishJSTest, finishJSTest);
     31    shouldBe("publicKey.byteLength", "120");
    2832
     33    finishJSTest();
     34});
    2935</script>
    3036
  • trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p256.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test exporting an EC key with malformed parameters");
     12description("Test exporting a P-256 ECDH private key with PKCS8 format.");
    1313
    1414jsTestIsAsync = true;
     
    2020var extractable = true;
    2121
     22var keyPair;
     23debug("Generating a key pair...");
    2224crypto.subtle.generateKey(algorithmKeyGen, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    23     privateKey = result.privateKey;
     25    keyPair = result;
     26    debug("Exporting the public key...");
     27    return crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
     28}).then(function(result) {
     29    privateKey = result;
    2430
    25     // Wrong key and format.
    26     return shouldReject('crypto.subtle.exportKey("raw", privateKey)');
    27 }).then(finishJSTest, finishJSTest);
     31    shouldBe("privateKey.byteLength", "138");
    2832
     33    finishJSTest();
     34});
    2935</script>
    3036
  • trunk/LayoutTests/crypto/subtle/ecdh-generate-export-pkcs8-p384.html

    r214073 r214074  
    1010
    1111<script>
    12 description("Test exporting an EC key with malformed parameters");
     12description("Test exporting a P-384 ECDH private key with PKCS8 format.");
    1313
    1414jsTestIsAsync = true;
     
    1616var algorithmKeyGen = {
    1717    name: "ECDH",
    18     namedCurve: "P-256"
     18    namedCurve: "P-384"
    1919};
    2020var extractable = true;
    2121
     22var keyPair;
     23debug("Generating a key pair...");
    2224crypto.subtle.generateKey(algorithmKeyGen, extractable, ["deriveKey", "deriveBits"]).then(function(result) {
    23     privateKey = result.privateKey;
     25    keyPair = result;
     26    debug("Exporting the public key...");
     27    return crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
     28}).then(function(result) {
     29    privateKey = result;
    2430
    25     // Wrong key and format.
    26     return shouldReject('crypto.subtle.exportKey("raw", privateKey)');
    27 }).then(finishJSTest, finishJSTest);
     31    shouldBe("privateKey.byteLength", "185");
    2832
     33    finishJSTest();
     34});
    2935</script>
    3036
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r213914 r214074  
     12017-03-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
     4        https://bugs.webkit.org/show_bug.cgi?id=169318
     5        <rdar://problem/31081956>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt:
     10        * web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt:
     11
    1122017-03-14  Youenn Fablet  <youenn@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/ec_importKey.worker-expected.txt

    r213560 r214074  
    2424FAIL 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
    2525FAIL 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
    26 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
     26PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, [])
    2727PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, true, [])
    28 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
     28PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey])
    2929PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveKey])
    30 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
     30PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
    3131PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
    32 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
     32PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits])
    3333PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits])
    34 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
     34PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, [])
    3535PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, false, [])
    36 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
     36PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey])
    3737PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveKey])
    38 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
     38PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
    3939PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
    40 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
     40PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits])
    4141PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits])
    42 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
     42PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, [])
    4343PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, true, [])
    44 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
     44PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey])
    4545PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveKey])
    46 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
     46PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
    4747PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
    48 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
     48PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits])
    4949PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits])
    50 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
     50PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, [])
    5151PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, false, [])
    52 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
     52PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey])
    5353PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveKey])
    54 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
     54PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
    5555PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
    56 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
     56PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits])
    5757PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits])
    58 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
     58FAIL 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
    5959FAIL 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
    60 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
     60FAIL 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
    6161FAIL 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
    62 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
     62FAIL 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
    6363FAIL 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
    64 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
     64FAIL 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
    6565FAIL 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
    66 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
     66FAIL 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
    6767FAIL 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
    68 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
     68FAIL 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
    6969FAIL 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
    70 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
     70FAIL 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
    7171FAIL 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
    72 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
     72FAIL 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
    7373FAIL 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
    7474
  • trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_ec_importKey-expected.txt

    r213560 r214074  
    2424FAIL 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
    2525FAIL 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
    26 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
     26PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, [])
    2727PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, true, [])
    28 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
     28PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey])
    2929PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveKey])
    30 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
     30PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
    3131PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
    32 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
     32PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits])
    3333PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [deriveBits])
    34 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
     34PASS Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, [])
    3535PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, false, [])
    36 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
     36PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey])
    3737PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveKey])
    38 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
     38PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
    3939PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
    40 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
     40PASS Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits])
    4141PASS Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [deriveBits])
    42 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
     42PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, [])
    4343PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, true, [])
    44 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
     44PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey])
    4545PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveKey])
    46 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
     46PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
    4747PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
    48 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
     48PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits])
    4949PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [deriveBits])
    50 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
     50PASS Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, [])
    5151PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, false, [])
    52 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
     52PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey])
    5353PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveKey])
    54 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
     54PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
    5555PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
    56 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
     56PASS Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits])
    5757PASS Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [deriveBits])
    58 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
     58FAIL 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
    5959FAIL 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
    60 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
     60FAIL 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
    6161FAIL 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
    62 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
     62FAIL 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
    6363FAIL 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
    64 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
     64FAIL 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
    6565FAIL 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
    66 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
     66FAIL 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
    6767FAIL 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
    68 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
     68FAIL 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
    6969FAIL 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
    70 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
     70FAIL 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
    7171FAIL 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
    72 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
     72FAIL 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
    7373FAIL 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
    7474
  • trunk/Source/WebCore/ChangeLog

    r214073 r214074  
     12017-03-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebCrypto] Support SPKI/PKCS8 for Elliptic Curve
     4        https://bugs.webkit.org/show_bug.cgi?id=169318
     5        <rdar://problem/31081956>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch adds SPKI/PKCS8 support for Elliptic Curve cryptos. We can now import/export
     10        SPKI/PKCS8 Elliptic Curve keys after this change. Few things to note: 1) This patch
     11        implements a loose DER encoder/decoder for hacking the underlying CommonCrypto library.
     12        2) It only permits id-ecPublicKey as the AlgorithmIdentifier following OpenSSL/Chrome(BoringSSL).
     13        3) It follows OpenSSL/Chrome(BoringSSL) to replace ECParameters in ECPrivateKey with custom
     14        tags. Hence, we should fully comply with OpenSSL/Chrome(BoringSSL).
     15
     16        Tests: crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html
     17               crypto/subtle/ec-import-jwk-key-export-spki-key.html
     18               crypto/subtle/ec-import-pkcs8-key-export-jwk-key.html
     19               crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html
     20               crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html
     21               crypto/subtle/ec-import-raw-key-export-spki-key.html
     22               crypto/subtle/ec-import-spki-key-export-jwk-key.html
     23               crypto/subtle/ec-import-spki-key-export-raw-key.html
     24               crypto/subtle/ec-import-spki-key-export-spki-key-p256.html
     25               crypto/subtle/ec-import-spki-key-export-spki-key-p384.html
     26               crypto/subtle/ecdh-generate-export-key-spki-p256.html
     27               crypto/subtle/ecdh-generate-export-key-spki-p384.html
     28               crypto/subtle/ecdh-generate-export-pkcs8-p256.html
     29               crypto/subtle/ecdh-generate-export-pkcs8-p384.html
     30               crypto/subtle/ecdh-import-pkcs8-key-p256.html
     31               crypto/subtle/ecdh-import-pkcs8-key-p384.html
     32               crypto/subtle/ecdh-import-spki-key-p256.html
     33               crypto/subtle/ecdh-import-spki-key-p384.html
     34               crypto/workers/subtle/ec-generate-export-pkcs8-key.html
     35               crypto/workers/subtle/ec-generate-export-spki-key.html
     36               crypto/workers/subtle/ec-import-pkcs8-key.html
     37               crypto/workers/subtle/ec-import-spki-key.html
     38
     39        * WebCore.xcodeproj/project.pbxproj:
     40        * crypto/algorithms/CryptoAlgorithmECDH.cpp:
     41        (WebCore::CryptoAlgorithmECDH::importKey):
     42        (WebCore::CryptoAlgorithmECDH::exportKey):
     43        * crypto/gnutls/CryptoKeyECGnuTLS.cpp:
     44        (WebCore::CryptoKeyEC::platformExportRaw):
     45        (WebCore::CryptoKeyEC::platformImportSpki):
     46        (WebCore::CryptoKeyEC::platformExportSpki):
     47        (WebCore::CryptoKeyEC::platformImportPkcs8):
     48        (WebCore::CryptoKeyEC::platformExportPkcs8):
     49        (WebCore::CryptoKeyEC::exportRaw): Deleted.
     50        * crypto/keys/CryptoKeyEC.cpp:
     51        (WebCore::CryptoKeyEC::importSpki):
     52        (WebCore::CryptoKeyEC::importPkcs8):
     53        (WebCore::CryptoKeyEC::exportRaw):
     54        (WebCore::CryptoKeyEC::exportSpki):
     55        (WebCore::CryptoKeyEC::exportPkcs8):
     56        * crypto/keys/CryptoKeyEC.h:
     57        * crypto/mac/CommonCryptoDERUtilities.h: Added.
     58        (WebCore::bytesUsedToEncodedLength):
     59        (WebCore::extraBytesNeededForEncodedLength):
     60        (WebCore::addEncodedASN1Length):
     61        (WebCore::bytesNeededForEncodedLength):
     62        * crypto/mac/CryptoKeyECMac.cpp:
     63        (WebCore::compareBytes):
     64        (WebCore::CryptoKeyEC::platformExportRaw):
     65        (WebCore::CryptoKeyEC::platformImportJWKPrivate):
     66        (WebCore::getOID):
     67        (WebCore::CryptoKeyEC::platformImportSpki):
     68        (WebCore::CryptoKeyEC::platformExportSpki):
     69        (WebCore::CryptoKeyEC::platformImportPkcs8):
     70        (WebCore::CryptoKeyEC::platformExportPkcs8):
     71        (WebCore::CryptoKeyEC::exportRaw): Deleted.
     72        Enlarge the robust of exportRaw.
     73        * crypto/mac/CryptoKeyRSAMac.cpp:
     74        (WebCore::CryptoKeyRSA::exportSpki):
     75        (WebCore::CryptoKeyRSA::exportPkcs8):
     76        Enhance the implementation.
     77        (WebCore::bytesUsedToEncodedLength): Deleted.
     78        (WebCore::bytesNeededForEncodedLength): Deleted.
     79        (WebCore::addEncodedASN1Length): Deleted.
     80        Moved to CommonCryptoDERUtilities.h.
     81
    1822017-03-16  Alex Christensen  <achristensen@webkit.org>
    283
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r214045 r214074  
    25832583                57E657EF1E71665400F941CA /* JSPbkdf2Params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57E657ED1E71665400F941CA /* JSPbkdf2Params.cpp */; };
    25842584                57E657F01E71665400F941CA /* JSPbkdf2Params.h in Headers */ = {isa = PBXBuildFile; fileRef = 57E657EE1E71665400F941CA /* JSPbkdf2Params.h */; };
     2585                57E664FC1E73703300765536 /* CommonCryptoDERUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */; };
    25852586                57EF5E601D20C83900171E60 /* TextCodecReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */; };
    25862587                57EF5E621D20D28700171E60 /* TextCodecReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */; };
     
    1025810259                57E657ED1E71665400F941CA /* JSPbkdf2Params.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPbkdf2Params.cpp; sourceTree = "<group>"; };
    1025910260                57E657EE1E71665400F941CA /* JSPbkdf2Params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPbkdf2Params.h; sourceTree = "<group>"; };
     10261                57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonCryptoDERUtilities.h; sourceTree = "<group>"; };
    1026010262                57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecReplacement.h; sourceTree = "<group>"; };
    1026110263                57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecReplacement.cpp; sourceTree = "<group>"; };
     
    2420124203                        isa = PBXGroup;
    2420224204                        children = (
     24205                                57E664FB1E73703300765536 /* CommonCryptoDERUtilities.h */,
    2420324206                                E125F843182425C900D84CD9 /* CryptoAlgorithmAES_CBCMac.cpp */,
    2420424207                                570440571E53851600356601 /* CryptoAlgorithmAES_CFBMac.cpp */,
     
    2706927072                                930908910AF7EDE40081DF01 /* HitTestRequest.h in Headers */,
    2707027073                                9307F1D80AF2D59000DBA31A /* HitTestResult.h in Headers */,
     27074                                57E664FC1E73703300765536 /* CommonCryptoDERUtilities.h in Headers */,
    2707127075                                BC3BC29C0E91AB0F00835588 /* HostWindow.h in Headers */,
    2707227076                                FD31609912B026F700C1A359 /* HRTFDatabase.h in Headers */,
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp

    r213628 r214074  
    154154        result = CryptoKeyEC::importRaw(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
    155155        break;
    156     default:
    157         exceptionCallback(NOT_SUPPORTED_ERR);
    158         return;
     156    case SubtleCrypto::KeyFormat::Spki:
     157        if (usages) {
     158            exceptionCallback(SYNTAX_ERR);
     159            return;
     160        }
     161        result = CryptoKeyEC::importSpki(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
     162        break;
     163    case SubtleCrypto::KeyFormat::Pkcs8:
     164        if (usages && (usages ^ CryptoKeyUsageDeriveKey) && (usages ^ CryptoKeyUsageDeriveBits) && (usages ^ (CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits))) {
     165            exceptionCallback(SYNTAX_ERR);
     166            return;
     167        }
     168        result = CryptoKeyEC::importPkcs8(ecParameters.identifier, ecParameters.namedCurve, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
     169        break;
    159170    }
    160171    if (!result) {
     
    177188    KeyData result;
    178189    switch (format) {
    179     case SubtleCrypto::KeyFormat::Jwk: {
     190    case SubtleCrypto::KeyFormat::Jwk:
    180191        result = ecKey.exportJwk();
    181192        break;
    182     }
    183193    case SubtleCrypto::KeyFormat::Raw: {
    184         if (ecKey.type() != CryptoKey::Type::Public) {
    185             exceptionCallback(INVALID_ACCESS_ERR);
    186             return;
    187         }
    188         result = ecKey.exportRaw();
    189         break;
    190     }
    191     default:
    192         exceptionCallback(NOT_SUPPORTED_ERR);
    193         return;
     194        auto raw = ecKey.exportRaw();
     195        if (raw.hasException()) {
     196            exceptionCallback(raw.releaseException().code());
     197            return;
     198        }
     199        result = raw.releaseReturnValue();
     200        break;
     201    }
     202    case SubtleCrypto::KeyFormat::Spki: {
     203        auto spki = ecKey.exportSpki();
     204        if (spki.hasException()) {
     205            exceptionCallback(spki.releaseException().code());
     206            return;
     207        }
     208        result = spki.releaseReturnValue();
     209        break;
     210    }
     211    case SubtleCrypto::KeyFormat::Pkcs8: {
     212        auto pkcs8 = ecKey.exportPkcs8();
     213        if (pkcs8.hasException()) {
     214            exceptionCallback(pkcs8.releaseException().code());
     215            return;
     216        }
     217        result = pkcs8.releaseReturnValue();
     218        break;
     219    }
    194220    }
    195221
  • trunk/Source/WebCore/crypto/gnutls/CryptoKeyECGnuTLS.cpp

    r213560 r214074  
    4949}
    5050
    51 Vector<uint8_t> CryptoKeyEC::exportRaw() const
     51Vector<uint8_t> CryptoKeyEC::platformExportRaw() const
    5252{
    5353    notImplemented();
     
    8989}
    9090
     91RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&&, bool, CryptoKeyUsageBitmap)
     92{
     93    notImplemented();
     94
     95    return nullptr;
     96}
     97
     98Vector<uint8_t> CryptoKeyEC::platformExportSpki() const
     99{
     100    notImplemented();
     101
     102    return { };
     103}
     104
     105RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&&, bool, CryptoKeyUsageBitmap)
     106{
     107    notImplemented();
     108
     109    return nullptr;
     110}
     111
     112Vector<uint8_t> CryptoKeyEC::platformExportPkcs8() const
     113{
     114    notImplemented();
     115
     116    return { };
     117}
     118
    91119} // namespace WebCore
    92120
  • trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp

    r213560 r214074  
    114114}
    115115
     116RefPtr<CryptoKeyEC> CryptoKeyEC::importSpki(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
     117{
     118    auto namedCurve = toNamedCurve(curve);
     119    if (!namedCurve)
     120        return nullptr;
     121
     122    return platformImportSpki(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
     123}
     124
     125RefPtr<CryptoKeyEC> CryptoKeyEC::importPkcs8(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
     126{
     127    auto namedCurve = toNamedCurve(curve);
     128    if (!namedCurve)
     129        return nullptr;
     130
     131    return platformImportPkcs8(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
     132}
     133
     134ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportRaw() const
     135{
     136    if (type() != CryptoKey::Type::Public)
     137        return Exception { INVALID_ACCESS_ERR };
     138
     139    return platformExportRaw();
     140}
     141
    116142JsonWebKey CryptoKeyEC::exportJwk() const
    117143{
     
    130156    platformAddFieldElements(result);
    131157    return result;
     158}
     159
     160ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportSpki() const
     161{
     162    if (type() != CryptoKey::Type::Public)
     163        return Exception { INVALID_ACCESS_ERR };
     164
     165    return platformExportSpki();
     166}
     167
     168ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportPkcs8() const
     169{
     170    if (type() != CryptoKey::Type::Private)
     171        return Exception { INVALID_ACCESS_ERR };
     172
     173    return platformExportPkcs8();
    132174}
    133175
  • trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h

    r213624 r214074  
    8080    static RefPtr<CryptoKeyEC> importRaw(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
    8181    static RefPtr<CryptoKeyEC> importJwk(CryptoAlgorithmIdentifier, const String& curve, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
     82    static RefPtr<CryptoKeyEC> importSpki(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
     83    static RefPtr<CryptoKeyEC> importPkcs8(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
    8284
    83     Vector<uint8_t> exportRaw() const;
     85    ExceptionOr<Vector<uint8_t>> exportRaw() const;
    8486    JsonWebKey exportJwk() const;
     87    ExceptionOr<Vector<uint8_t>> exportSpki() const;
     88    ExceptionOr<Vector<uint8_t>> exportPkcs8() const;
    8589
    8690    size_t keySizeInBits() const;
     
    100104    static RefPtr<CryptoKeyEC> platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap);
    101105    static RefPtr<CryptoKeyEC> platformImportJWKPrivate(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap);
     106    static RefPtr<CryptoKeyEC> platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
     107    static RefPtr<CryptoKeyEC> platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
     108    Vector<uint8_t> platformExportRaw() const;
    102109    void platformAddFieldElements(JsonWebKey&) const;
     110    Vector<uint8_t> platformExportSpki() const;
     111    Vector<uint8_t> platformExportPkcs8() const;
    103112
    104113    PlatformECKey m_platformKey;
  • trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp

    r213560 r214074  
    2929#if ENABLE(SUBTLE_CRYPTO)
    3030
     31#include "CommonCryptoDERUtilities.h"
    3132#include "CommonCryptoUtilities.h"
    3233#include "JsonWebKey.h"
     
    3536namespace WebCore {
    3637
    37 static unsigned char InitialOctet = 0x04; // Per Section 2.3.3 of http://www.secg.org/sec1-v2.pdf
     38static const unsigned char InitialOctetEC = 0x04; // Per Section 2.3.3 of http://www.secg.org/sec1-v2.pdf
     39// OID id-ecPublicKey 1.2.840.10045.2.1.
     40static const unsigned char IdEcPublicKey[] = {0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
     41// OID secp256r1 1.2.840.10045.3.1.7.
     42static constexpr unsigned char Secp256r1[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
     43// OID secp384r1 1.3.132.0.34
     44static constexpr unsigned char Secp384r1[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22};
     45// Version 1. Per https://tools.ietf.org/html/rfc5915#section-3
     46static const unsigned char PrivateKeyVersion[] = {0x02, 0x01, 0x01};
     47// Custom OpenSSL ECParameters Tags
     48static const size_t CustomTagSize = 2;
     49static constexpr unsigned char EcP256[] = {0xa1, 0x44};
     50static constexpr unsigned char EcP384[] = {0xa1, 0x64};
    3851
    3952// Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
     
    90103}
    91104
    92 Vector<uint8_t> CryptoKeyEC::exportRaw() const
     105Vector<uint8_t> CryptoKeyEC::platformExportRaw() const
    93106{
    94107    Vector<uint8_t> result(keySizeInBits() / 4 + 1); // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
     
    142155
    143156    // A hack to CommonCrypto since it doesn't provide API for creating private keys directly from x, y, d.
    144     // BinaryInput = InitialOctet + X + Y + D
     157    // BinaryInput = InitialOctetEC + X + Y + D
    145158    Vector<uint8_t> binaryInput;
    146     binaryInput.append(InitialOctet);
     159    binaryInput.append(InitialOctetEC);
    147160    binaryInput.appendVector(x);
    148161    binaryInput.appendVector(y);
     
    174187}
    175188
     189static size_t getOID(CryptoKeyEC::NamedCurve curve, const uint8_t*& oid)
     190{
     191    size_t oidSize;
     192    switch (curve) {
     193    case CryptoKeyEC::NamedCurve::P256:
     194        oid = Secp256r1;
     195        oidSize = sizeof(Secp256r1);
     196        break;
     197    case CryptoKeyEC::NamedCurve::P384:
     198        oid = Secp384r1;
     199        oidSize = sizeof(Secp384r1);
     200    }
     201    return oidSize;
     202}
     203
     204// Per https://www.ietf.org/rfc/rfc5280.txt
     205// SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }
     206// AlgorithmIdentifier  ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL }
     207// Per https://www.ietf.org/rfc/rfc5480.txt
     208// id-ecPublicKey OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
     209// secp256r1 OBJECT IDENTIFIER      ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 }
     210// secp384r1 OBJECT IDENTIFIER      ::= { iso(1) identified-organization(3) certicom(132) curve(0) 34 }
     211RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
     212{
     213    // The following is a loose check on the provided SPKI key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
     214    // Once the underlying crypto library is updated to accept SPKI EC Key, we should remove this hack.
     215    // <rdar://problem/30987628>
     216    size_t index = 1; // Read SEQUENCE
     217    if (keyData.size() < index + 1)
     218        return nullptr;
     219    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
     220    if (keyData.size() < index + 1)
     221        return nullptr;
     222    index += bytesUsedToEncodedLength(keyData[index]); // Read length
     223    if (keyData.size() < index + sizeof(IdEcPublicKey))
     224        return nullptr;
     225    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
     226        return nullptr;
     227    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
     228    const uint8_t* oid;
     229    size_t oidSize = getOID(curve, oid);
     230    if (keyData.size() < index + oidSize)
     231        return nullptr;
     232    if (memcmp(keyData.data() + index, oid, oidSize))
     233        return nullptr;
     234    index += oidSize + 1; // Read named curve OID, BIT STRING
     235    if (keyData.size() < index + 1)
     236        return nullptr;
     237    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet
     238
     239    if (!doesUncompressedPointMatchNamedCurve(curve, keyData.size() - index))
     240        return nullptr;
     241
     242    CCECCryptorRef ccPublicKey;
     243    if (CCECCryptorImportKey(kCCImportKeyBinary, keyData.data() + index, keyData.size() - index, ccECKeyPublic, &ccPublicKey))
     244        return nullptr;
     245
     246    return create(identifier, curve, CryptoKeyType::Public, ccPublicKey, extractable, usages);
     247}
     248
     249Vector<uint8_t> CryptoKeyEC::platformExportSpki() const
     250{
     251    Vector<uint8_t> keyBytes(keySizeInBits() / 4 + 1); // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
     252    size_t keySize = keyBytes.size();
     253    CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &keySize, ccECKeyPublic, m_platformKey);
     254
     255    // The following addes SPKI header to a raw EC public key.
     256    // Once the underlying crypto library is updated to output SPKI EC Key, we should remove this hack.
     257    // <rdar://problem/30987628>
     258    const uint8_t* oid;
     259    size_t oidSize = getOID(namedCurve(), oid);
     260
     261    // SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1 + BIT STRING + length(?) + InitialOctet + Key size
     262    size_t totalSize = sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(keySize + 1) + keySize + 4;
     263
     264    Vector<uint8_t> result;
     265    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
     266    result.append(SequenceMark);
     267    addEncodedASN1Length(result, totalSize);
     268    result.append(SequenceMark);
     269    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
     270    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
     271    result.append(oid, oidSize);
     272    result.append(BitStringMark);
     273    addEncodedASN1Length(result, keySize + 1);
     274    result.append(InitialOctet);
     275    result.append(keyBytes.data(), keyBytes.size());
     276
     277    return result;
     278}
     279
     280// Per https://www.ietf.org/rfc/rfc5208.txt
     281// PrivateKeyInfo ::= SEQUENCE { version INTEGER, privateKeyAlgorithm AlgorithmIdentifier, privateKey OCTET STRING { ECPrivateKey } }
     282// Per https://www.ietf.org/rfc/rfc5915.txt
     283// ECPrivateKey ::= SEQUENCE { version INTEGER { ecPrivkeyVer1(1) }, privateKey OCTET STRING, parameters CustomECParameters, publicKey BIT STRING }
     284// OpenSSL uses custom ECParameters. We follow OpenSSL as a compatibility concern.
     285RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
     286{
     287    // The following is a loose check on the provided PKCS8 key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
     288    // Once the underlying crypto library is updated to accept PKCS8 EC Key, we should remove this hack.
     289    // <rdar://problem/30987628>
     290    size_t index = 1; // Read SEQUENCE
     291    if (keyData.size() < index + 1)
     292        return nullptr;
     293    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, SEQUENCE
     294    if (keyData.size() < index + 1)
     295        return nullptr;
     296    index += bytesUsedToEncodedLength(keyData[index]); // Read length
     297    if (keyData.size() < index + sizeof(IdEcPublicKey))
     298        return nullptr;
     299    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
     300        return nullptr;
     301    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
     302    const uint8_t* oid;
     303    size_t oidSize = getOID(curve, oid);
     304    if (keyData.size() < index + oidSize)
     305        return nullptr;
     306    if (memcmp(keyData.data() + index, oid, oidSize))
     307        return nullptr;
     308    index += oidSize + 1; // Read named curve OID, OCTET STRING
     309    if (keyData.size() < index + 1)
     310        return nullptr;
     311    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
     312    if (keyData.size() < index + 1)
     313        return nullptr;
     314    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, OCTET STRING
     315    if (keyData.size() < index + 1)
     316        return nullptr;
     317    index += bytesUsedToEncodedLength(keyData[index]); // Read length
     318
     319    if (keyData.size() < index + getKeySizeFromNamedCurve(curve) / 8)
     320        return nullptr;
     321    size_t privateKeyPos = index;
     322    index += getKeySizeFromNamedCurve(curve) / 8 + CustomTagSize + 1; // Read privateKey, CustomECParameters, BIT STRING
     323    if (keyData.size() < index + 1)
     324        return nullptr;
     325    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet
     326
     327    // KeyBinary = uncompressed point + private key
     328    Vector<uint8_t> keyBinary;
     329    keyBinary.append(keyData.data() + index, keyData.size() - index);
     330    if (!doesUncompressedPointMatchNamedCurve(curve, keyBinary.size()))
     331        return nullptr;
     332    keyBinary.append(keyData.data() + privateKeyPos, getKeySizeFromNamedCurve(curve) / 8);
     333
     334    CCECCryptorRef ccPrivateKey;
     335    if (CCECCryptorImportKey(kCCImportKeyBinary, keyBinary.data(), keyBinary.size(), ccECKeyPrivate, &ccPrivateKey))
     336        return nullptr;
     337
     338    return create(identifier, curve, CryptoKeyType::Private, ccPrivateKey, extractable, usages);
     339}
     340
     341Vector<uint8_t> CryptoKeyEC::platformExportPkcs8() const
     342{
     343    size_t keySizeInBytes = keySizeInBits() / 8;
     344    Vector<uint8_t> keyBytes(keySizeInBytes * 3 + 1); // 04 + X + Y + private key
     345    size_t keySize = keyBytes.size();
     346    CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &keySize, ccECKeyPrivate, m_platformKey);
     347
     348    // The following addes PKCS8 header to a raw EC private key.
     349    // Once the underlying crypto library is updated to output PKCS8 EC Key, we should remove this hack.
     350    // <rdar://problem/30987628>
     351    const uint8_t* oid;
     352    size_t oidSize = getOID(namedCurve(), oid);
     353    const uint8_t* customTag;
     354    switch (namedCurve()) {
     355    case NamedCurve::P256:
     356        customTag = EcP256;
     357        break;
     358    case NamedCurve::P384:
     359        customTag = EcP384;
     360    }
     361
     362    // InitialOctet + 04 + X + Y
     363    size_t publicKeySize = keySizeInBytes * 2 + 2;
     364    // VERSION + OCTET STRING + length(1) + private key + CustomECParameters(2) + BIT STRING + length(?) + publicKeySize
     365    size_t ecPrivateKeySize = sizeof(Version) + keySizeInBytes + CustomTagSize + bytesNeededForEncodedLength(publicKeySize) + publicKeySize + 3;
     366    // SEQUENCE + length(?) + ecPrivateKeySize
     367    size_t privateKeySize = bytesNeededForEncodedLength(ecPrivateKeySize) + ecPrivateKeySize + 1;
     368    // VERSION + SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1 + OCTET STRING + length(?) + privateKeySize
     369    size_t totalSize = sizeof(Version) + sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(privateKeySize) + privateKeySize + 3;
     370
     371    Vector<uint8_t> result;
     372    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
     373    result.append(SequenceMark);
     374    addEncodedASN1Length(result, totalSize);
     375    result.append(Version, sizeof(Version));
     376    result.append(SequenceMark);
     377    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
     378    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
     379    result.append(oid, oidSize);
     380    result.append(OctetStringMark);
     381    addEncodedASN1Length(result, privateKeySize);
     382    result.append(SequenceMark);
     383    addEncodedASN1Length(result, ecPrivateKeySize);
     384    result.append(PrivateKeyVersion, sizeof(PrivateKeyVersion));
     385    result.append(OctetStringMark);
     386    addEncodedASN1Length(result, keySizeInBytes);
     387    result.append(keyBytes.data() + publicKeySize - 1, keySizeInBytes);
     388    result.append(customTag, CustomTagSize);
     389    result.append(BitStringMark);
     390    addEncodedASN1Length(result, publicKeySize);
     391    result.append(InitialOctet);
     392    result.append(keyBytes.data(), publicKeySize - 1);
     393
     394    return result;
     395}
     396
    176397} // namespace WebCore
    177398
  • trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp

    r212465 r214074  
    2929#if ENABLE(SUBTLE_CRYPTO)
    3030
     31#include "CommonCryptoDERUtilities.h"
    3132#include "CommonCryptoUtilities.h"
    3233#include "CryptoAlgorithmRegistry.h"
     
    4041
    4142// OID rsaEncryption: 1.2.840.113549.1.1.1. Per https://tools.ietf.org/html/rfc3279#section-2.3.1
    42 static unsigned char RSAOIDHeader[] = {0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00};
    43 // Version 0. Per https://tools.ietf.org/html/rfc5208#section-5
    44 static unsigned char Version[] = {0x02, 0x01, 0x00};
    45 
    46 // Per X.690 08/2015: https://www.itu.int/rec/T-REC-X.680-X.693/en
    47 static unsigned char BitStringMark = 0x03;
    48 static unsigned char OctetStringMark = 0x04;
    49 static unsigned char SequenceMark = 0x30;
    50 
    51 static unsigned char InitialOctet = 0x00;
     43static const unsigned char RSAOIDHeader[] = {0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00};
    5244
    5345// FIXME: We should get rid of magic number 16384. It assumes that the length of provided key will not exceed 16KB.
     
    254246}
    255247
    256 static size_t bytesUsedToEncodedLength(uint8_t octet)
    257 {
    258     if (octet < 128)
    259         return 1;
    260     return octet - 127;
    261 }
    262 
    263 static size_t bytesNeededForEncodedLength(size_t length)
    264 {
    265     if (!length)
    266         return 0;
    267     size_t result = 1;
    268     while (result < sizeof(length) && length >= (1 << (result * 8)))
    269         result += 1;
    270     return result;
    271 }
    272 
    273 static void addEncodedASN1Length(Vector<uint8_t>& in, size_t length)
    274 {
    275     if (length < 128) {
    276         in.append(length);
    277         return;
    278     }
    279 
    280     size_t extraBytes = bytesNeededForEncodedLength(length);
    281     in.append(128 + extraBytes);
    282 
    283     size_t lastPosition = in.size() + extraBytes - 1;
    284     in.grow(in.size() + extraBytes);
    285     for (size_t i = 0; i < extraBytes; i++) {
    286         in[lastPosition - i] = length & 0xff;
    287         length = length >> 8;
    288     }
    289 }
    290 
    291248// FIXME: We should use WorkQueue here instead of dispatch_async once WebKitSubtleCrypto is deprecated.
    292249// https://bugs.webkit.org/show_bug.cgi?id=164943
     
    374331
    375332    // RSAOIDHeader + BitStringMark + Length + keySize + InitialOctet
    376     size_t totalSize = sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize + 1) + keySize + 3;
     333    size_t totalSize = sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize + 1) + keySize + 2;
    377334
    378335    // Per https://tools.ietf.org/html/rfc5280#section-4.1. subjectPublicKeyInfo.
    379336    Vector<uint8_t> result;
     337    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
    380338    result.append(SequenceMark);
    381339    addEncodedASN1Length(result, totalSize);
     
    432390
    433391    // Version + RSAOIDHeader + OctetStringMark + Length + keySize
    434     size_t totalSize = sizeof(Version) + sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize) + keySize + 2;
     392    size_t totalSize = sizeof(Version) + sizeof(RSAOIDHeader) + bytesNeededForEncodedLength(keySize) + keySize + 1;
    435393
    436394    // Per https://tools.ietf.org/html/rfc5208#section-5. PrivateKeyInfo.
    437395    Vector<uint8_t> result;
     396    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
    438397    result.append(SequenceMark);
    439398    addEncodedASN1Length(result, totalSize);
Note: See TracChangeset for help on using the changeset viewer.