| Index: Source/modules/crypto/SubtleCrypto.cpp
|
| diff --git a/Source/modules/crypto/SubtleCrypto.cpp b/Source/modules/crypto/SubtleCrypto.cpp
|
| index 832f916541561c73da9c175f00c8229f9d9976be..ca705a87c5f74f36a959f6ebbc98a2ade219fa2c 100644
|
| --- a/Source/modules/crypto/SubtleCrypto.cpp
|
| +++ b/Source/modules/crypto/SubtleCrypto.cpp
|
| @@ -36,6 +36,7 @@
|
| #include "modules/crypto/CryptoResultImpl.h"
|
| #include "modules/crypto/Key.h"
|
| #include "modules/crypto/NormalizeAlgorithm.h"
|
| +#include "platform/JSONValues.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/WebCrypto.h"
|
| #include "public/platform/WebCryptoAlgorithm.h"
|
| @@ -65,7 +66,7 @@ static bool ensureNotNull(Key* key, const char* paramName, CryptoResult* result)
|
| return true;
|
| }
|
|
|
| -bool parseAlgorithm(const Dictionary& raw, blink::WebCryptoOperation op, blink::WebCryptoAlgorithm& algorithm, CryptoResult* result)
|
| +static bool parseAlgorithm(const Dictionary& raw, blink::WebCryptoOperation op, blink::WebCryptoAlgorithm& algorithm, CryptoResult* result)
|
| {
|
| AlgorithmError error;
|
| bool success = normalizeAlgorithm(raw, op, algorithm, &error);
|
| @@ -136,6 +137,57 @@ static ScriptPromise startCryptoOperation(ScriptState* scriptState, const Dictio
|
| return promise;
|
| }
|
|
|
| +static bool copyStringProperty(const char* property, const Dictionary& source, JSONObject* destination)
|
| +{
|
| + String value;
|
| + if (!source.get(property, value))
|
| + return false;
|
| + destination->setString(property, value);
|
| + return true;
|
| +}
|
| +
|
| +static bool copySequenceOfStringProperty(const char* property, const Dictionary& source, JSONObject* destination)
|
| +{
|
| + Vector<String> value;
|
| + if (!source.get(property, value))
|
| + return false;
|
| + RefPtr<JSONArray> jsonArray = JSONArray::create();
|
| + for (unsigned i = 0; i < value.size(); ++i)
|
| + jsonArray->pushString(value[i]);
|
| + destination->setArray(property, jsonArray.release());
|
| + return true;
|
| +}
|
| +
|
| +// FIXME: At the time of writing this is not a part of the spec. It is based an
|
| +// an unpublished editor's draft for:
|
| +// https://www.w3.org/Bugs/Public/show_bug.cgi?id=24963
|
| +// See http://crbug.com/373917.
|
| +static bool copyJwkDictionaryToJson(const Dictionary& dict, CString& jsonUtf8, CryptoResult* result)
|
| +{
|
| + RefPtr<JSONObject> jsonObject = JSONObject::create();
|
| +
|
| + if (!copyStringProperty("kty", dict, jsonObject.get())) {
|
| + result->completeWithError(blink::WebCryptoErrorTypeData, "The required JWK property \"kty\" was missing");
|
| + return false;
|
| + }
|
| +
|
| + copyStringProperty("use", dict, jsonObject.get());
|
| + copySequenceOfStringProperty("key_ops", dict, jsonObject.get());
|
| + copyStringProperty("alg", dict, jsonObject.get());
|
| +
|
| + bool ext;
|
| + if (dict.get("ext", ext))
|
| + jsonObject->setBoolean("ext", ext);
|
| +
|
| + const char* const propertyNames[] = { "d", "n", "e", "p", "q", "dp", "dq", "qi", "k" };
|
| + for (unsigned i = 0; i < WTF_ARRAY_LENGTH(propertyNames); ++i)
|
| + copyStringProperty(propertyNames[i], dict, jsonObject.get());
|
| +
|
| + String json = jsonObject->toJSONString();
|
| + jsonUtf8 = json.utf8();
|
| + return true;
|
| +}
|
| +
|
| SubtleCrypto::SubtleCrypto()
|
| {
|
| ScriptWrappable::init(this);
|
| @@ -201,6 +253,11 @@ ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
|
| if (!Key::parseFormat(rawFormat, format, result.get()))
|
| return promise;
|
|
|
| + if (format == blink::WebCryptoKeyFormatJwk) {
|
| + result->completeWithError(blink::WebCryptoErrorTypeData, "Key data must be an object for JWK import");
|
| + return promise;
|
| + }
|
| +
|
| blink::WebCryptoKeyUsageMask keyUsages;
|
| if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
|
| return promise;
|
| @@ -213,6 +270,39 @@ ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
|
| return promise;
|
| }
|
|
|
| +ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& rawFormat, const Dictionary& keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages)
|
| +{
|
| + RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(scriptState);
|
| + ScriptPromise promise = result->promise();
|
| +
|
| + if (!canAccessWebCrypto(scriptState, result.get()))
|
| + return promise;
|
| +
|
| + blink::WebCryptoKeyFormat format;
|
| + if (!Key::parseFormat(rawFormat, format, result.get()))
|
| + return promise;
|
| +
|
| + blink::WebCryptoKeyUsageMask keyUsages;
|
| + if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
|
| + return promise;
|
| +
|
| + if (format != blink::WebCryptoKeyFormatJwk) {
|
| + result->completeWithError(blink::WebCryptoErrorTypeData, "Key data must be a buffer for non-JWK formats");
|
| + return promise;
|
| + }
|
| +
|
| + blink::WebCryptoAlgorithm algorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, blink::WebCryptoOperationImportKey, algorithm, result.get()))
|
| + return promise;
|
| +
|
| + CString jsonUtf8;
|
| + if (!copyJwkDictionaryToJson(keyData, jsonUtf8, result.get()))
|
| + return promise;
|
| +
|
| + blink::Platform::current()->crypto()->importKey(format, reinterpret_cast<const unsigned char*>(jsonUtf8.data()), jsonUtf8.length(), algorithm, extractable, keyUsages, result->result());
|
| + return promise;
|
| +}
|
| +
|
| ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& rawFormat, Key* key)
|
| {
|
| RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(scriptState);
|
|
|