summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/child/webcrypto/jwk.cc21
-rw-r--r--content/child/webcrypto/jwk.h6
-rw-r--r--content/child/webcrypto/platform_crypto.h61
-rw-r--r--content/child/webcrypto/platform_crypto_nss.cc241
-rw-r--r--content/child/webcrypto/platform_crypto_openssl.cc74
-rw-r--r--content/child/webcrypto/shared_crypto.cc122
-rw-r--r--content/child/webcrypto/shared_crypto.h43
-rw-r--r--content/child/webcrypto/shared_crypto_unittest.cc133
-rw-r--r--content/child/webcrypto/status.h4
-rw-r--r--content/child/webcrypto/webcrypto_impl.cc726
-rw-r--r--content/child/webcrypto/webcrypto_impl.h9
-rw-r--r--content/child/webcrypto/webcrypto_util.cc23
-rw-r--r--content/child/webcrypto/webcrypto_util.h11
13 files changed, 385 insertions, 1089 deletions
diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc
index 1b3997c..b0b5cd74 100644
--- a/content/child/webcrypto/jwk.cc
+++ b/content/child/webcrypto/jwk.cc
@@ -2,16 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "jwk.h"
-
#include <algorithm>
#include <functional>
#include <map>
-
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
-#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/platform_crypto.h"
@@ -303,14 +299,18 @@ bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
}
// Writes a secret/symmetric key to a JWK dictionary.
-void WriteSecretKey(const std::vector<uint8>& raw_key,
+void WriteSecretKey(const blink::WebArrayBuffer& raw_key,
base::DictionaryValue* jwk_dict) {
DCHECK(jwk_dict);
jwk_dict->SetString("kty", "oct");
// For a secret/symmetric key, the only extra JWK field is 'k', containing the
// base64url encoding of the raw key.
- const base::StringPiece key_str(
- reinterpret_cast<const char*>(Uint8VectorStart(raw_key)), raw_key.size());
+ DCHECK(!raw_key.isNull());
+ DCHECK(raw_key.data());
+ DCHECK(raw_key.byteLength());
+ unsigned int key_length_bytes = raw_key.byteLength();
+ const base::StringPiece key_str(static_cast<const char*>(raw_key.data()),
+ key_length_bytes);
jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str));
}
@@ -791,14 +791,14 @@ Status ImportKeyJwk(const CryptoData& key_data,
}
Status ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
DCHECK(key.extractable());
base::DictionaryValue jwk_dict;
Status status = Status::OperationError();
switch (key.type()) {
case blink::WebCryptoKeyTypeSecret: {
- std::vector<uint8> exported_key;
+ blink::WebArrayBuffer exported_key;
status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key);
if (status.IsError())
return status;
@@ -835,7 +835,8 @@ Status ExportKeyJwk(const blink::WebCryptoKey& key,
std::string json;
base::JSONWriter::Write(&jwk_dict, &json);
- buffer->assign(json.data(), json.data() + json.size());
+ *buffer = CreateArrayBuffer(reinterpret_cast<const uint8*>(json.data()),
+ json.size());
return Status::Success();
}
diff --git a/content/child/webcrypto/jwk.h b/content/child/webcrypto/jwk.h
index c919188..17bf59e 100644
--- a/content/child/webcrypto/jwk.h
+++ b/content/child/webcrypto/jwk.h
@@ -5,9 +5,6 @@
#ifndef CONTENT_CHILD_WEBCRYPTO_JWK_H_
#define CONTENT_CHILD_WEBCRYPTO_JWK_H_
-#include <vector>
-
-#include "base/basictypes.h"
#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
#include "third_party/WebKit/public/platform/WebCrypto.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -25,7 +22,8 @@ Status ImportKeyJwk(const CryptoData& key_data,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key);
-Status ExportKeyJwk(const blink::WebCryptoKey& key, std::vector<uint8>* buffer);
+Status ExportKeyJwk(const blink::WebCryptoKey& key,
+ blink::WebArrayBuffer* buffer);
} // namespace webcrypto
diff --git a/content/child/webcrypto/platform_crypto.h b/content/child/webcrypto/platform_crypto.h
index accebe7..e332920 100644
--- a/content/child/webcrypto/platform_crypto.h
+++ b/content/child/webcrypto/platform_crypto.h
@@ -6,18 +6,13 @@
#define CONTENT_CHILD_WEBCRYPTO_PLATFORM_CRYPTO_H_
#include <vector>
-
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
+#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
#include "third_party/WebKit/public/platform/WebCrypto.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-namespace blink {
-template <typename T>
-class WebVector;
-}
-
namespace content {
enum EncryptOrDecrypt { ENCRYPT, DECRYPT };
@@ -33,28 +28,6 @@ class Status;
// The general purpose code which applies to both OpenSSL and NSS
// implementations of webcrypto should live in the outter webcrypto namespace,
// and the crypto library specific bits in the "platform" namespace.
-//
-// -----------------
-// Threading:
-// -----------------
-//
-// Unless otherwise noted, functions in webcrypto::platform are called
-// exclusively from a sequenced worker pool.
-//
-// This means that operations using a given key cannot occur in
-// parallel and it is not necessary to guard against concurrent usage.
-//
-// The exceptions are:
-//
-// * Key::ThreadSafeSerializeForClone(), which is called from the
-// target Blink thread during structured clone.
-//
-// * ImportKeyRaw(), ImportKeySpki(), ImportKeyPkcs8(), which can be
-// called from the target Blink thread during structured clone
-// deserialization, as well as from the webcrypto worker pool.
-//
-// TODO(eroman): Change it so import happens in worker pool too.
-// http://crbug.com/366834
namespace platform {
class SymKey;
@@ -67,9 +40,6 @@ class Key : public blink::WebCryptoKeyHandle {
virtual SymKey* AsSymKey() = 0;
virtual PublicKey* AsPublicKey() = 0;
virtual PrivateKey* AsPrivateKey() = 0;
-
- virtual bool ThreadSafeSerializeForClone(
- blink::WebVector<uint8>* key_data) = 0;
};
// Do any one-time initialization. Note that this can be called MULTIPLE times
@@ -83,7 +53,7 @@ Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
SymKey* key,
const CryptoData& data,
const CryptoData& iv,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is a non-null AES-GCM key.
@@ -94,20 +64,20 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
const CryptoData& iv,
const CryptoData& additional_data,
unsigned int tag_length_bits,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is non-null.
// * |data| is not empty.
Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is non-null.
Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is a non-null HMAC key.
@@ -115,13 +85,13 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
Status SignHmac(SymKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |algorithm| is a SHA function.
Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |algorithm| is a SHA function.
@@ -134,7 +104,7 @@ scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is non-null.
@@ -178,7 +148,6 @@ Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
// * |key| is non-null.
// * |algorithm.id()| is for a symmetric key algorithm.
// * For AES algorithms |key_data| is either 16, 24, or 32 bytes long.
-// Note that this may be called from target Blink thread.
Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& key_data,
bool extractable,
@@ -194,14 +163,12 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& exponent_data,
blink::WebCryptoKey* key);
-// Note that this may be called from target Blink thread.
Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& key_data,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key);
-// Note that this may be called from target Blink thread.
Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& key_data,
bool extractable,
@@ -210,11 +177,11 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
// Preconditions:
// * |key| is non-null.
-Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer);
+Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is non-null.
-Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer);
+Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer);
// Preconditions:
// * |key| is non-null.
@@ -226,14 +193,14 @@ Status ExportRsaPublicKey(PublicKey* key,
// * |key| is non-null.
Status ExportKeyPkcs8(PrivateKey* key,
const blink::WebCryptoKeyAlgorithm& key_algorithm,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |wrapping_key| is non-null
// * |key| is non-null
Status WrapSymKeyAesKw(SymKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Unwraps (decrypts) |wrapped_key_data| using AES-KW and places the results in
// a WebCryptoKey. Raw key data remains inside NSS. This function should be used
@@ -260,14 +227,14 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
// * |buffer| is non-null.
Status DecryptAesKw(SymKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |wrapping_key| is non-null
// * |key| is non-null
Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
// Preconditions:
// * |wrapping_key| is non-null
diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc
index ffa62a5..86ee040 100644
--- a/content/child/webcrypto/platform_crypto_nss.cc
+++ b/content/child/webcrypto/platform_crypto_nss.cc
@@ -19,6 +19,7 @@
#include "content/child/webcrypto/webcrypto_util.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
+#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -119,20 +120,9 @@ namespace webcrypto {
namespace platform {
-// Each key maintains a copy of its serialized form
-// in either 'raw', 'pkcs8', or 'spki' format. This is to allow
-// structured cloning of keys synchronously from the target Blink
-// thread without having to lock access to the key.
-//
-// TODO(eroman): Take advantage of this for implementing exportKey(): no need
-// to call into NSS if the serialized form already exists.
-// http://crubg.com/366836
class SymKey : public Key {
public:
- static Status Create(crypto::ScopedPK11SymKey key, scoped_ptr<SymKey>* out) {
- out->reset(new SymKey(key.Pass()));
- return ExportKeyRaw(out->get(), &(*out)->serialized_key_);
- }
+ explicit SymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
PK11SymKey* key() { return key_.get(); }
@@ -140,28 +130,15 @@ class SymKey : public Key {
virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; }
virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; }
- virtual bool ThreadSafeSerializeForClone(
- blink::WebVector<uint8>* key_data) OVERRIDE {
- key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
- return true;
- }
-
private:
- explicit SymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
-
crypto::ScopedPK11SymKey key_;
- std::vector<uint8> serialized_key_;
DISALLOW_COPY_AND_ASSIGN(SymKey);
};
class PublicKey : public Key {
public:
- static Status Create(crypto::ScopedSECKEYPublicKey key,
- scoped_ptr<PublicKey>* out) {
- out->reset(new PublicKey(key.Pass()));
- return ExportKeySpki(out->get(), &(*out)->serialized_key_);
- }
+ explicit PublicKey(crypto::ScopedSECKEYPublicKey key) : key_(key.Pass()) {}
SECKEYPublicKey* key() { return key_.get(); }
@@ -169,29 +146,15 @@ class PublicKey : public Key {
virtual PublicKey* AsPublicKey() OVERRIDE { return this; }
virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; }
- virtual bool ThreadSafeSerializeForClone(
- blink::WebVector<uint8>* key_data) OVERRIDE {
- key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
- return true;
- }
-
private:
- explicit PublicKey(crypto::ScopedSECKEYPublicKey key) : key_(key.Pass()) {}
-
crypto::ScopedSECKEYPublicKey key_;
- std::vector<uint8> serialized_key_;
DISALLOW_COPY_AND_ASSIGN(PublicKey);
};
class PrivateKey : public Key {
public:
- static Status Create(crypto::ScopedSECKEYPrivateKey key,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- scoped_ptr<PrivateKey>* out) {
- out->reset(new PrivateKey(key.Pass()));
- return ExportKeyPkcs8(out->get(), algorithm, &(*out)->serialized_key_);
- }
+ explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {}
SECKEYPrivateKey* key() { return key_.get(); }
@@ -199,17 +162,8 @@ class PrivateKey : public Key {
virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; }
virtual PrivateKey* AsPrivateKey() OVERRIDE { return this; }
- virtual bool ThreadSafeSerializeForClone(
- blink::WebVector<uint8>* key_data) OVERRIDE {
- key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
- return true;
- }
-
private:
- explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {}
-
crypto::ScopedSECKEYPrivateKey key_;
- std::vector<uint8> serialized_key_;
DISALLOW_COPY_AND_ASSIGN(PrivateKey);
};
@@ -264,7 +218,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
SymKey* key,
const CryptoData& iv,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT;
SECItem iv_item = MakeSECItemForBuffer(iv);
@@ -301,15 +255,15 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE;
CHECK_GT(output_max_len, data.byte_length());
- buffer->resize(output_max_len);
+ *buffer = blink::WebArrayBuffer::create(output_max_len, 1);
- unsigned char* buffer_data = Uint8VectorStart(buffer);
+ unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data());
int output_len;
if (SECSuccess != PK11_CipherOp(context.get(),
buffer_data,
&output_len,
- buffer->size(),
+ buffer->byteLength(),
data.bytes(),
data.byte_length())) {
return Status::OperationError();
@@ -323,7 +277,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
return Status::OperationError();
}
- buffer->resize(final_output_chunk_len + output_len);
+ ShrinkBuffer(buffer, final_output_chunk_len + output_len);
return Status::Success();
}
@@ -336,7 +290,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
const CryptoData& iv,
const CryptoData& additional_data,
unsigned int tag_length_bits,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!g_aes_gcm_support.Get().IsSupported())
return Status::ErrorUnsupported();
@@ -379,8 +333,8 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
buffer_size = data.byte_length();
}
- buffer->resize(buffer_size);
- unsigned char* buffer_data = Uint8VectorStart(buffer);
+ *buffer = blink::WebArrayBuffer::create(buffer_size, 1);
+ unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data());
PK11_EncryptDecryptFunction func =
(mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func()
@@ -392,7 +346,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
&param,
buffer_data,
&output_len,
- buffer->size(),
+ buffer->byteLength(),
data.bytes(),
data.byte_length());
@@ -401,7 +355,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
// Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug
// above).
- buffer->resize(output_len);
+ ShrinkBuffer(buffer, output_len);
return Status::Success();
}
@@ -749,13 +703,13 @@ class DigestorNSS : public blink::WebCryptoDigestor {
return true;
}
- Status FinishWithVectorAndStatus(std::vector<uint8>* result) {
+ Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) {
if (!hash_context_)
return Status::ErrorUnexpected();
unsigned int result_length = HASH_ResultLenContext(hash_context_);
- result->resize(result_length);
- unsigned char* digest = Uint8VectorStart(result);
+ *result = blink::WebArrayBuffer::create(result_length, 1);
+ unsigned char* digest = reinterpret_cast<unsigned char*>(result->data());
unsigned int digest_size; // ignored
return FinishInternal(digest, &digest_size);
}
@@ -803,6 +757,7 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
+
DCHECK(!algorithm.isNull());
CK_MECHANISM_TYPE mechanism;
@@ -832,12 +787,7 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
algorithm, key_data.byte_length(), &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<SymKey> key_handle;
- status = SymKey::Create(pk11_sym_key.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()),
blink::WebCryptoKeyTypeSecret,
extractable,
key_algorithm,
@@ -845,7 +795,7 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
return Status::Success();
}
-Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer) {
+Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) {
if (PK11_ExtractKeyValue(key->key()) != SECSuccess)
return Status::OperationError();
@@ -855,7 +805,7 @@ Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer) {
if (!key_data)
return Status::OperationError();
- buffer->assign(key_data->data, key_data->data + key_data->len);
+ *buffer = CreateArrayBuffer(key_data->data, key_data->len);
return Status::Success();
}
@@ -893,6 +843,7 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
+
DCHECK(key);
if (!key_data.byte_length())
@@ -921,12 +872,7 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
algorithm, sec_public_key.get(), &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<PublicKey> key_handle;
- Status status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()),
blink::WebCryptoKeyTypePublic,
extractable,
key_algorithm,
@@ -935,7 +881,7 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
return Status::Success();
}
-Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer) {
+Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
const crypto::ScopedSECItem spki_der(
SECKEY_EncodeDERSubjectPublicKeyInfo(key->key()));
// http://crbug.com/366427: the spec does not define any other failures for
@@ -946,7 +892,7 @@ Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer) {
DCHECK(spki_der->data);
DCHECK(spki_der->len);
- buffer->assign(spki_der->data, spki_der->data + spki_der->len);
+ *buffer = CreateArrayBuffer(spki_der->data, spki_der->len);
return Status::Success();
}
@@ -967,7 +913,7 @@ Status ExportRsaPublicKey(PublicKey* key,
Status ExportKeyPkcs8(PrivateKey* key,
const blink::WebCryptoKeyAlgorithm& key_algorithm,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): Support other RSA key types as they are added to Blink.
if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 &&
key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5)
@@ -1012,7 +958,7 @@ Status ExportKeyPkcs8(PrivateKey* key,
NULL,
&private_key_info,
SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate)));
-#else // defined(USE_NSS)
+#else // defined(USE_NSS)
crypto::ScopedSECItem encoded_key(
PK11_ExportDERPrivateKeyInfo(key->key(), NULL));
#endif // defined(USE_NSS)
@@ -1020,7 +966,7 @@ Status ExportKeyPkcs8(PrivateKey* key,
if (!encoded_key.get())
return Status::OperationError();
- buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
+ *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len);
return Status::Success();
}
@@ -1029,6 +975,7 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
+
DCHECK(key);
if (!key_data.byte_length())
@@ -1063,13 +1010,7 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<PrivateKey> key_handle;
- Status status =
- PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()),
blink::WebCryptoKeyTypePrivate,
extractable,
key_algorithm,
@@ -1085,7 +1026,7 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
Status SignHmac(SymKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash));
SECItem param_item = {siBuffer, NULL, 0};
@@ -1103,8 +1044,8 @@ Status SignHmac(SymKey* key,
DCHECK_NE(0u, signature_item.len);
- buffer->resize(signature_item.len);
- signature_item.data = Uint8VectorStart(buffer);
+ *buffer = blink::WebArrayBuffer::create(signature_item.len, 1);
+ signature_item.data = reinterpret_cast<unsigned char*>(buffer->data());
if (PK11_SignWithSymKey(key->key(),
PK11_GetMechanism(key->key()),
@@ -1114,7 +1055,7 @@ Status SignHmac(SymKey* key,
return Status::OperationError();
}
- DCHECK_EQ(buffer->size(), signature_item.len);
+ DCHECK_EQ(buffer->byteLength(), signature_item.len);
return Status::Success();
}
@@ -1124,7 +1065,7 @@ Status SignHmac(SymKey* key,
Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
const unsigned int encrypted_length_bytes =
SECKEY_PublicKeyStrength(key->key());
@@ -1134,8 +1075,9 @@ Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
encrypted_length_bytes - 11 < data.byte_length())
return Status::ErrorDataTooLarge();
- buffer->resize(encrypted_length_bytes);
- unsigned char* const buffer_data = Uint8VectorStart(buffer);
+ *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1);
+ unsigned char* const buffer_data =
+ reinterpret_cast<unsigned char*>(buffer->data());
if (PK11_PubEncryptPKCS1(key->key(),
buffer_data,
@@ -1149,14 +1091,15 @@ Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key());
if (modulus_length_bytes <= 0)
return Status::ErrorUnexpected();
const unsigned int max_output_length_bytes = modulus_length_bytes;
- buffer->resize(max_output_length_bytes);
- unsigned char* const buffer_data = Uint8VectorStart(buffer);
+ *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1);
+ unsigned char* const buffer_data =
+ reinterpret_cast<unsigned char*>(buffer->data());
unsigned int output_length_bytes = 0;
if (PK11_PrivDecryptPKCS1(key->key(),
@@ -1168,7 +1111,7 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
return Status::OperationError();
}
DCHECK_LE(output_length_bytes, max_output_length_bytes);
- buffer->resize(output_length_bytes);
+ ShrinkBuffer(buffer, output_length_bytes);
return Status::Success();
}
@@ -1179,7 +1122,7 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
// inner hash of the input Web Crypto algorithm.
SECOidTag sign_alg_tag;
@@ -1209,8 +1152,7 @@ Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
return Status::OperationError();
}
- buffer->assign(signature_item->data,
- signature_item->data + signature_item->len);
+ *buffer = CreateArrayBuffer(signature_item->data, signature_item->len);
return Status::Success();
}
@@ -1255,7 +1197,7 @@ Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
SymKey* key,
const CryptoData& data,
const CryptoData& iv,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): Inline.
return AesCbcEncryptDecrypt(mode, key, iv, data, buffer);
}
@@ -1266,7 +1208,7 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
const CryptoData& iv,
const CryptoData& additional_data,
unsigned int tag_length_bits,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): Inline.
return AesGcmEncryptDecrypt(
mode, key, data, iv, additional_data, tag_length_bits, buffer);
@@ -1342,46 +1284,34 @@ Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<PublicKey> public_key_handle;
- Status status = PublicKey::Create(
- crypto::ScopedSECKEYPublicKey(sec_public_key), &public_key_handle);
- if (status.IsError())
- return status;
-
- scoped_ptr<PrivateKey> private_key_handle;
- status = PrivateKey::Create(
- scoped_sec_private_key.Pass(), key_algorithm, &private_key_handle);
- if (status.IsError())
- return status;
-
- *public_key = blink::WebCryptoKey::create(public_key_handle.release(),
- blink::WebCryptoKeyTypePublic,
- true,
- key_algorithm,
- usage_mask);
- *private_key = blink::WebCryptoKey::create(private_key_handle.release(),
- blink::WebCryptoKeyTypePrivate,
- extractable,
- key_algorithm,
- usage_mask);
+ *public_key = blink::WebCryptoKey::create(
+ new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)),
+ blink::WebCryptoKeyTypePublic,
+ true,
+ key_algorithm,
+ usage_mask);
+ *private_key =
+ blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()),
+ blink::WebCryptoKeyTypePrivate,
+ extractable,
+ key_algorithm,
+ usage_mask);
return Status::Success();
}
-void Init() {
- crypto::EnsureNSSInit();
-}
+void Init() { crypto::EnsureNSSInit(); }
Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
DigestorNSS digestor(algorithm);
Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
// http://crbug.com/366427: the spec does not define any other failures for
// digest, so none of the subsequent errors are spec compliant.
if (!error.IsSuccess())
return error;
- return digestor.FinishWithVectorAndStatus(buffer);
+ return digestor.FinishWithWebArrayAndStatus(buffer);
}
scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
@@ -1414,13 +1344,11 @@ Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<SymKey> key_handle;
- Status status = SymKey::Create(pk11_key.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(
- key_handle.release(), key_type, extractable, key_algorithm, usage_mask);
+ *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()),
+ key_type,
+ extractable,
+ key_algorithm,
+ usage_mask);
return Status::Success();
}
@@ -1430,6 +1358,7 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& modulus_data,
const CryptoData& exponent_data,
blink::WebCryptoKey* key) {
+
if (!modulus_data.byte_length())
return Status::ErrorImportRsaEmptyModulus();
@@ -1478,12 +1407,7 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<PublicKey> key_handle;
- Status status = PublicKey::Create(pubkey.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()),
blink::WebCryptoKeyTypePublic,
extractable,
key_algorithm,
@@ -1493,7 +1417,7 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
Status WrapSymKeyAesKw(SymKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// The data size must be at least 16 bytes and a multiple of 8 bytes.
// RFC 3394 does not specify a maximum allowed data length, but since only
// keys are being wrapped in this application (which are small), a reasonable
@@ -1514,7 +1438,7 @@ Status WrapSymKeyAesKw(SymKey* wrapping_key,
return Status::ErrorUnexpected();
const unsigned int output_length = input_length + 8;
- buffer->resize(output_length);
+ *buffer = blink::WebArrayBuffer::create(output_length, 1);
SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP,
@@ -1555,12 +1479,7 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
algorithm, PK11_GetKeyLength(unwrapped_key.get()), &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<SymKey> key_handle;
- status = SymKey::Create(unwrapped_key.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
blink::WebCryptoKeyTypeSecret,
extractable,
key_algorithm,
@@ -1570,7 +1489,7 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
Status DecryptAesKw(SymKey* wrapping_key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// Due to limitations in the NSS API for the AES-KW algorithm, |data| must be
// temporarily viewed as a symmetric key to be unwrapped (decrypted).
crypto::ScopedPK11SymKey decrypted;
@@ -1586,14 +1505,14 @@ Status DecryptAesKw(SymKey* wrapping_key,
const SECItem* const key_data = PK11_GetKeyData(decrypted.get());
if (!key_data)
return Status::OperationError();
- buffer->assign(key_data->data, key_data->data + key_data->len);
+ *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len);
return Status::Success();
}
Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// Check the raw length of the key to be wrapped against the max size allowed
// by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function,
// the maximum data length that can be encrypted is the wrapping_key's modulus
@@ -1605,7 +1524,7 @@ Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
modulus_length_bytes - 11 < input_length_bytes)
return Status::ErrorDataTooLarge();
- buffer->resize(modulus_length_bytes);
+ *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1);
SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
if (SECSuccess !=
@@ -1625,6 +1544,7 @@ Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
+
// Verify wrapped_key_data size does not exceed the modulus of the RSA key.
const int modulus_length_bytes =
PK11_GetPrivateModulusLen(wrapping_key->key());
@@ -1661,12 +1581,7 @@ Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm))
return Status::ErrorUnexpected();
- scoped_ptr<SymKey> key_handle;
- status = SymKey::Create(unwrapped_key.Pass(), &key_handle);
- if (status.IsError())
- return status;
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
+ *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
blink::WebCryptoKeyTypeSecret,
extractable,
key_algorithm,
diff --git a/content/child/webcrypto/platform_crypto_openssl.cc b/content/child/webcrypto/platform_crypto_openssl.cc
index 34abcd8..e990e6a 100644
--- a/content/child/webcrypto/platform_crypto_openssl.cc
+++ b/content/child/webcrypto/platform_crypto_openssl.cc
@@ -36,11 +36,6 @@ class SymKey : public Key {
virtual SymKey* AsSymKey() OVERRIDE { return this; }
virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; }
virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; }
- virtual bool ThreadSafeSerializeForClone(
- blink::WebVector<uint8>* key_data) OVERRIDE {
- key_data->assign(Uint8VectorStart(key_), key_.size());
- return true;
- }
const std::vector<unsigned char>& key() const { return key_; }
@@ -88,7 +83,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
SymKey* key,
const CryptoData& iv,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
CipherOperation cipher_operation =
(mode == ENCRYPT) ? kDoEncrypt : kDoDecrypt;
@@ -127,9 +122,10 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
output_max_len += AES_BLOCK_SIZE - remainder;
DCHECK_GT(output_max_len, data.byte_length());
- buffer->resize(output_max_len);
+ *buffer = blink::WebArrayBuffer::create(output_max_len, 1);
- unsigned char* const buffer_data = Uint8VectorStart(buffer);
+ unsigned char* const buffer_data =
+ reinterpret_cast<unsigned char*>(buffer->data());
int output_len = 0;
if (!EVP_CipherUpdate(context.get(),
@@ -149,7 +145,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
static_cast<unsigned int>(final_output_chunk_len);
DCHECK_LE(final_output_len, output_max_len);
- buffer->resize(final_output_len);
+ ShrinkBuffer(buffer, final_output_len);
return Status::Success();
}
@@ -188,12 +184,16 @@ class DigestorOpenSSL : public blink::WebCryptoDigestor {
return true;
}
- Status FinishWithVectorAndStatus(std::vector<uint8>* result) {
+ Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) {
const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
- result->resize(hash_expected_size);
- unsigned char* const hash_buffer = Uint8VectorStart(result);
+ *result = blink::WebArrayBuffer::create(hash_expected_size, 1);
+ unsigned char* const hash_buffer =
+ static_cast<unsigned char* const>(result->data());
unsigned int hash_buffer_size; // ignored
- return FinishInternal(hash_buffer, &hash_buffer_size);
+ Status error = FinishInternal(hash_buffer, &hash_buffer_size);
+ if (!error.IsSuccess())
+ result->reset();
+ return error;
}
private:
@@ -239,8 +239,8 @@ class DigestorOpenSSL : public blink::WebCryptoDigestor {
unsigned char result_[EVP_MAX_MD_SIZE];
};
-Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer) {
- *buffer = key->key();
+Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) {
+ *buffer = CreateArrayBuffer(Uint8VectorStart(key->key()), key->key().size());
return Status::Success();
}
@@ -250,19 +250,19 @@ Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
SymKey* key,
const CryptoData& data,
const CryptoData& iv,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): inline the function here.
return AesCbcEncryptDecrypt(mode, key, iv, data, buffer);
}
Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
DigestorOpenSSL digestor(algorithm);
Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
if (!error.IsSuccess())
return error;
- return digestor.FinishWithVectorAndStatus(buffer);
+ return digestor.FinishWithWebArrayAndStatus(buffer);
}
scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
@@ -335,7 +335,9 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
Status SignHmac(SymKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
+ blink::WebArrayBuffer result;
+
const EVP_MD* digest_algorithm = GetDigest(hash.id());
if (!digest_algorithm)
return Status::ErrorUnsupported();
@@ -351,9 +353,9 @@ Status SignHmac(SymKey* key,
const unsigned char null_key[] = {};
const void* const raw_key_voidp = raw_key.size() ? &raw_key[0] : null_key;
- buffer->resize(hmac_expected_length);
+ result = blink::WebArrayBuffer::create(hmac_expected_length, 1);
crypto::ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> hmac_result(
- Uint8VectorStart(buffer), hmac_expected_length);
+ reinterpret_cast<unsigned char*>(result.data()), hmac_expected_length);
crypto::OpenSSLErrStackTracer(FROM_HERE);
@@ -368,6 +370,7 @@ Status SignHmac(SymKey* key,
if (!success || hmac_actual_length != hmac_expected_length)
return Status::OperationError();
+ *buffer = result;
return Status::Success();
}
@@ -388,7 +391,7 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
const CryptoData& iv,
const CryptoData& additional_data,
unsigned int tag_length_bits,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -396,14 +399,14 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
// Guaranteed that key is valid.
Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -411,7 +414,7 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
const blink::WebCryptoAlgorithm& hash,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -444,14 +447,14 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
return Status::ErrorUnsupported();
}
-Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer) {
+Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
Status ExportKeyPkcs8(PrivateKey* key,
const blink::WebCryptoKeyAlgorithm& key_algorithm,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -465,7 +468,7 @@ Status ExportRsaPublicKey(PublicKey* key,
Status WrapSymKeyAesKw(SymKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -482,14 +485,14 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
Status DecryptAesKw(SymKey* key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
SymKey* key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// TODO(eroman): http://crbug.com/267888
return Status::ErrorUnsupported();
}
@@ -504,17 +507,6 @@ Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
return Status::ErrorUnsupported();
}
-bool ThreadSafeDeserializeKeyForClone(
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) {
- // TODO(eroman): http://crbug.com/267888
- return false;
-}
-
} // namespace platform
} // namespace webcrypto
diff --git a/content/child/webcrypto/shared_crypto.cc b/content/child/webcrypto/shared_crypto.cc
index 81c66cf..ee97895 100644
--- a/content/child/webcrypto/shared_crypto.cc
+++ b/content/child/webcrypto/shared_crypto.cc
@@ -20,17 +20,6 @@ namespace content {
namespace webcrypto {
-// ------------
-// Threading:
-// ------------
-//
-// All functions in this file are called from the webcrypto worker pool except
-// for:
-//
-// * SerializeKeyForClone()
-// * DeserializeKeyForClone()
-// * ImportKey() // TODO(eroman): Change this.
-
namespace {
// TODO(eroman): Move this helper to WebCryptoKey.
@@ -77,7 +66,7 @@ Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::SymKey* sym_key;
Status status = ToPlatformSymKey(key, &sym_key);
if (status.IsError())
@@ -98,7 +87,7 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::SymKey* sym_key;
Status status = ToPlatformSymKey(key, &sym_key);
if (status.IsError())
@@ -130,7 +119,7 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::PublicKey* public_key;
Status status = ToPlatformPublicKey(key, &public_key);
if (status.IsError())
@@ -146,7 +135,7 @@ Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::PrivateKey* private_key;
Status status = ToPlatformPrivateKey(key, &private_key);
if (status.IsError())
@@ -162,7 +151,7 @@ Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
Status SignHmac(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::SymKey* sym_key;
Status status = ToPlatformSymKey(key, &sym_key);
if (status.IsError())
@@ -177,16 +166,16 @@ Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& signature,
const CryptoData& data,
bool* signature_match) {
- std::vector<uint8> result;
+ blink::WebArrayBuffer result;
Status status = SignHmac(algorithm, key, data, &result);
if (status.IsError())
return status;
// Do not allow verification of truncated MACs.
*signature_match =
- result.size() == signature.byte_length() &&
+ result.byteLength() == signature.byte_length() &&
crypto::SecureMemEqual(
- Uint8VectorStart(result), signature.bytes(), signature.byte_length());
+ result.data(), signature.bytes(), signature.byte_length());
return Status::Success();
}
@@ -194,7 +183,7 @@ Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm,
Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::PrivateKey* private_key;
Status status = ToPlatformPrivateKey(key, &private_key);
if (status.IsError())
@@ -222,7 +211,6 @@ Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
signature_match);
}
-// Note that this function may be called from the target Blink thread.
Status ImportKeyRaw(const CryptoData& key_data,
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
@@ -285,40 +273,40 @@ blink::WebCryptoAlgorithm KeyAlgorithmToImportAlgorithm(
//
// A failure here implies either a bug in the code, or that the serialized data
// was corrupted.
-bool ValidateDeserializedKey(const blink::WebCryptoKey& key,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type) {
+Status ValidateDeserializedKey(const blink::WebCryptoKey& key,
+ const blink::WebCryptoKeyAlgorithm& algorithm,
+ blink::WebCryptoKeyType type) {
if (algorithm.id() != key.algorithm().id())
- return false;
+ return Status::ErrorUnexpected();
if (key.type() != type)
- return false;
+ return Status::ErrorUnexpected();
switch (algorithm.paramsType()) {
case blink::WebCryptoKeyAlgorithmParamsTypeAes:
if (algorithm.aesParams()->lengthBits() !=
key.algorithm().aesParams()->lengthBits())
- return false;
+ return Status::ErrorUnexpected();
break;
case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
if (algorithm.rsaParams()->modulusLengthBits() !=
key.algorithm().rsaParams()->modulusLengthBits())
- return false;
+ return Status::ErrorUnexpected();
if (algorithm.rsaParams()->publicExponent().size() !=
key.algorithm().rsaParams()->publicExponent().size())
- return false;
+ return Status::ErrorUnexpected();
if (memcmp(algorithm.rsaParams()->publicExponent().data(),
key.algorithm().rsaParams()->publicExponent().data(),
key.algorithm().rsaParams()->publicExponent().size()) != 0)
- return false;
+ return Status::ErrorUnexpected();
break;
case blink::WebCryptoKeyAlgorithmParamsTypeNone:
case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
break;
}
- return true;
+ return Status::Success();
}
// Validates the size of data input to AES-KW. AES-KW requires the input data
@@ -378,7 +366,7 @@ Status UnwrapKeyRaw(const CryptoData& wrapped_key_data,
Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoKey& key_to_wrap,
const blink::WebCryptoAlgorithm& wrapping_algorithm,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
// A raw key is always a symmetric key.
platform::SymKey* platform_key;
Status status = ToPlatformSymKey(key_to_wrap, &platform_key);
@@ -411,7 +399,7 @@ Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key,
Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
platform::SymKey* sym_key;
Status status = ToPlatformSymKey(key, &sym_key);
if (status.IsError())
@@ -425,7 +413,7 @@ Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm,
Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (algorithm.id() != key.algorithm().id())
return Status::ErrorUnexpected();
switch (algorithm.id()) {
@@ -445,7 +433,7 @@ Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm,
Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (algorithm.id() != key.algorithm().id())
return Status::ErrorUnexpected();
switch (algorithm.id()) {
@@ -469,7 +457,7 @@ Status UnwrapKeyDecryptAndImport(
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
- std::vector<uint8> buffer;
+ blink::WebArrayBuffer buffer;
Status status = DecryptDontCheckKeyUsage(
wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer);
if (status.IsError())
@@ -487,8 +475,8 @@ Status WrapKeyExportAndEncrypt(
const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoKey& key_to_wrap,
const blink::WebCryptoAlgorithm& wrapping_algorithm,
- std::vector<uint8>* buffer) {
- std::vector<uint8> exported_data;
+ blink::WebArrayBuffer* buffer) {
+ blink::WebArrayBuffer exported_data;
Status status = ExportKey(format, key_to_wrap, &exported_data);
if (status.IsError())
return status;
@@ -518,7 +506,7 @@ void Init() { platform::Init(); }
Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
return Status::ErrorUnexpected();
return EncryptDontCheckUsage(algorithm, key, data, buffer);
@@ -527,7 +515,7 @@ Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt))
return Status::ErrorUnexpected();
return DecryptDontCheckKeyUsage(algorithm, key, data, buffer);
@@ -535,7 +523,7 @@ Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
Status Digest(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
switch (algorithm.id()) {
case blink::WebCryptoAlgorithmIdSha1:
case blink::WebCryptoAlgorithmIdSha256:
@@ -638,7 +626,6 @@ Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
}
}
-// Note that this function may be called from the target Blink thread.
Status ImportKey(blink::WebCryptoKeyFormat format,
const CryptoData& key_data,
const blink::WebCryptoAlgorithm& algorithm,
@@ -664,7 +651,7 @@ Status ImportKey(blink::WebCryptoKeyFormat format,
// TODO(eroman): Move this to anonymous namespace.
Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
switch (format) {
case blink::WebCryptoKeyFormatRaw: {
platform::SymKey* sym_key;
@@ -696,7 +683,7 @@ Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
Status ExportKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& key,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!key.extractable())
return Status::ErrorKeyNotExtractable();
return ExportKeyDontCheckExtractability(format, key, buffer);
@@ -705,7 +692,7 @@ Status ExportKey(blink::WebCryptoKeyFormat format,
Status Sign(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
return Status::ErrorUnexpected();
if (algorithm.id() != key.algorithm().id())
@@ -754,7 +741,7 @@ Status WrapKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoKey& key_to_wrap,
const blink::WebCryptoAlgorithm& wrapping_algorithm,
- std::vector<uint8>* buffer) {
+ blink::WebArrayBuffer* buffer) {
if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
return Status::ErrorUnexpected();
if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
@@ -815,28 +802,24 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format,
}
}
-// Note that this function is called from the target Blink thread.
-bool SerializeKeyForClone(const blink::WebCryptoKey& key,
- blink::WebVector<uint8>* key_data) {
- return static_cast<webcrypto::platform::Key*>(key.handle())
- ->ThreadSafeSerializeForClone(key_data);
-}
-
-// Note that this function is called from the target Blink thread.
-bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usage_mask,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) {
- // TODO(eroman): This should not call into the platform crypto layer.
- // Otherwise it runs the risk of stalling while the NSS/OpenSSL global locks
- // are held.
- //
- // An alternate approach is to defer the key import until the key is used.
- // However this means that any deserialization errors would have to be
- // surfaced as WebCrypto errors, leading to slightly different behaviors. For
- // instance you could clone a key which fails to be deserialized.
+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),
@@ -844,7 +827,8 @@ bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
usage_mask,
key);
if (status.IsError())
- return false;
+ return status;
+
return ValidateDeserializedKey(*key, algorithm, type);
}
diff --git a/content/child/webcrypto/shared_crypto.h b/content/child/webcrypto/shared_crypto.h
index 3be2612..c9ce1a0 100644
--- a/content/child/webcrypto/shared_crypto.h
+++ b/content/child/webcrypto/shared_crypto.h
@@ -5,8 +5,6 @@
#ifndef CONTENT_CHILD_WEBCRYPTO_SHARED_CRYPTO_H_
#define CONTENT_CHILD_WEBCRYPTO_SHARED_CRYPTO_H_
-#include <vector>
-
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
@@ -39,9 +37,7 @@ CONTENT_EXPORT void Init();
// |
// v
// WebCryptoImpl (Implements the blink::WebCrypto interface for
-// | asynchronous completions; posts tasks to
-// | the webcrypto worker pool to fulfill the request
-// using the synchronous methods of shared_crypto.h)
+// | asynchronous completions)
// |
// | [shared_crypto_unittest.cc]
// | /
@@ -71,7 +67,7 @@ CONTENT_EXPORT void Init();
// * Inferring default parameters when not specified
// * Validating key exportability
// * Validating algorithm with key.algorithm
-// * Converting the Blink key to a more specific platform::{PublicKey,
+// * Converting the blink key to a more specific platform::{PublicKey,
// PrivateKey, SymKey} and making sure it was the right type.
// * Validating alogorithm specific parameters (for instance, was the iv for
// AES-CBC 16 bytes).
@@ -80,16 +76,16 @@ CONTENT_EXPORT void Init();
CONTENT_EXPORT Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT Status Digest(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
blink::WebCryptoAlgorithmId algorithm);
@@ -116,12 +112,12 @@ CONTENT_EXPORT Status ImportKey(blink::WebCryptoKeyFormat format,
CONTENT_EXPORT Status ExportKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& key,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT Status Sign(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT Status
VerifySignature(const blink::WebCryptoAlgorithm& algorithm,
@@ -135,7 +131,7 @@ CONTENT_EXPORT Status
const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoKey& key_to_wrap,
const blink::WebCryptoAlgorithm& wrapping_algorithm,
- std::vector<uint8>* buffer);
+ blink::WebArrayBuffer* buffer);
CONTENT_EXPORT Status
UnwrapKey(blink::WebCryptoKeyFormat format,
@@ -147,18 +143,17 @@ CONTENT_EXPORT Status
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key);
-// Called on the target Blink thread.
-CONTENT_EXPORT bool SerializeKeyForClone(const blink::WebCryptoKey& key,
- blink::WebVector<uint8>* key_data);
-
-// Called on the target Blink thread.
-CONTENT_EXPORT bool DeserializeKeyForClone(
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usage_mask,
- const CryptoData& key_data,
- blink::WebCryptoKey* key);
+CONTENT_EXPORT Status
+ SerializeKeyForClone(const blink::WebCryptoKey& key,
+ blink::WebVector<unsigned char>* data);
+
+CONTENT_EXPORT Status
+ DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
+ blink::WebCryptoKeyType type,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usage_mask,
+ const CryptoData& key_data,
+ blink::WebCryptoKey* key);
} // namespace webcrypto
diff --git a/content/child/webcrypto/shared_crypto_unittest.cc b/content/child/webcrypto/shared_crypto_unittest.cc
index 43ff8d8..30c6a67 100644
--- a/content/child/webcrypto/shared_crypto_unittest.cc
+++ b/content/child/webcrypto/shared_crypto_unittest.cc
@@ -67,89 +67,6 @@ bool operator!=(const content::webcrypto::Status& a,
namespace {
-// -----------------------------------------------------------------------------
-// TODO(eroman): Remove these helpers and convert all of the tests to using the
-// std::vector<> flavor of functions directly.
-// -----------------------------------------------------------------------------
-
-blink::WebArrayBuffer CreateArrayBuffer(const uint8* data,
- unsigned int data_size) {
- blink::WebArrayBuffer buffer = blink::WebArrayBuffer::create(data_size, 1);
- DCHECK(!buffer.isNull());
- if (data_size) // data_size == 0 might mean the data pointer is invalid
- memcpy(buffer.data(), data, data_size);
- return buffer;
-}
-
-void AssignWebArrayBuffer(const std::vector<uint8>& in,
- blink::WebArrayBuffer* out) {
- *out = CreateArrayBuffer(Uint8VectorStart(in), in.size());
-}
-
-Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
- Status status = Encrypt(algorithm, key, data, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
- Status status = Decrypt(algorithm, key, data, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-Status Digest(const blink::WebCryptoAlgorithm& algorithm,
- const CryptoData& data,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
- Status status = Digest(algorithm, data, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-Status ExportKey(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& key,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
- Status status = webcrypto::ExportKey(format, key, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-Status Sign(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
-
- Status status = Sign(algorithm, key, data, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-Status WrapKey(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& wrapping_key,
- const blink::WebCryptoKey& key_to_wrap,
- const blink::WebCryptoAlgorithm& wrapping_algorithm,
- blink::WebArrayBuffer* web_buffer) {
- std::vector<uint8> buffer;
-
- Status status = webcrypto::WrapKey(
- format, wrapping_key, key_to_wrap, wrapping_algorithm, &buffer);
- AssignWebArrayBuffer(buffer, web_buffer);
- return status;
-}
-
-// -----------------------------------------------------------------------------
-
// TODO(eroman): For Linux builds using system NSS, AES-GCM support is a
// runtime dependency. Test it by trying to import a key.
// TODO(padolph): Consider caching the result of the import key test.
@@ -1958,45 +1875,6 @@ TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) {
}
}
-TEST_F(SharedCryptoTest, MAYBE(ExportJwkEmptySymmetricKey)) {
- const blink::WebCryptoAlgorithm import_algorithm =
- webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1);
-
- blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
- blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
-
- // Import a zero-byte HMAC key.
- const char key_data_hex[] = "";
- key = ImportSecretKeyFromRaw(
- HexStringToBytes(key_data_hex), import_algorithm, usages);
- EXPECT_EQ(0u, key.algorithm().hmacParams()->lengthBits());
-
- // Export the key in JWK format and validate.
- blink::WebArrayBuffer json;
- ASSERT_EQ(Status::Success(),
- ExportKey(blink::WebCryptoKeyFormatJwk, key, &json));
- EXPECT_TRUE(VerifySecretJwk(json, "HS1", key_data_hex, usages));
-
- // Now try re-importing the JWK key.
- key = blink::WebCryptoKey::createNull();
- EXPECT_EQ(Status::Success(),
- ImportKey(blink::WebCryptoKeyFormatJwk,
- CryptoData(json),
- import_algorithm,
- true,
- usages,
- &key));
-
- EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
- EXPECT_EQ(0u, key.algorithm().hmacParams()->lengthBits());
-
- blink::WebArrayBuffer exported_key_data;
- EXPECT_EQ(Status::Success(),
- ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key_data));
-
- EXPECT_EQ(0u, exported_key_data.byteLength());
-}
-
TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) {
// Passing case: Import a valid RSA key in SPKI format.
blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
@@ -2250,12 +2128,11 @@ TEST_F(SharedCryptoTest, MAYBE(GenerateKeyPairRsa)) {
EXPECT_EQ(usage_mask, public_key.usages());
EXPECT_EQ(usage_mask, private_key.usages());
- // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha256)
- algorithm =
- CreateRsaHashedKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
- blink::WebCryptoAlgorithmIdSha256,
- modulus_length,
- public_exponent);
+ // Successful WebCryptoAlgorithmIdRsaOaep key generation.
+ algorithm = CreateRsaHashedKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length,
+ public_exponent);
EXPECT_EQ(Status::Success(),
GenerateKeyPair(
algorithm, extractable, usage_mask, &public_key, &private_key));
diff --git a/content/child/webcrypto/status.h b/content/child/webcrypto/status.h
index 3d67f6b..46bdee1 100644
--- a/content/child/webcrypto/status.h
+++ b/content/child/webcrypto/status.h
@@ -40,14 +40,12 @@ namespace webcrypto {
// As such, it is important that errors DO NOT reveal any sensitive material
// (like key bytes).
//
-// Care must be taken with what errors are reported back to Blink when doing
+// Care must be taken with what errors are reported back to blink when doing
// compound operations like unwrapping a JWK key. In this case, errors
// generated by the JWK import are not appropriate to report since the wrapped
// JWK is not visible to the caller.
class CONTENT_EXPORT Status {
public:
- Status() : type_(TYPE_ERROR) {}
-
// Returns true if the Status represents an error (any one of them).
bool IsError() const;
diff --git a/content/child/webcrypto/webcrypto_impl.cc b/content/child/webcrypto/webcrypto_impl.cc
index dcf57a2..ad08771 100644
--- a/content/child/webcrypto/webcrypto_impl.cc
+++ b/content/child/webcrypto/webcrypto_impl.cc
@@ -4,21 +4,12 @@
#include "content/child/webcrypto/webcrypto_impl.h"
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "base/threading/worker_pool.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/shared_crypto.h"
#include "content/child/webcrypto/status.h"
#include "content/child/webcrypto/webcrypto_util.h"
-#include "content/child/worker_thread_task_runner.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -28,82 +19,6 @@ using webcrypto::Status;
namespace {
-// ---------------------
-// Threading
-// ---------------------
-//
-// WebCrypto operations can be slow. For instance generating an RSA key can
-// take hundreds of milliseconds to several seconds.
-//
-// Moreover the underlying crypto libraries are not threadsafe when operating
-// on the same key.
-//
-// The strategy used here is to run a sequenced worker pool for all WebCrypto
-// operations. This pool (of 1 threads) is also used by requests started from
-// Blink Web Workers.
-//
-// A few notes to keep in mind:
-//
-// * PostTaskAndReply() cannot be used for two reasons:
-//
-// (1) Blink web worker threads do not have an associated message loop so
-// construction of the reply callback will crash.
-//
-// (2) PostTaskAndReply() handles failure posting the reply by leaking the
-// callback, rather than destroying it. In the case of Web Workers this
-// condition is reachable via normal execution, since Web Workers can
-// be stopped before the WebCrypto operation has finished. A policy of
-// leaking would therefore be problematic.
-//
-// * blink::WebArrayBuffer is NOT threadsafe, and should therefore be allocated
-// on the target Blink thread.
-//
-// TODO(eroman): Is there any way around this? Copying the result between
-// threads is silly.
-//
-// * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's
-// handle(), which wraps an NSS/OpenSSL type, may not be and should only be
-// used from the webcrypto thread).
-//
-// * blink::WebCryptoResult is not threadsafe and should only be operated on
-// the target Blink thread. HOWEVER, it is safe to delete it from any thread.
-// This can happen if by the time the operation has completed in the crypto
-// worker pool, the Blink worker thread that initiated the request is gone.
-// Posting back to the origin thread will fail, and the WebCryptoResult will
-// be deleted while running in the crypto worker pool.
-class CryptoThreadPool {
- public:
- CryptoThreadPool()
- : worker_pool_(new base::SequencedWorkerPool(1, "WebCrypto")),
- task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
- worker_pool_->GetSequenceToken(),
- base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {}
-
- static bool PostTask(const tracked_objects::Location& from_here,
- const base::Closure& task);
-
- private:
- scoped_refptr<base::SequencedWorkerPool> worker_pool_;
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-};
-
-base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool =
- LAZY_INSTANCE_INITIALIZER;
-
-bool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here,
- const base::Closure& task) {
- return crypto_thread_pool.Get().task_runner_->PostTask(from_here, task);
-}
-
-void CompleteWithThreadPoolError(blink::WebCryptoResult* result) {
-#if defined(WEBCRYPTO_HAS_ERROR_TYPE)
- result->completeWithError(blink::WebCryptoErrorTypeOperation,
- "Failed posting to crypto worker pool");
-#else
- result->completeWithError("Failed posting to crypto worker pool");
-#endif
-}
-
void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
DCHECK(status.IsError());
@@ -120,33 +35,6 @@ void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
#endif
}
-void CompleteWithBufferOrError(const Status& status,
- const std::vector<uint8>& buffer,
- blink::WebCryptoResult* result) {
- if (status.IsError()) {
- CompleteWithError(status, result);
- } else {
- if (buffer.size() > UINT_MAX) {
- // WebArrayBuffers have a smaller range than std::vector<>, so
- // theoretically this could overflow.
- CompleteWithError(Status::ErrorUnexpected(), result);
- } else {
- result->completeWithBuffer(webcrypto::Uint8VectorStart(buffer),
- buffer.size());
- }
- }
-}
-
-void CompleteWithKeyOrError(const Status& status,
- const blink::WebCryptoKey& key,
- blink::WebCryptoResult* result) {
- if (status.IsError()) {
- CompleteWithError(status, result);
- } else {
- result->completeWithKey(key);
- }
-}
-
bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
// TODO(padolph): include all other asymmetric algorithms once they are
// defined, e.g. EC and DH.
@@ -155,413 +43,11 @@ bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
}
-// Gets a task runner for the current thread. The current thread is either:
-//
-// * The main Blink thread
-// * A Blink web worker thread
-//
-// A different mechanism is needed for posting to these threads. The main
-// thread has an associated message loop and can simply use
-// base::ThreadTaskRunnerHandle. Whereas the web worker threads are managed by
-// Blink and need to be indirected through WorkerThreadTaskRunner.
-scoped_refptr<base::TaskRunner> GetCurrentBlinkThread() {
- if (base::ThreadTaskRunnerHandle::IsSet())
- return base::ThreadTaskRunnerHandle::Get();
- return WorkerThreadTaskRunner::current();
-}
-
-// --------------------------------------------------------------------
-// State
-// --------------------------------------------------------------------
-//
-// Explicit state classes are used rather than base::Bind(). This is done
-// both for clarity, but also to avoid extraneous allocations for things
-// like passing buffers and result objects between threads.
-//
-// BaseState is the base class common to all of the async operations, and
-// keeps track of the thread to complete on, the error state, and the
-// callback into Blink.
-//
-// Ownership of the State object is passed between the crypto thread and the
-// Blink thread. Under normal completion it is destroyed on the Blink thread.
-// However it may also be destroyed on the crypto thread if the Blink thread
-// has vanished (which can happen for Blink web worker threads).
-
-struct BaseState {
- explicit BaseState(const blink::WebCryptoResult& result)
- : origin_thread(GetCurrentBlinkThread()), result(result) {}
-
- scoped_refptr<base::TaskRunner> origin_thread;
-
- webcrypto::Status status;
- blink::WebCryptoResult result;
-
- protected:
- // Since there is no virtual destructor, must not delete directly as a
- // BaseState.
- ~BaseState() {}
-};
-
-struct EncryptState : public BaseState {
- EncryptState(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const unsigned char* data,
- unsigned int data_size,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- algorithm(algorithm),
- key(key),
- data(data, data + data_size) {}
-
- const blink::WebCryptoAlgorithm algorithm;
- const blink::WebCryptoKey key;
- const std::vector<uint8> data;
-
- std::vector<uint8> buffer;
-};
-
-typedef EncryptState DecryptState;
-typedef EncryptState DigestState;
-
-struct GenerateKeyState : public BaseState {
- GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usage_mask,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- algorithm(algorithm),
- extractable(extractable),
- usage_mask(usage_mask),
- public_key(blink::WebCryptoKey::createNull()),
- private_key(blink::WebCryptoKey::createNull()),
- is_asymmetric(false) {}
-
- const blink::WebCryptoAlgorithm algorithm;
- const bool extractable;
- const blink::WebCryptoKeyUsageMask usage_mask;
-
- // If |is_asymmetric| is false, then |public_key| is understood to mean the
- // symmetric key, and |private_key| is unused.
- blink::WebCryptoKey public_key;
- blink::WebCryptoKey private_key;
- bool is_asymmetric;
-};
-
-struct ImportKeyState : public BaseState {
- ImportKeyState(blink::WebCryptoKeyFormat format,
- const unsigned char* key_data,
- unsigned int key_data_size,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usage_mask,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- format(format),
- key_data(key_data, key_data + key_data_size),
- algorithm(algorithm),
- extractable(extractable),
- usage_mask(usage_mask),
- key(blink::WebCryptoKey::createNull()) {}
-
- const blink::WebCryptoKeyFormat format;
- const std::vector<uint8> key_data;
- const blink::WebCryptoAlgorithm algorithm;
- const bool extractable;
- const blink::WebCryptoKeyUsageMask usage_mask;
-
- blink::WebCryptoKey key;
-};
-
-struct ExportKeyState : public BaseState {
- ExportKeyState(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& key,
- const blink::WebCryptoResult& result)
- : BaseState(result), format(format), key(key) {}
-
- const blink::WebCryptoKeyFormat format;
- const blink::WebCryptoKey key;
-
- std::vector<uint8> buffer;
-};
-
-typedef EncryptState SignState;
-
-struct VerifySignatureState : public BaseState {
- VerifySignatureState(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const unsigned char* signature,
- unsigned int signature_size,
- const unsigned char* data,
- unsigned int data_size,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- algorithm(algorithm),
- key(key),
- signature(signature, signature + signature_size),
- data(data, data + data_size),
- verify_result(false) {}
-
- const blink::WebCryptoAlgorithm algorithm;
- const blink::WebCryptoKey key;
- const std::vector<uint8> signature;
- const std::vector<uint8> data;
-
- bool verify_result;
-};
-
-struct WrapKeyState : public BaseState {
- WrapKeyState(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& key,
- const blink::WebCryptoKey& wrapping_key,
- const blink::WebCryptoAlgorithm& wrap_algorithm,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- format(format),
- key(key),
- wrapping_key(wrapping_key),
- wrap_algorithm(wrap_algorithm) {}
-
- const blink::WebCryptoKeyFormat format;
- const blink::WebCryptoKey key;
- const blink::WebCryptoKey wrapping_key;
- const blink::WebCryptoAlgorithm wrap_algorithm;
-
- std::vector<uint8> buffer;
-};
-
-struct UnwrapKeyState : public BaseState {
- UnwrapKeyState(blink::WebCryptoKeyFormat format,
- const unsigned char* wrapped_key,
- unsigned wrapped_key_size,
- const blink::WebCryptoKey& wrapping_key,
- const blink::WebCryptoAlgorithm& unwrap_algorithm,
- const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const blink::WebCryptoResult& result)
- : BaseState(result),
- format(format),
- wrapped_key(wrapped_key, wrapped_key + wrapped_key_size),
- wrapping_key(wrapping_key),
- unwrap_algorithm(unwrap_algorithm),
- unwrapped_key_algorithm(unwrapped_key_algorithm),
- extractable(extractable),
- usages(usages),
- unwrapped_key(blink::WebCryptoKey::createNull()) {}
-
- const blink::WebCryptoKeyFormat format;
- const std::vector<uint8> wrapped_key;
- const blink::WebCryptoKey wrapping_key;
- const blink::WebCryptoAlgorithm unwrap_algorithm;
- const blink::WebCryptoAlgorithm unwrapped_key_algorithm;
- const bool extractable;
- const blink::WebCryptoKeyUsageMask usages;
-
- blink::WebCryptoKey unwrapped_key;
-};
-
-// --------------------------------------------------------------------
-// Wrapper functions
-// --------------------------------------------------------------------
-//
-// * The methods named Do*() run on the crypto thread.
-// * The methods named Do*Reply() run on the target Blink thread
-
-void DoEncryptReply(scoped_ptr<EncryptState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoEncrypt(scoped_ptr<EncryptState> state) {
- state->status = webcrypto::Encrypt(state->algorithm,
- state->key,
- webcrypto::CryptoData(state->data),
- &state->buffer);
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoEncryptReply, Passed(&state)));
-}
-
-void DoDecryptReply(scoped_ptr<DecryptState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoDecrypt(scoped_ptr<DecryptState> state) {
- state->status = webcrypto::Decrypt(state->algorithm,
- state->key,
- webcrypto::CryptoData(state->data),
- &state->buffer);
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoDecryptReply, Passed(&state)));
-}
-
-void DoDigestReply(scoped_ptr<DigestState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoDigest(scoped_ptr<DigestState> state) {
- state->status = webcrypto::Digest(
- state->algorithm, webcrypto::CryptoData(state->data), &state->buffer);
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoDigestReply, Passed(&state)));
-}
-
-void DoGenerateKeyReply(scoped_ptr<GenerateKeyState> state) {
- if (state->status.IsError()) {
- CompleteWithError(state->status, &state->result);
- } else {
- if (state->is_asymmetric)
- state->result.completeWithKeyPair(state->public_key, state->private_key);
- else
- state->result.completeWithKey(state->public_key);
- }
-}
-
-void DoGenerateKey(scoped_ptr<GenerateKeyState> state) {
- state->is_asymmetric = IsAlgorithmAsymmetric(state->algorithm);
- if (state->is_asymmetric) {
- state->status = webcrypto::GenerateKeyPair(state->algorithm,
- state->extractable,
- state->usage_mask,
- &state->public_key,
- &state->private_key);
-
- if (state->status.IsSuccess()) {
- DCHECK(state->public_key.handle());
- DCHECK(state->private_key.handle());
- DCHECK_EQ(state->algorithm.id(), state->public_key.algorithm().id());
- DCHECK_EQ(state->algorithm.id(), state->private_key.algorithm().id());
- DCHECK_EQ(true, state->public_key.extractable());
- DCHECK_EQ(state->extractable, state->private_key.extractable());
- DCHECK_EQ(state->usage_mask, state->public_key.usages());
- DCHECK_EQ(state->usage_mask, state->private_key.usages());
- }
- } else {
- blink::WebCryptoKey* key = &state->public_key;
-
- state->status = webcrypto::GenerateSecretKey(
- state->algorithm, state->extractable, state->usage_mask, key);
-
- if (state->status.IsSuccess()) {
- DCHECK(key->handle());
- DCHECK_EQ(state->algorithm.id(), key->algorithm().id());
- DCHECK_EQ(state->extractable, key->extractable());
- DCHECK_EQ(state->usage_mask, key->usages());
- }
- }
-
- state->origin_thread->PostTask(
- FROM_HERE, base::Bind(DoGenerateKeyReply, Passed(&state)));
-}
-
-void DoImportKeyReply(scoped_ptr<ImportKeyState> state) {
- CompleteWithKeyOrError(state->status, state->key, &state->result);
-}
-
-void DoImportKey(scoped_ptr<ImportKeyState> state) {
- state->status = webcrypto::ImportKey(state->format,
- webcrypto::CryptoData(state->key_data),
- state->algorithm,
- state->extractable,
- state->usage_mask,
- &state->key);
- if (state->status.IsSuccess()) {
- DCHECK(state->key.handle());
- DCHECK(!state->key.algorithm().isNull());
- DCHECK_EQ(state->extractable, state->key.extractable());
- }
-
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoImportKeyReply, Passed(&state)));
-}
-
-void DoExportKeyReply(scoped_ptr<ExportKeyState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoExportKey(scoped_ptr<ExportKeyState> state) {
- state->status =
- webcrypto::ExportKey(state->format, state->key, &state->buffer);
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoExportKeyReply, Passed(&state)));
-}
-
-void DoSignReply(scoped_ptr<SignState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoSign(scoped_ptr<SignState> state) {
- state->status = webcrypto::Sign(state->algorithm,
- state->key,
- webcrypto::CryptoData(state->data),
- &state->buffer);
-
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoSignReply, Passed(&state)));
-}
-
-void DoVerifyReply(scoped_ptr<VerifySignatureState> state) {
- if (state->status.IsError()) {
- CompleteWithError(state->status, &state->result);
- } else {
- state->result.completeWithBoolean(state->verify_result);
- }
-}
-
-void DoVerify(scoped_ptr<VerifySignatureState> state) {
- state->status =
- webcrypto::VerifySignature(state->algorithm,
- state->key,
- webcrypto::CryptoData(state->signature),
- webcrypto::CryptoData(state->data),
- &state->verify_result);
-
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoVerifyReply, Passed(&state)));
-}
-
-void DoWrapKeyReply(scoped_ptr<WrapKeyState> state) {
- CompleteWithBufferOrError(state->status, state->buffer, &state->result);
-}
-
-void DoWrapKey(scoped_ptr<WrapKeyState> state) {
- // TODO(eroman): The parameter ordering of webcrypto::WrapKey() is
- // inconsistent with that of blink::WebCrypto::wrapKey().
- state->status = webcrypto::WrapKey(state->format,
- state->wrapping_key,
- state->key,
- state->wrap_algorithm,
- &state->buffer);
-
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoWrapKeyReply, Passed(&state)));
-}
-
-void DoUnwrapKeyReply(scoped_ptr<UnwrapKeyState> state) {
- CompleteWithKeyOrError(state->status, state->unwrapped_key, &state->result);
-}
-
-void DoUnwrapKey(scoped_ptr<UnwrapKeyState> state) {
- state->status =
- webcrypto::UnwrapKey(state->format,
- webcrypto::CryptoData(state->wrapped_key),
- state->wrapping_key,
- state->unwrap_algorithm,
- state->unwrapped_key_algorithm,
- state->extractable,
- state->usages,
- &state->unwrapped_key);
-
- state->origin_thread->PostTask(FROM_HERE,
- base::Bind(DoUnwrapKeyReply, Passed(&state)));
-}
-
} // namespace
-WebCryptoImpl::WebCryptoImpl() {
- webcrypto::Init();
-}
+WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); }
-WebCryptoImpl::~WebCryptoImpl() {
-}
+WebCryptoImpl::~WebCryptoImpl() {}
void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
@@ -569,13 +55,13 @@ void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
unsigned int data_size,
blink::WebCryptoResult result) {
DCHECK(!algorithm.isNull());
-
- scoped_ptr<EncryptState> state(
- new EncryptState(algorithm, key, data, data_size, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoEncrypt, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebArrayBuffer buffer;
+ Status status = webcrypto::Encrypt(
+ algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
@@ -584,13 +70,13 @@ void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
unsigned int data_size,
blink::WebCryptoResult result) {
DCHECK(!algorithm.isNull());
-
- scoped_ptr<DecryptState> state(
- new DecryptState(algorithm, key, data, data_size, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoDecrypt, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebArrayBuffer buffer;
+ Status status = webcrypto::Decrypt(
+ algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
@@ -598,13 +84,13 @@ void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
unsigned int data_size,
blink::WebCryptoResult result) {
DCHECK(!algorithm.isNull());
-
- scoped_ptr<DigestState> state(new DigestState(
- algorithm, blink::WebCryptoKey::createNull(), data, data_size, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoDigest, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebArrayBuffer buffer;
+ Status status = webcrypto::Digest(
+ algorithm, webcrypto::CryptoData(data, data_size), &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
@@ -612,12 +98,37 @@ void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoResult result) {
DCHECK(!algorithm.isNull());
-
- scoped_ptr<GenerateKeyState> state(
- new GenerateKeyState(algorithm, extractable, usage_mask, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoGenerateKey, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
+ if (IsAlgorithmAsymmetric(algorithm)) {
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+ Status status = webcrypto::GenerateKeyPair(
+ algorithm, extractable, usage_mask, &public_key, &private_key);
+ if (status.IsError()) {
+ CompleteWithError(status, &result);
+ } else {
+ DCHECK(public_key.handle());
+ DCHECK(private_key.handle());
+ DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
+ DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
+ DCHECK_EQ(true, public_key.extractable());
+ DCHECK_EQ(extractable, private_key.extractable());
+ DCHECK_EQ(usage_mask, public_key.usages());
+ DCHECK_EQ(usage_mask, private_key.usages());
+ result.completeWithKeyPair(public_key, private_key);
+ }
+ } else {
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ Status status =
+ webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key);
+ if (status.IsError()) {
+ CompleteWithError(status, &result);
+ } else {
+ DCHECK(key.handle());
+ DCHECK_EQ(algorithm.id(), key.algorithm().id());
+ DCHECK_EQ(extractable, key.extractable());
+ DCHECK_EQ(usage_mask, key.usages());
+ result.completeWithKey(key);
+ }
}
}
@@ -628,27 +139,33 @@ void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoResult result) {
- scoped_ptr<ImportKeyState> state(new ImportKeyState(format,
- key_data,
- key_data_size,
- algorithm,
- extractable,
- usage_mask,
- result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoImportKey, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ Status status =
+ webcrypto::ImportKey(format,
+ webcrypto::CryptoData(key_data, key_data_size),
+ algorithm,
+ extractable,
+ usage_mask,
+ &key);
+ if (status.IsError()) {
+ CompleteWithError(status, &result);
+ } else {
+ DCHECK(key.handle());
+ DCHECK(!key.algorithm().isNull());
+ DCHECK_EQ(extractable, key.extractable());
+ result.completeWithKey(key);
}
}
void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& key,
blink::WebCryptoResult result) {
- scoped_ptr<ExportKeyState> state(new ExportKeyState(format, key, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoExportKey, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebArrayBuffer buffer;
+ Status status = webcrypto::ExportKey(format, key, &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
@@ -656,12 +173,14 @@ void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
const unsigned char* data,
unsigned int data_size,
blink::WebCryptoResult result) {
- scoped_ptr<SignState> state(
- new SignState(algorithm, key, data, data_size, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoSign, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ DCHECK(!algorithm.isNull());
+ blink::WebArrayBuffer buffer;
+ Status status = webcrypto::Sign(
+ algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
@@ -671,12 +190,18 @@ void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
const unsigned char* data,
unsigned int data_size,
blink::WebCryptoResult result) {
- scoped_ptr<VerifySignatureState> state(new VerifySignatureState(
- algorithm, key, signature, signature_size, data, data_size, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoVerify, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ DCHECK(!algorithm.isNull());
+ bool signature_match = false;
+ Status status = webcrypto::VerifySignature(
+ algorithm,
+ key,
+ webcrypto::CryptoData(signature, signature_size),
+ webcrypto::CryptoData(data, data_size),
+ &signature_match);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBoolean(signature_match);
}
void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format,
@@ -684,12 +209,14 @@ void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoAlgorithm& wrap_algorithm,
blink::WebCryptoResult result) {
- scoped_ptr<WrapKeyState> state(
- new WrapKeyState(format, key, wrapping_key, wrap_algorithm, result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoWrapKey, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebArrayBuffer buffer;
+ // TODO(eroman): Use the same parameter ordering.
+ Status status = webcrypto::WrapKey(
+ format, wrapping_key, key, wrap_algorithm, &buffer);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithBuffer(buffer);
}
void WebCryptoImpl::unwrapKey(
@@ -702,19 +229,32 @@ void WebCryptoImpl::unwrapKey(
bool extractable,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoResult result) {
- scoped_ptr<UnwrapKeyState> state(new UnwrapKeyState(format,
- wrapped_key,
- wrapped_key_size,
- wrapping_key,
- unwrap_algorithm,
- unwrapped_key_algorithm,
- extractable,
- usages,
- result));
- if (!CryptoThreadPool::PostTask(FROM_HERE,
- base::Bind(DoUnwrapKey, Passed(&state)))) {
- CompleteWithThreadPoolError(&result);
- }
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ Status status =
+ webcrypto::UnwrapKey(format,
+ webcrypto::CryptoData(wrapped_key, wrapped_key_size),
+ wrapping_key,
+ unwrap_algorithm,
+ unwrapped_key_algorithm,
+ extractable,
+ usages,
+ &key);
+ if (status.IsError())
+ CompleteWithError(status, &result);
+ else
+ result.completeWithKey(key);
+}
+
+bool WebCryptoImpl::digestSynchronous(
+ const blink::WebCryptoAlgorithmId algorithm_id,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebArrayBuffer& result) {
+ blink::WebCryptoAlgorithm algorithm =
+ blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm_id, NULL);
+ return (webcrypto::Digest(
+ algorithm, webcrypto::CryptoData(data, data_size), &result))
+ .IsSuccess();
}
blink::WebCryptoDigestor* WebCryptoImpl::createDigestor(
@@ -730,21 +270,21 @@ bool WebCryptoImpl::deserializeKeyForClone(
const unsigned char* key_data,
unsigned key_data_size,
blink::WebCryptoKey& key) {
- // TODO(eroman): Rather than do the import immediately on the current thread,
- // it could defer to the crypto thread.
- return webcrypto::DeserializeKeyForClone(
+ Status status = webcrypto::DeserializeKeyForClone(
algorithm,
type,
extractable,
usages,
webcrypto::CryptoData(key_data, key_data_size),
&key);
+ return status.IsSuccess();
}
bool WebCryptoImpl::serializeKeyForClone(
const blink::WebCryptoKey& key,
blink::WebVector<unsigned char>& key_data) {
- return webcrypto::SerializeKeyForClone(key, &key_data);
+ Status status = webcrypto::SerializeKeyForClone(key, &key_data);
+ return status.IsSuccess();
}
} // namespace content
diff --git a/content/child/webcrypto/webcrypto_impl.h b/content/child/webcrypto/webcrypto_impl.h
index 179de041..f28cdb1 100644
--- a/content/child/webcrypto/webcrypto_impl.h
+++ b/content/child/webcrypto/webcrypto_impl.h
@@ -13,7 +13,7 @@
namespace content {
-// Wrapper around the Blink WebCrypto asynchronous interface, which forwards to
+// Wrapper around the blink WebCrypto asynchronous interface, which forwards to
// the synchronous platfrom (NSS or OpenSSL) implementation.
//
// TODO(eroman): Post the synchronous work to a background thread.
@@ -77,7 +77,12 @@ class WebCryptoImpl : public blink::WebCrypto {
bool extractable,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoResult result);
-
+ // This method synchronously computes a digest for the given data, returning
+ // |true| if successful and |false| otherwise.
+ virtual bool digestSynchronous(const blink::WebCryptoAlgorithmId algorithm_id,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebArrayBuffer& result);
// This method returns a digestor object that can be used to synchronously
// compute a digest one chunk at a time. Thus, the consume does not need to
// hold onto a large buffer with all the data to digest. Chunks can be given
diff --git a/content/child/webcrypto/webcrypto_util.cc b/content/child/webcrypto/webcrypto_util.cc
index f80fe32..0438274 100644
--- a/content/child/webcrypto/webcrypto_util.cc
+++ b/content/child/webcrypto/webcrypto_util.cc
@@ -22,10 +22,25 @@ const uint8* Uint8VectorStart(const std::vector<uint8>& data) {
return &data[0];
}
-uint8* Uint8VectorStart(std::vector<uint8>* data) {
- if (data->empty())
- return NULL;
- return &(*data)[0];
+void ShrinkBuffer(blink::WebArrayBuffer* buffer, unsigned int new_size) {
+ DCHECK_LE(new_size, buffer->byteLength());
+
+ if (new_size == buffer->byteLength())
+ return;
+
+ blink::WebArrayBuffer new_buffer = blink::WebArrayBuffer::create(new_size, 1);
+ DCHECK(!new_buffer.isNull());
+ memcpy(new_buffer.data(), buffer->data(), new_size);
+ *buffer = new_buffer;
+}
+
+blink::WebArrayBuffer CreateArrayBuffer(const uint8* data,
+ unsigned int data_size) {
+ blink::WebArrayBuffer buffer = blink::WebArrayBuffer::create(data_size, 1);
+ DCHECK(!buffer.isNull());
+ if (data_size) // data_size == 0 might mean the data pointer is invalid
+ memcpy(buffer.data(), data, data_size);
+ return buffer;
}
// This function decodes unpadded 'base64url' encoded data, as described in
diff --git a/content/child/webcrypto/webcrypto_util.h b/content/child/webcrypto/webcrypto_util.h
index 81d2c61..60f0dbd 100644
--- a/content/child/webcrypto/webcrypto_util.h
+++ b/content/child/webcrypto/webcrypto_util.h
@@ -11,6 +11,7 @@
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
@@ -24,7 +25,15 @@ class Status;
// convenience function for getting the pointer, and should not be used beyond
// the expected lifetime of |data|.
CONTENT_EXPORT const uint8* Uint8VectorStart(const std::vector<uint8>& data);
-CONTENT_EXPORT uint8* Uint8VectorStart(std::vector<uint8>* data);
+
+// Shrinks a WebArrayBuffer to a new size.
+// TODO(eroman): This works by re-allocating a new buffer. It would be better if
+// the WebArrayBuffer could just be truncated instead.
+void ShrinkBuffer(blink::WebArrayBuffer* buffer, unsigned int new_size);
+
+// Creates a WebArrayBuffer from a uint8 byte array
+blink::WebArrayBuffer CreateArrayBuffer(const uint8* data,
+ unsigned int data_size);
// This function decodes unpadded 'base64url' encoded data, as described in
// RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5.