| Index: content/child/webcrypto/shared_crypto.cc
|
| diff --git a/content/child/webcrypto/shared_crypto.cc b/content/child/webcrypto/shared_crypto.cc
|
| index b0097c1cad593c903258e167bf641a44c76f8aa1..1ce45cda656a0575713dda5d1107c841bce5a664 100644
|
| --- a/content/child/webcrypto/shared_crypto.cc
|
| +++ b/content/child/webcrypto/shared_crypto.cc
|
| @@ -233,6 +233,83 @@ Status ImportKeyRaw(const CryptoData& key_data,
|
| }
|
| }
|
|
|
| +// Returns the key format to use for structured cloning.
|
| +blink::WebCryptoKeyFormat GetCloneFormatForKeyType(
|
| + blink::WebCryptoKeyType type) {
|
| + switch (type) {
|
| + case blink::WebCryptoKeyTypeSecret:
|
| + return blink::WebCryptoKeyFormatRaw;
|
| + case blink::WebCryptoKeyTypePublic:
|
| + return blink::WebCryptoKeyFormatSpki;
|
| + case blink::WebCryptoKeyTypePrivate:
|
| + return blink::WebCryptoKeyFormatPkcs8;
|
| + }
|
| +
|
| + NOTREACHED();
|
| + return blink::WebCryptoKeyFormatRaw;
|
| +}
|
| +
|
| +// Converts a KeyAlgorithm into an equivalent Algorithm for import.
|
| +blink::WebCryptoAlgorithm KeyAlgorithmToImportAlgorithm(
|
| + const blink::WebCryptoKeyAlgorithm& algorithm) {
|
| + switch (algorithm.paramsType()) {
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeAes:
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
|
| + return CreateAlgorithm(algorithm.id());
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
|
| + return CreateHmacImportAlgorithm(algorithm.hmacParams()->hash().id());
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
|
| + return CreateRsaHashedImportAlgorithm(
|
| + algorithm.id(), algorithm.rsaHashedParams()->hash().id());
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeNone:
|
| + break;
|
| + }
|
| + return blink::WebCryptoAlgorithm::createNull();
|
| +}
|
| +
|
| +// There is some duplicated information in the serialized format used by
|
| +// structured clone (since the KeyAlgorithm is serialized separately from the
|
| +// key data). Use this extra information to further validate what was
|
| +// deserialized from the key data.
|
| +//
|
| +// A failure here implies either a bug in the code, or that the serialized data
|
| +// was corrupted.
|
| +Status ValidateDeserializedKey(const blink::WebCryptoKey& key,
|
| + const blink::WebCryptoKeyAlgorithm& algorithm,
|
| + blink::WebCryptoKeyType type) {
|
| + if (algorithm.id() != key.algorithm().id())
|
| + return Status::ErrorUnexpected();
|
| +
|
| + if (key.type() != type)
|
| + return Status::ErrorUnexpected();
|
| +
|
| + switch (algorithm.paramsType()) {
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeAes:
|
| + if (algorithm.aesParams()->lengthBits() !=
|
| + key.algorithm().aesParams()->lengthBits())
|
| + return Status::ErrorUnexpected();
|
| + break;
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
|
| + if (algorithm.rsaParams()->modulusLengthBits() !=
|
| + key.algorithm().rsaParams()->modulusLengthBits())
|
| + return Status::ErrorUnexpected();
|
| + if (algorithm.rsaParams()->publicExponent().size() !=
|
| + key.algorithm().rsaParams()->publicExponent().size())
|
| + return Status::ErrorUnexpected();
|
| + if (memcmp(algorithm.rsaParams()->publicExponent().data(),
|
| + key.algorithm().rsaParams()->publicExponent().data(),
|
| + key.algorithm().rsaParams()->publicExponent().size()) != 0)
|
| + return Status::ErrorUnexpected();
|
| + break;
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeNone:
|
| + case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
|
| + break;
|
| + }
|
| +
|
| + return Status::Success();
|
| +}
|
| +
|
| } // namespace
|
|
|
| void Init() { platform::Init(); }
|
| @@ -403,12 +480,10 @@ Status ImportKey(blink::WebCryptoKeyFormat format,
|
| }
|
| }
|
|
|
| -Status ExportKey(blink::WebCryptoKeyFormat format,
|
| - const blink::WebCryptoKey& key,
|
| - blink::WebArrayBuffer* buffer) {
|
| - if (!key.extractable())
|
| - return Status::ErrorKeyNotExtractable();
|
| -
|
| +// TODO(eroman): Move this to anonymous namespace.
|
| +Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
|
| + const blink::WebCryptoKey& key,
|
| + blink::WebArrayBuffer* buffer) {
|
| switch (format) {
|
| case blink::WebCryptoKeyFormatRaw: {
|
| platform::SymKey* sym_key;
|
| @@ -433,6 +508,14 @@ Status ExportKey(blink::WebCryptoKeyFormat format,
|
| }
|
| }
|
|
|
| +Status ExportKey(blink::WebCryptoKeyFormat format,
|
| + const blink::WebCryptoKey& key,
|
| + blink::WebArrayBuffer* buffer) {
|
| + if (!key.extractable())
|
| + return Status::ErrorKeyNotExtractable();
|
| + return ExportKeyDontCheckExtractability(format, key, buffer);
|
| +}
|
| +
|
| Status Sign(const blink::WebCryptoAlgorithm& algorithm,
|
| const blink::WebCryptoKey& key,
|
| const CryptoData& data,
|
| @@ -587,6 +670,36 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format,
|
| }
|
| }
|
|
|
| +Status SerializeKeyForClone(const blink::WebCryptoKey& key,
|
| + blink::WebVector<unsigned char>* data) {
|
| + blink::WebArrayBuffer buffer;
|
| + Status status = ExportKeyDontCheckExtractability(
|
| + GetCloneFormatForKeyType(key.type()), key, &buffer);
|
| + if (status.IsError())
|
| + return status;
|
| + data->assign(
|
| + reinterpret_cast<unsigned char*>(buffer.data()), buffer.byteLength());
|
| + return Status::Success();
|
| +}
|
| +
|
| +Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
|
| + blink::WebCryptoKeyType type,
|
| + bool extractable,
|
| + blink::WebCryptoKeyUsageMask usage_mask,
|
| + const CryptoData& key_data,
|
| + blink::WebCryptoKey* key) {
|
| + Status status = ImportKey(GetCloneFormatForKeyType(type),
|
| + key_data,
|
| + KeyAlgorithmToImportAlgorithm(algorithm),
|
| + extractable,
|
| + usage_mask,
|
| + key);
|
| + if (status.IsError())
|
| + return status;
|
| +
|
| + return ValidateDeserializedKey(*key, algorithm, type);
|
| +}
|
| +
|
| } // namespace webcrypto
|
|
|
| } // namespace content
|
|
|