+2017-03-17 Jiewen Tan <jiewen_tan@apple.com>
+
+ [WebCrypto] Make sure all CryptoKey classes are structured clonable
+ https://bugs.webkit.org/show_bug.cgi?id=169232
+ <rdar://problem/31106660>
+
+ Reviewed by Brent Fulgham.
+
+ * crypto/workers/subtle/aes-postMessage-worker-expected.txt:
+ * crypto/workers/subtle/aes-postMessage-worker.html:
+ * crypto/workers/subtle/ec-postMessage-worker-expected.txt: Added.
+ * crypto/workers/subtle/ec-postMessage-worker.html: Added.
+ * crypto/workers/subtle/hmac-postMessage-worker-expected.txt:
+ * crypto/workers/subtle/hmac-postMessage-worker.html:
+ * crypto/workers/subtle/raw-postMessage-worker-expected.txt: Added.
+ * crypto/workers/subtle/raw-postMessage-worker.html: Added.
+ * crypto/workers/subtle/resources/ec-postMessage-worker.js: Added.
+ * crypto/workers/subtle/resources/raw-postMessage-worker.js: Added.
+ * crypto/workers/subtle/resources/rsa-postMessage-worker.js:
+ * crypto/workers/subtle/rsa-postMessage-worker-expected.txt:
+ * crypto/workers/subtle/rsa-postMessage-worker.html:
+
2017-03-17 Zalan Bujtas <zalan@apple.com>
Fix the flow thread state on the descendants of out of flow positioned replaced elements.
PASS key.algorithm.name is 'AES-CBC'
PASS key.algorithm.length is 128
PASS key.usages is ['decrypt', 'encrypt']
+PASS bytesToASCIIString(exportedKey) is rawKeyAscii
PASS successfullyParsed is true
TEST COMPLETE
description("Test sending aes crypto keys via postMessage to a worker.");
jsTestIsAsync = true;
+var rawKeyAscii = "16 bytes of key!";
+var rawKey = asciiToUint8Array(rawKeyAscii);
-crypto.subtle.importKey("raw", asciiToUint8Array("16 bytes of key!"), {name: "aes-cbc", length: 128}, true, ["encrypt", "decrypt"]).then(function(localKey) {
+crypto.subtle.importKey("raw", rawKey, {name: "aes-cbc", length: 128}, true, ["encrypt", "decrypt"]).then(function(localKey) {
var worker = new Worker("resources/aes-postMessage-worker.js");
worker.onmessage = function(evt) {
if (!evt.data.result) {
shouldBe("key.algorithm.name", "'AES-CBC'");
shouldBe("key.algorithm.length", "128");
shouldBe("key.usages", "['decrypt', 'encrypt']");
+
+ crypto.subtle.exportKey("raw", key).then(function(result) {
+ exportedKey = result;
+
+ shouldBe("bytesToASCIIString(exportedKey)", "rawKeyAscii");
+
+ finishJSTest();
+ });
}
- finishJSTest();
}
worker.postMessage(localKey);
});
--- /dev/null
+Test sending ec crypto keys via postMessage to a worker.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS All checks passed in worker for private key
+PASS privateKey.type is 'private'
+PASS privateKey.extractable is true
+PASS privateKey.algorithm.name is 'ECDH'
+PASS privateKey.algorithm.namedCurve is 'P-256'
+PASS privateKey.usages is ['deriveBits']
+PASS exportedKey.x is privateKeyJSON.x
+PASS exportedKey.y is privateKeyJSON.y
+PASS exportedKey.d is privateKeyJSON.d
+PASS All checks passed in worker for public key
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'ECDH'
+PASS publicKey.algorithm.namedCurve is 'P-256'
+PASS publicKey.usages is [ ]
+PASS exportedKey.x is publicKeyJSON.x
+PASS exportedKey.y is publicKeyJSON.y
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/common.js"></script>
+</head>
+<body>
+<script>
+
+description("Test sending ec crypto keys via postMessage to a worker.");
+
+jsTestIsAsync = true;
+
+var publicKeyJSON = {
+ kty: "EC",
+ use: "enc",
+ ext: true,
+ crv: "P-256",
+ x: "1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA",
+ y: "9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI",
+};
+
+var privateKeyJSON = {
+ kty: "EC",
+ ext: true,
+ key_ops: ["deriveBits", "deriveKey"],
+ crv: "P-256",
+ x: "1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA",
+ y: "9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI",
+ d: "ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg",
+};
+
+var count = 0;
+var worker = new Worker("resources/ec-postMessage-worker.js");
+worker.onmessage = function(evt) {
+ if (!evt.data.result) {
+ testFailed("Check failed in worker: " + evt.data.message);
+ finishJSTest();
+ } else {
+ if (publicKey = evt.data.publicKey) {
+ testPassed("All checks passed in worker for public key");
+ shouldBe("publicKey.type", "'public'");
+ shouldBe("publicKey.extractable", "true");
+ shouldBe("publicKey.algorithm.name", "'ECDH'");
+ shouldBe("publicKey.algorithm.namedCurve", "'P-256'");
+ shouldBe("publicKey.usages", "[ ]");
+
+ crypto.subtle.exportKey("jwk", publicKey).then(function(result) {
+ count = count + 1;
+ exportedKey = result;
+
+ shouldBe("exportedKey.x", "publicKeyJSON.x");
+ shouldBe("exportedKey.y", "publicKeyJSON.y");
+
+ if (count == 2)
+ finishJSTest();
+ });
+ } else if (privateKey = evt.data.privateKey) {
+ testPassed("All checks passed in worker for private key");
+ shouldBe("privateKey.type", "'private'");
+ shouldBe("privateKey.extractable", "true");
+ shouldBe("privateKey.algorithm.name", "'ECDH'");
+ shouldBe("privateKey.algorithm.namedCurve", "'P-256'");
+ shouldBe("privateKey.usages", "['deriveBits']");
+
+ crypto.subtle.exportKey("jwk", privateKey).then(function(result) {
+ count = count + 1;
+ exportedKey = result;
+
+ shouldBe("exportedKey.x", "privateKeyJSON.x");
+ shouldBe("exportedKey.y", "privateKeyJSON.y");
+ shouldBe("exportedKey.d", "privateKeyJSON.d");
+
+ if (count == 2)
+ finishJSTest();
+ });
+ }
+ }
+}
+
+crypto.subtle.importKey("jwk", publicKeyJSON, { name:"ECDH", namedCurve:"P-256" }, true, [ ]).then(function(localPublicKey) {
+ worker.postMessage({ publicKey: localPublicKey });
+});
+crypto.subtle.importKey("jwk", privateKeyJSON, { name:"ECDH", namedCurve:"P-256" }, true, ['deriveBits']).then(function(localPrivateKey) {
+ worker.postMessage({ privateKey: localPrivateKey });
+});
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
PASS key.algorithm.length is 128
PASS key.algorithm.hash.name is 'SHA-1'
PASS key.usages is ["sign", "verify"]
+PASS bytesToASCIIString(exportedKey) is rawKeyAscii
PASS successfullyParsed is true
TEST COMPLETE
description("Test sending hmac crypto keys via postMessage to a worker.");
jsTestIsAsync = true;
+var rawKeyAscii = "16 bytes of key!";
+var rawKey = asciiToUint8Array(rawKeyAscii);
-crypto.subtle.importKey("raw", asciiToUint8Array("16 bytes of key!"), {name: 'hmac', hash: {name: 'sha-1'}}, true, ['sign', 'verify']).then(function(localKey) {
+crypto.subtle.importKey("raw", rawKey, {name: 'hmac', hash: {name: 'sha-1'}}, true, ['sign', 'verify']).then(function(localKey) {
var worker = new Worker("resources/hmac-postMessage-worker.js");
worker.onmessage = function(evt) {
if (!evt.data.result) {
shouldBe("key.algorithm.length", "128");
shouldBe("key.algorithm.hash.name", "'SHA-1'");
shouldBe("key.usages", '["sign", "verify"]');
+
+ crypto.subtle.exportKey("raw", key).then(function(result) {
+ exportedKey = result;
+
+ shouldBe("bytesToASCIIString(exportedKey)", "rawKeyAscii");
+
+ finishJSTest();
+ });
}
- finishJSTest();
}
worker.postMessage(localKey);
});
--- /dev/null
+Test sending raw crypto keys via postMessage to a worker.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS All checks passed in worker
+PASS key.type is 'secret'
+PASS key.extractable is false
+PASS key.algorithm.name is 'PBKDF2'
+PASS key.usages is ['deriveBits', 'deriveKey']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/common.js"></script>
+</head>
+<body>
+<script>
+
+description("Test sending raw crypto keys via postMessage to a worker.");
+
+jsTestIsAsync = true;
+
+crypto.subtle.importKey("raw", asciiToUint8Array("16 bytes of key!"), "PBKDF2", false, ["deriveBits", "deriveKey"]).then(function(localKey) {
+ var worker = new Worker("resources/raw-postMessage-worker.js");
+ worker.onmessage = function(evt) {
+ if (!evt.data.result) {
+ testFailed("Check failed in worker: " + evt.data.message);
+ } else {
+ testPassed("All checks passed in worker");
+ key = evt.data.key;
+ shouldBe("key.type", "'secret'");
+ shouldBe("key.extractable", "false");
+ shouldBe("key.algorithm.name", "'PBKDF2'");
+ shouldBe("key.usages", "['deriveBits', 'deriveKey']");
+ }
+ finishJSTest();
+ }
+ worker.postMessage(localKey);
+});
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+importScripts("../../../resources/common.js");
+
+onmessage = function(evt)
+{
+ if (publicKey = evt.data.publicKey) {
+ if (publicKey.type != 'public')
+ postMessage({ result:false, message:'publicKey.type should be "public"' });
+ else if (!publicKey.extractable)
+ postMessage({ result:false, message:'publicKey.extractable should be true' });
+ else if (publicKey.algorithm.name != "ECDH")
+ postMessage({ result:false, message:'publicKey.algorithm.name should be "ECDH"' });
+ else if (publicKey.algorithm.namedCurve != "P-256")
+ postMessage({ result:false, message:'publicKey.algorithm.namedCurve should be P-256' });
+ else if (publicKey.usages.toString() != "")
+ postMessage({ result:false, message:'publicKey.usages should be [ ]' });
+ else
+ postMessage({ result:true, publicKey:publicKey });
+ } else if (privateKey = evt.data.privateKey) {
+ if (privateKey.type != 'private')
+ postMessage({ result:false, message:'privateKey.type should be "private"' });
+ else if (!privateKey.extractable)
+ postMessage({ result:false, message:'privateKey.extractable should be true' });
+ else if (privateKey.algorithm.name != "ECDH")
+ postMessage({ result:false, message:'publicKey.algorithm.name should be "ECDH"' });
+ else if (privateKey.algorithm.namedCurve != "P-256")
+ postMessage({ result:false, message:'publicKey.algorithm.namedCurve should be P-256' });
+ else if (privateKey.usages.toString() != "deriveBits")
+ postMessage({ result:false, message:'privateKey.usages should be ["deriveBits"]' });
+ else
+ postMessage({ result:true, privateKey:privateKey });
+ } else {
+ postMessage({ result:false, message:'key is ' + key });
+ }
+}
--- /dev/null
+onmessage = function(evt)
+{
+ var key = evt.data;
+ if (!key)
+ postMessage({ result:false, message:'key is ' + key });
+ if (key.type != 'secret')
+ postMessage({ result:false, message:'key.type should be "secret"' });
+ else if (key.extractable)
+ postMessage({ result:false, message:'key.extractable should be false' });
+ else if (key.algorithm.name != "PBKDF2")
+ postMessage({ result:false, message:'key.algorithm.name should be "PBKDF2"' });
+ else if (key.usages.toString() != "deriveBits,deriveKey")
+ postMessage({ result:false, message:'key.usages should be ["deriveBits", "deriveKey"]' });
+ else
+ postMessage({ result:true, key:key });
+}
} else if (privateKey = evt.data.privateKey) {
if (privateKey.type != 'private')
postMessage({ result:false, message:'privateKey.type should be "private"' });
- else if (privateKey.extractable)
- postMessage({ result:false, message:'privateKey.extractable should be false' });
+ else if (!privateKey.extractable)
+ postMessage({ result:false, message:'privateKey.extractable should be true' });
else if (privateKey.algorithm.name != "RSAES-PKCS1-v1_5")
postMessage({ result:false, message:'privateKey.algorithm.name should be "RSAES-PKCS1-v1_5"' });
else if (privateKey.algorithm.modulusLength != 2048)
PASS All checks passed in worker for private key
PASS privateKey.type is 'private'
-PASS privateKey.extractable is false
+PASS privateKey.extractable is true
PASS privateKey.algorithm.name is 'RSAES-PKCS1-v1_5'
PASS privateKey.algorithm.modulusLength is 2048
PASS bytesToHexString(privateKey.algorithm.publicExponent) is '010001'
PASS privateKey.algorithm.hash is undefined.
PASS privateKey.usages is ['decrypt']
+PASS exportedKey.n is privateKeyJSON.n
+PASS exportedKey.e is privateKeyJSON.e
+PASS exportedKey.d is privateKeyJSON.d
+PASS exportedKey.p is privateKeyJSON.p
+PASS exportedKey.q is privateKeyJSON.q
+PASS exportedKey.dp is privateKeyJSON.dp
+PASS exportedKey.dq is privateKeyJSON.dq
+PASS exportedKey.qi is privateKeyJSON.qi
PASS All checks passed in worker for public key
PASS publicKey.type is 'public'
PASS publicKey.extractable is true
PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
PASS publicKey.algorithm.hash is undefined.
PASS publicKey.usages is ['encrypt']
+PASS exportedKey.n is publicKeyJSON.n
+PASS exportedKey.e is publicKeyJSON.e
PASS successfullyParsed is true
TEST COMPLETE
shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
shouldBeUndefined("publicKey.algorithm.hash");
shouldBe("publicKey.usages", "['encrypt']");
+
+ crypto.subtle.exportKey("jwk", publicKey).then(function(result) {
+ count = count + 1;
+ exportedKey = result;
+
+ shouldBe("exportedKey.n", "publicKeyJSON.n");
+ shouldBe("exportedKey.e", "publicKeyJSON.e");
+
+ if (count == 2)
+ finishJSTest();
+ });
} else if (privateKey = evt.data.privateKey) {
testPassed("All checks passed in worker for private key");
shouldBe("privateKey.type", "'private'");
- shouldBe("privateKey.extractable", "false");
+ shouldBe("privateKey.extractable", "true");
shouldBe("privateKey.algorithm.name", "'RSAES-PKCS1-v1_5'");
shouldBe("privateKey.algorithm.modulusLength", "2048");
shouldBe("bytesToHexString(privateKey.algorithm.publicExponent)", "'010001'");
shouldBeUndefined("privateKey.algorithm.hash");
shouldBe("privateKey.usages", "['decrypt']");
+
+ crypto.subtle.exportKey("jwk", privateKey).then(function(result) {
+ count = count + 1;
+ exportedKey = result;
+
+ shouldBe("exportedKey.n", "privateKeyJSON.n");
+ shouldBe("exportedKey.e", "privateKeyJSON.e");
+ shouldBe("exportedKey.d", "privateKeyJSON.d");
+ shouldBe("exportedKey.p", "privateKeyJSON.p");
+ shouldBe("exportedKey.q", "privateKeyJSON.q");
+ shouldBe("exportedKey.dp", "privateKeyJSON.dp");
+ shouldBe("exportedKey.dq", "privateKeyJSON.dq");
+ shouldBe("exportedKey.qi", "privateKeyJSON.qi");
+
+ if (count == 2)
+ finishJSTest();
+ });
}
- count = count + 1;
}
-
- if (count == 2)
- finishJSTest();
}
crypto.subtle.importKey("jwk", publicKeyJSON, algorithmKeyGen, true, ['encrypt']).then(function(localPublicKey) {
worker.postMessage({ publicKey: localPublicKey });
});
-crypto.subtle.importKey("jwk", privateKeyJSON, algorithmKeyGen, false, ['decrypt']).then(function(localPrivateKey) {
+crypto.subtle.importKey("jwk", privateKeyJSON, algorithmKeyGen, true, ['decrypt']).then(function(localPrivateKey) {
worker.postMessage({ privateKey: localPrivateKey });
});
</script>
+2017-03-17 Jiewen Tan <jiewen_tan@apple.com>
+
+ [WebCrypto] Make sure all CryptoKey classes are structured clonable
+ https://bugs.webkit.org/show_bug.cgi?id=169232
+ <rdar://problem/31106660>
+
+ Reviewed by Brent Fulgham.
+
+ This patch does the following few things: 1) It makes CryptoKeyEC and CryptoKeyRaw
+ structured clonable; 2) It makes CryptoKeyAES and CryptoKeyHMAC to use a move importer
+ during deserialization; 3) It adds some tests to make sure CryptoKeyAES, CryptoKeyHMAC
+ and CryptoKeyRSA won't lose their internal data during serialization/deserialization.
+
+ Tests: crypto/workers/subtle/ec-postMessage-worker.html
+ crypto/workers/subtle/raw-postMessage-worker.html
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::write):
+ (WebCore::CloneDeserializer::readHMACKey):
+ (WebCore::CloneDeserializer::readAESKey):
+ (WebCore::CloneDeserializer::readECKey):
+ (WebCore::CloneDeserializer::readRawKey):
+ (WebCore::CloneDeserializer::readCryptoKey):
+ * crypto/keys/CryptoKeyEC.cpp:
+ (WebCore::CryptoKeyEC::namedCurveString):
+ (WebCore::CryptoKeyEC::isValidECAlgorithm):
+ * crypto/keys/CryptoKeyEC.h:
+
2017-03-17 Michael Saboff <msaboff@apple.com>
Use USE_INTERNAL_SDK to compute ENABLE_FAST_JIT_PERMISSIONS instead of HAVE_INTERNAL_SDK
#include "CryptoKeyAES.h"
#include "CryptoKeyDataOctetSequence.h"
#include "CryptoKeyDataRSAComponents.h"
+#include "CryptoKeyEC.h"
#include "CryptoKeyHMAC.h"
#include "CryptoKeyRSA.h"
+#include "CryptoKeyRaw.h"
#include "File.h"
#include "FileList.h"
#include "IDBValue.h"
enum class CryptoKeyClassSubtag {
HMAC = 0,
AES = 1,
- RSA = 2
+ RSA = 2,
+ EC = 3,
+ Raw = 4,
};
-const uint8_t cryptoKeyClassSubtagMaximumValue = 2;
+const uint8_t cryptoKeyClassSubtagMaximumValue = 4;
enum class CryptoKeyAsymmetricTypeSubtag {
Public = 0,
*
* PrimeInfo :-
* <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}> <crtCoefficientSize:uint32_t> <crtCoefficient:byte{crtCoefficientSize}>
+ *
+ * CryptoKeyEC :-
+ * CryptoAlgorithmIdentifierTag <namedCurve:StringData> CryptoKeyAsymmetricTypeSubtag <keySize:uint32_t> <keyData:byte{keySize}>
+ *
+ * CryptoKeyRaw :-
+ * CryptoAlgorithmIdentifierTag <keySize:uint32_t> <keyData:byte{keySize}>
*/
using DeserializationResult = std::pair<JSC::JSValue, SerializationReturnCode>;
write(downcast<CryptoKeyAES>(*key).key());
break;
case CryptoKeyClass::EC:
- // A dummy implementation for now.
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169232
+ write(CryptoKeyClassSubtag::EC);
+ write(key->algorithmIdentifier());
+ write(downcast<CryptoKeyEC>(*key).namedCurveString());
+ switch (key->type()) {
+ case CryptoKey::Type::Public: {
+ write(CryptoKeyAsymmetricTypeSubtag::Public);
+ auto result = downcast<CryptoKeyEC>(*key).exportRaw();
+ ASSERT(!result.hasException());
+ write(result.releaseReturnValue());
+ break;
+ }
+ case CryptoKey::Type::Private: {
+ write(CryptoKeyAsymmetricTypeSubtag::Private);
+ // Use the standard complied method is not very efficient, but simple/reliable.
+ auto result = downcast<CryptoKeyEC>(*key).exportPkcs8();
+ ASSERT(!result.hasException());
+ write(result.releaseReturnValue());
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
break;
case CryptoKeyClass::Raw:
- // A dummy implementation for now.
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169232
+ write(CryptoKeyClassSubtag::Raw);
+ write(key->algorithmIdentifier());
+ write(downcast<CryptoKeyRaw>(*key).key());
break;
case CryptoKeyClass::RSA:
write(CryptoKeyClassSubtag::RSA);
CryptoAlgorithmIdentifier hash;
if (!read(hash))
return false;
- result = CryptoKeyHMAC::create(keyData, hash, extractable, usages);
+ result = CryptoKeyHMAC::importRaw(0, hash, WTFMove(keyData), extractable, usages);
return true;
}
Vector<uint8_t> keyData;
if (!read(keyData))
return false;
- result = CryptoKeyAES::create(algorithm, keyData, extractable, usages);
+ result = CryptoKeyAES::importRaw(algorithm, WTFMove(keyData), extractable, usages);
return true;
}
return true;
}
+ bool readECKey(bool extractable, CryptoKeyUsageBitmap usages, RefPtr<CryptoKey>& result)
+ {
+ CryptoAlgorithmIdentifier algorithm;
+ if (!read(algorithm))
+ return false;
+ if (!CryptoKeyEC::isValidECAlgorithm(algorithm))
+ return false;
+ CachedStringRef curve;
+ if (!readStringData(curve))
+ return false;
+ CryptoKeyAsymmetricTypeSubtag type;
+ if (!read(type))
+ return false;
+ Vector<uint8_t> keyData;
+ if (!read(keyData))
+ return false;
+
+ switch (type) {
+ case CryptoKeyAsymmetricTypeSubtag::Public:
+ result = CryptoKeyEC::importRaw(algorithm, curve->string(), WTFMove(keyData), extractable, usages);
+ break;
+ case CryptoKeyAsymmetricTypeSubtag::Private:
+ result = CryptoKeyEC::importPkcs8(algorithm, curve->string(), WTFMove(keyData), extractable, usages);
+ break;
+ }
+
+ return true;
+ }
+
+ bool readRawKey(CryptoKeyUsageBitmap usages, RefPtr<CryptoKey>& result)
+ {
+ CryptoAlgorithmIdentifier algorithm;
+ if (!read(algorithm))
+ return false;
+ Vector<uint8_t> keyData;
+ if (!read(keyData))
+ return false;
+ result = CryptoKeyRaw::create(algorithm, WTFMove(keyData), usages);
+ return true;
+ }
+
bool readCryptoKey(JSValue& cryptoKey)
{
uint32_t keyFormatVersion;
if (!readRSAKey(extractable, usages, result))
return false;
break;
+ case CryptoKeyClassSubtag::EC:
+ if (!readECKey(extractable, usages, result))
+ return false;
+ break;
+ case CryptoKeyClassSubtag::Raw:
+ if (!readRawKey(usages, result))
+ return false;
+ break;
}
cryptoKey = getJSValue(result.get());
return true;
return platformExportPkcs8();
}
+String CryptoKeyEC::namedCurveString() const
+{
+ switch (m_curve) {
+ case NamedCurve::P256:
+ return String(P256);
+ case NamedCurve::P384:
+ return String(P384);
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyString();
+}
+
+bool CryptoKeyEC::isValidECAlgorithm(CryptoAlgorithmIdentifier algorithm)
+{
+ return algorithm == CryptoAlgorithmIdentifier::ECDSA || algorithm == CryptoAlgorithmIdentifier::ECDH;
+}
+
std::unique_ptr<KeyAlgorithm> CryptoKeyEC::buildAlgorithm() const
{
String name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
size_t keySizeInBits() const;
NamedCurve namedCurve() const { return m_curve; }
+ String namedCurveString() const;
PlatformECKey platformKey() { return m_platformKey; }
+ static bool isValidECAlgorithm(CryptoAlgorithmIdentifier);
private:
CryptoKeyEC(CryptoAlgorithmIdentifier, NamedCurve, CryptoKeyType, PlatformECKey, bool extractable, CryptoKeyUsageBitmap);