| Index: content/child/webcrypto/platform_crypto_nss.cc
|
| diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc
|
| index 86ee04032ccf860f17f796356e5f5d6a3f39d571..ffa62a54f788dcd5722dd57df683a42d2326af29 100644
|
| --- a/content/child/webcrypto/platform_crypto_nss.cc
|
| +++ b/content/child/webcrypto/platform_crypto_nss.cc
|
| @@ -19,7 +19,6 @@
|
| #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"
|
| @@ -120,9 +119,20 @@ 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:
|
| - explicit SymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
|
| + static Status Create(crypto::ScopedPK11SymKey key, scoped_ptr<SymKey>* out) {
|
| + out->reset(new SymKey(key.Pass()));
|
| + return ExportKeyRaw(out->get(), &(*out)->serialized_key_);
|
| + }
|
|
|
| PK11SymKey* key() { return key_.get(); }
|
|
|
| @@ -130,15 +140,28 @@ 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:
|
| - explicit PublicKey(crypto::ScopedSECKEYPublicKey key) : key_(key.Pass()) {}
|
| + static Status Create(crypto::ScopedSECKEYPublicKey key,
|
| + scoped_ptr<PublicKey>* out) {
|
| + out->reset(new PublicKey(key.Pass()));
|
| + return ExportKeySpki(out->get(), &(*out)->serialized_key_);
|
| + }
|
|
|
| SECKEYPublicKey* key() { return key_.get(); }
|
|
|
| @@ -146,15 +169,29 @@ 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:
|
| - explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {}
|
| + 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_);
|
| + }
|
|
|
| SECKEYPrivateKey* key() { return key_.get(); }
|
|
|
| @@ -162,8 +199,17 @@ 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);
|
| };
|
| @@ -218,7 +264,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
|
| SymKey* key,
|
| const CryptoData& iv,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT;
|
|
|
| SECItem iv_item = MakeSECItemForBuffer(iv);
|
| @@ -255,15 +301,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 = blink::WebArrayBuffer::create(output_max_len, 1);
|
| + buffer->resize(output_max_len);
|
|
|
| - unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data());
|
| + unsigned char* buffer_data = Uint8VectorStart(buffer);
|
|
|
| int output_len;
|
| if (SECSuccess != PK11_CipherOp(context.get(),
|
| buffer_data,
|
| &output_len,
|
| - buffer->byteLength(),
|
| + buffer->size(),
|
| data.bytes(),
|
| data.byte_length())) {
|
| return Status::OperationError();
|
| @@ -277,7 +323,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
|
| return Status::OperationError();
|
| }
|
|
|
| - ShrinkBuffer(buffer, final_output_chunk_len + output_len);
|
| + buffer->resize(final_output_chunk_len + output_len);
|
| return Status::Success();
|
| }
|
|
|
| @@ -290,7 +336,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
|
| const CryptoData& iv,
|
| const CryptoData& additional_data,
|
| unsigned int tag_length_bits,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| if (!g_aes_gcm_support.Get().IsSupported())
|
| return Status::ErrorUnsupported();
|
|
|
| @@ -333,8 +379,8 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
|
| buffer_size = data.byte_length();
|
| }
|
|
|
| - *buffer = blink::WebArrayBuffer::create(buffer_size, 1);
|
| - unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data());
|
| + buffer->resize(buffer_size);
|
| + unsigned char* buffer_data = Uint8VectorStart(buffer);
|
|
|
| PK11_EncryptDecryptFunction func =
|
| (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func()
|
| @@ -346,7 +392,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
|
| ¶m,
|
| buffer_data,
|
| &output_len,
|
| - buffer->byteLength(),
|
| + buffer->size(),
|
| data.bytes(),
|
| data.byte_length());
|
|
|
| @@ -355,7 +401,7 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
|
|
|
| // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug
|
| // above).
|
| - ShrinkBuffer(buffer, output_len);
|
| + buffer->resize(output_len);
|
|
|
| return Status::Success();
|
| }
|
| @@ -703,13 +749,13 @@ class DigestorNSS : public blink::WebCryptoDigestor {
|
| return true;
|
| }
|
|
|
| - Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) {
|
| + Status FinishWithVectorAndStatus(std::vector<uint8>* result) {
|
| if (!hash_context_)
|
| return Status::ErrorUnexpected();
|
|
|
| unsigned int result_length = HASH_ResultLenContext(hash_context_);
|
| - *result = blink::WebArrayBuffer::create(result_length, 1);
|
| - unsigned char* digest = reinterpret_cast<unsigned char*>(result->data());
|
| + result->resize(result_length);
|
| + unsigned char* digest = Uint8VectorStart(result);
|
| unsigned int digest_size; // ignored
|
| return FinishInternal(digest, &digest_size);
|
| }
|
| @@ -757,7 +803,6 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
|
| bool extractable,
|
| blink::WebCryptoKeyUsageMask usage_mask,
|
| blink::WebCryptoKey* key) {
|
| -
|
| DCHECK(!algorithm.isNull());
|
|
|
| CK_MECHANISM_TYPE mechanism;
|
| @@ -787,7 +832,12 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
|
| algorithm, key_data.byte_length(), &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypeSecret,
|
| extractable,
|
| key_algorithm,
|
| @@ -795,7 +845,7 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
|
| return Status::Success();
|
| }
|
|
|
| -Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) {
|
| +Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer) {
|
| if (PK11_ExtractKeyValue(key->key()) != SECSuccess)
|
| return Status::OperationError();
|
|
|
| @@ -805,7 +855,7 @@ Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) {
|
| if (!key_data)
|
| return Status::OperationError();
|
|
|
| - *buffer = CreateArrayBuffer(key_data->data, key_data->len);
|
| + buffer->assign(key_data->data, key_data->data + key_data->len);
|
|
|
| return Status::Success();
|
| }
|
| @@ -843,7 +893,6 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
|
| bool extractable,
|
| blink::WebCryptoKeyUsageMask usage_mask,
|
| blink::WebCryptoKey* key) {
|
| -
|
| DCHECK(key);
|
|
|
| if (!key_data.byte_length())
|
| @@ -872,7 +921,12 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
|
| algorithm, sec_public_key.get(), &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypePublic,
|
| extractable,
|
| key_algorithm,
|
| @@ -881,7 +935,7 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
|
| return Status::Success();
|
| }
|
|
|
| -Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
|
| +Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer) {
|
| const crypto::ScopedSECItem spki_der(
|
| SECKEY_EncodeDERSubjectPublicKeyInfo(key->key()));
|
| // http://crbug.com/366427: the spec does not define any other failures for
|
| @@ -892,7 +946,7 @@ Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
|
| DCHECK(spki_der->data);
|
| DCHECK(spki_der->len);
|
|
|
| - *buffer = CreateArrayBuffer(spki_der->data, spki_der->len);
|
| + buffer->assign(spki_der->data, spki_der->data + spki_der->len);
|
|
|
| return Status::Success();
|
| }
|
| @@ -913,7 +967,7 @@ Status ExportRsaPublicKey(PublicKey* key,
|
|
|
| Status ExportKeyPkcs8(PrivateKey* key,
|
| const blink::WebCryptoKeyAlgorithm& key_algorithm,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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)
|
| @@ -958,7 +1012,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)
|
| @@ -966,7 +1020,7 @@ Status ExportKeyPkcs8(PrivateKey* key,
|
| if (!encoded_key.get())
|
| return Status::OperationError();
|
|
|
| - *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len);
|
| + buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
|
| return Status::Success();
|
| }
|
|
|
| @@ -975,7 +1029,6 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
|
| bool extractable,
|
| blink::WebCryptoKeyUsageMask usage_mask,
|
| blink::WebCryptoKey* key) {
|
| -
|
| DCHECK(key);
|
|
|
| if (!key_data.byte_length())
|
| @@ -1010,7 +1063,13 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
|
| if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypePrivate,
|
| extractable,
|
| key_algorithm,
|
| @@ -1026,7 +1085,7 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
|
| Status SignHmac(SymKey* key,
|
| const blink::WebCryptoAlgorithm& hash,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash));
|
|
|
| SECItem param_item = {siBuffer, NULL, 0};
|
| @@ -1044,8 +1103,8 @@ Status SignHmac(SymKey* key,
|
|
|
| DCHECK_NE(0u, signature_item.len);
|
|
|
| - *buffer = blink::WebArrayBuffer::create(signature_item.len, 1);
|
| - signature_item.data = reinterpret_cast<unsigned char*>(buffer->data());
|
| + buffer->resize(signature_item.len);
|
| + signature_item.data = Uint8VectorStart(buffer);
|
|
|
| if (PK11_SignWithSymKey(key->key(),
|
| PK11_GetMechanism(key->key()),
|
| @@ -1055,7 +1114,7 @@ Status SignHmac(SymKey* key,
|
| return Status::OperationError();
|
| }
|
|
|
| - DCHECK_EQ(buffer->byteLength(), signature_item.len);
|
| + DCHECK_EQ(buffer->size(), signature_item.len);
|
| return Status::Success();
|
| }
|
|
|
| @@ -1065,7 +1124,7 @@ Status SignHmac(SymKey* key,
|
|
|
| Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| const unsigned int encrypted_length_bytes =
|
| SECKEY_PublicKeyStrength(key->key());
|
|
|
| @@ -1075,9 +1134,8 @@ Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
|
| encrypted_length_bytes - 11 < data.byte_length())
|
| return Status::ErrorDataTooLarge();
|
|
|
| - *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1);
|
| - unsigned char* const buffer_data =
|
| - reinterpret_cast<unsigned char*>(buffer->data());
|
| + buffer->resize(encrypted_length_bytes);
|
| + unsigned char* const buffer_data = Uint8VectorStart(buffer);
|
|
|
| if (PK11_PubEncryptPKCS1(key->key(),
|
| buffer_data,
|
| @@ -1091,15 +1149,14 @@ Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
|
|
|
| Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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 = blink::WebArrayBuffer::create(max_output_length_bytes, 1);
|
| - unsigned char* const buffer_data =
|
| - reinterpret_cast<unsigned char*>(buffer->data());
|
| + buffer->resize(max_output_length_bytes);
|
| + unsigned char* const buffer_data = Uint8VectorStart(buffer);
|
|
|
| unsigned int output_length_bytes = 0;
|
| if (PK11_PrivDecryptPKCS1(key->key(),
|
| @@ -1111,7 +1168,7 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
|
| return Status::OperationError();
|
| }
|
| DCHECK_LE(output_length_bytes, max_output_length_bytes);
|
| - ShrinkBuffer(buffer, output_length_bytes);
|
| + buffer->resize(output_length_bytes);
|
| return Status::Success();
|
| }
|
|
|
| @@ -1122,7 +1179,7 @@ Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
|
| Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
|
| const blink::WebCryptoAlgorithm& hash,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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;
|
| @@ -1152,7 +1209,8 @@ Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
|
| return Status::OperationError();
|
| }
|
|
|
| - *buffer = CreateArrayBuffer(signature_item->data, signature_item->len);
|
| + buffer->assign(signature_item->data,
|
| + signature_item->data + signature_item->len);
|
| return Status::Success();
|
| }
|
|
|
| @@ -1197,7 +1255,7 @@ Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
|
| SymKey* key,
|
| const CryptoData& data,
|
| const CryptoData& iv,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| // TODO(eroman): Inline.
|
| return AesCbcEncryptDecrypt(mode, key, iv, data, buffer);
|
| }
|
| @@ -1208,7 +1266,7 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
|
| const CryptoData& iv,
|
| const CryptoData& additional_data,
|
| unsigned int tag_length_bits,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* buffer) {
|
| // TODO(eroman): Inline.
|
| return AesGcmEncryptDecrypt(
|
| mode, key, data, iv, additional_data, tag_length_bits, buffer);
|
| @@ -1284,34 +1342,46 @@ Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
|
| if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *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);
|
| + 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);
|
|
|
| return Status::Success();
|
| }
|
|
|
| -void Init() { crypto::EnsureNSSInit(); }
|
| +void Init() {
|
| + crypto::EnsureNSSInit();
|
| +}
|
|
|
| Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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.FinishWithWebArrayAndStatus(buffer);
|
| + return digestor.FinishWithVectorAndStatus(buffer);
|
| }
|
|
|
| scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
|
| @@ -1344,11 +1414,13 @@ Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
|
| if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()),
|
| - key_type,
|
| - extractable,
|
| - key_algorithm,
|
| - usage_mask);
|
| + 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);
|
| return Status::Success();
|
| }
|
|
|
| @@ -1358,7 +1430,6 @@ 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();
|
|
|
| @@ -1407,7 +1478,12 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
|
| if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypePublic,
|
| extractable,
|
| key_algorithm,
|
| @@ -1417,7 +1493,7 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
|
|
|
| Status WrapSymKeyAesKw(SymKey* wrapping_key,
|
| SymKey* key,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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
|
| @@ -1438,7 +1514,7 @@ Status WrapSymKeyAesKw(SymKey* wrapping_key,
|
| return Status::ErrorUnexpected();
|
|
|
| const unsigned int output_length = input_length + 8;
|
| - *buffer = blink::WebArrayBuffer::create(output_length, 1);
|
| + buffer->resize(output_length);
|
| SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
|
|
|
| if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP,
|
| @@ -1479,7 +1555,12 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
|
| algorithm, PK11_GetKeyLength(unwrapped_key.get()), &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypeSecret,
|
| extractable,
|
| key_algorithm,
|
| @@ -1489,7 +1570,7 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
|
|
|
| Status DecryptAesKw(SymKey* wrapping_key,
|
| const CryptoData& data,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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;
|
| @@ -1505,14 +1586,14 @@ Status DecryptAesKw(SymKey* wrapping_key,
|
| const SECItem* const key_data = PK11_GetKeyData(decrypted.get());
|
| if (!key_data)
|
| return Status::OperationError();
|
| - *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len);
|
| + buffer->assign(key_data->data, key_data->data + key_data->len);
|
|
|
| return Status::Success();
|
| }
|
|
|
| Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
|
| SymKey* key,
|
| - blink::WebArrayBuffer* buffer) {
|
| + std::vector<uint8>* 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
|
| @@ -1524,7 +1605,7 @@ Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
|
| modulus_length_bytes - 11 < input_length_bytes)
|
| return Status::ErrorDataTooLarge();
|
|
|
| - *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1);
|
| + buffer->resize(modulus_length_bytes);
|
| SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
|
|
|
| if (SECSuccess !=
|
| @@ -1544,7 +1625,6 @@ 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());
|
| @@ -1581,7 +1661,12 @@ Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
|
| if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm))
|
| return Status::ErrorUnexpected();
|
|
|
| - *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
|
| + 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(),
|
| blink::WebCryptoKeyTypeSecret,
|
| extractable,
|
| key_algorithm,
|
|
|