Index: content/renderer/webcrypto/platform_crypto_nss.cc |
diff --git a/content/renderer/webcrypto/webcrypto_impl_nss.cc b/content/renderer/webcrypto/platform_crypto_nss.cc |
similarity index 59% |
rename from content/renderer/webcrypto/webcrypto_impl_nss.cc |
rename to content/renderer/webcrypto/platform_crypto_nss.cc |
index e70aab82e2a10ed7a681911494a97be3cca29480..344a83ef8a867daae78ff40e1aa7aa4057e02cde 100644 |
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc |
+++ b/content/renderer/webcrypto/platform_crypto_nss.cc |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "content/renderer/webcrypto/webcrypto_impl.h" |
+#include "content/renderer/webcrypto/platform_crypto.h" |
#include <cryptohi.h> |
#include <pk11pub.h> |
@@ -12,10 +12,10 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "content/renderer/webcrypto/crypto_data.h" |
#include "content/renderer/webcrypto/webcrypto_util.h" |
#include "crypto/nss_util.h" |
#include "crypto/scoped_nss_types.h" |
-#include "crypto/secure_util.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" |
@@ -111,52 +111,89 @@ base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = |
LAZY_INSTANCE_INITIALIZER; |
namespace content { |
+namespace webcrypto { |
-using webcrypto::Status; |
- |
-namespace { |
+class PlatformKey : public blink::WebCryptoKeyHandle { |
+ public: |
+ virtual PlatformSymKey* AsSymKey() { return NULL; } |
+ virtual PlatformPublicKey* AsPublicKey() { return NULL; } |
+ virtual PlatformPrivateKey* AsPrivateKey() { return NULL; } |
+}; |
-class SymKeyHandle : public blink::WebCryptoKeyHandle { |
+class PlatformSymKey : public PlatformKey { |
public: |
- explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {} |
+ explicit PlatformSymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {} |
PK11SymKey* key() { return key_.get(); } |
+ virtual PlatformSymKey* AsSymKey() OVERRIDE { return this; } |
+ |
private: |
crypto::ScopedPK11SymKey key_; |
- DISALLOW_COPY_AND_ASSIGN(SymKeyHandle); |
+ DISALLOW_COPY_AND_ASSIGN(PlatformSymKey); |
}; |
-class PublicKeyHandle : public blink::WebCryptoKeyHandle { |
+class PlatformPublicKey : public PlatformKey { |
public: |
- explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key) |
+ explicit PlatformPublicKey(crypto::ScopedSECKEYPublicKey key) |
: key_(key.Pass()) {} |
SECKEYPublicKey* key() { return key_.get(); } |
+ virtual PlatformPublicKey* AsPublicKey() OVERRIDE { return this; } |
+ |
private: |
crypto::ScopedSECKEYPublicKey key_; |
- DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle); |
+ DISALLOW_COPY_AND_ASSIGN(PlatformPublicKey); |
}; |
-class PrivateKeyHandle : public blink::WebCryptoKeyHandle { |
+class PlatformPrivateKey : public PlatformKey { |
public: |
- explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key) |
+ explicit PlatformPrivateKey(crypto::ScopedSECKEYPrivateKey key) |
: key_(key.Pass()) {} |
SECKEYPrivateKey* key() { return key_.get(); } |
+ virtual PlatformPrivateKey* AsPrivateKey() OVERRIDE { return this; } |
+ |
private: |
crypto::ScopedSECKEYPrivateKey key_; |
- DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle); |
+ DISALLOW_COPY_AND_ASSIGN(PlatformPrivateKey); |
}; |
+PlatformSymKey* PlatformCrypto::ToSymKey(const blink::WebCryptoKey& key) { |
+ return static_cast<PlatformKey*>(key.handle())->AsSymKey(); |
+} |
+ |
+PlatformPublicKey* PlatformCrypto::ToPublicKey(const blink::WebCryptoKey& key) { |
+ return static_cast<PlatformKey*>(key.handle())->AsPublicKey(); |
+} |
+ |
+PlatformPrivateKey* PlatformCrypto::ToPrivateKey( |
+ const blink::WebCryptoKey& key) { |
+ return static_cast<PlatformKey*>(key.handle())->AsPrivateKey(); |
+} |
+ |
+namespace { |
+ |
+// Creates a SECItem for the data in |buffer|. This does NOT make a copy, so |
+// |buffer| should outlive the SECItem. |
+SECItem MakeSECItemForBuffer(const CryptoData& buffer) { |
+ SECItem item = { |
+ siBuffer, |
+ // NSS requires non-const data even though it is just for input. |
+ const_cast<unsigned char*>(buffer.bytes()), |
+ buffer.byte_length() |
+ }; |
+ return item; |
+} |
+ |
HASH_HashType WebCryptoAlgorithmToNSSHashType( |
- const blink::WebCryptoAlgorithm& algorithm) { |
- switch (algorithm.id()) { |
+ blink::WebCryptoAlgorithmId algorithm) { |
+ switch (algorithm) { |
case blink::WebCryptoAlgorithmIdSha1: |
return HASH_AlgSHA1; |
case blink::WebCryptoAlgorithmIdSha224: |
@@ -194,40 +231,27 @@ CK_MECHANISM_TYPE WebCryptoHashToHMACMechanism( |
Status AesCbcEncryptDecrypt( |
CK_ATTRIBUTE_TYPE operation, |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+ PlatformSymKey* key, |
+ const CryptoData& iv, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdAesCbc, algorithm.id()); |
- DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
- DCHECK_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
DCHECK(operation == CKA_ENCRYPT || operation == CKA_DECRYPT); |
- SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
- |
- const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); |
- if (params->iv().size() != AES_BLOCK_SIZE) |
- return Status::ErrorIncorrectSizeAesCbcIv(); |
- |
- SECItem iv_item; |
- iv_item.type = siBuffer; |
- iv_item.data = const_cast<unsigned char*>(params->iv().data()); |
- iv_item.len = params->iv().size(); |
+ SECItem iv_item = MakeSECItemForBuffer(iv); |
crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); |
if (!param) |
return Status::Error(); |
crypto::ScopedPK11Context context(PK11_CreateContextBySymKey( |
- CKM_AES_CBC_PAD, operation, sym_key->key(), param.get())); |
+ CKM_AES_CBC_PAD, operation, key->key(), param.get())); |
if (!context.get()) |
return Status::Error(); |
// Oddly PK11_CipherOp takes input and output lengths as "int" rather than |
// "unsigned int". Do some checks now to avoid integer overflowing. |
- if (data_size >= INT_MAX - AES_BLOCK_SIZE) { |
+ if (data.byte_length() >= INT_MAX - AES_BLOCK_SIZE) { |
// TODO(eroman): Handle this by chunking the input fed into NSS. Right now |
// it doesn't make much difference since the one-shot API would end up |
// blowing out the memory and crashing anyway. |
@@ -238,14 +262,14 @@ Status AesCbcEncryptDecrypt( |
// input, or input which is not a multiple of the block size. See also |
// https://bugzilla.mozilla.com/show_bug.cgi?id=921687. |
if (operation == CKA_DECRYPT && |
- (data_size == 0 || (data_size % AES_BLOCK_SIZE != 0))) { |
+ (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) { |
return Status::Error(); |
} |
// TODO(eroman): Refine the output buffer size. It can be computed exactly for |
// encryption, and can be smaller for decryption. |
- unsigned int output_max_len = data_size + AES_BLOCK_SIZE; |
- CHECK_GT(output_max_len, data_size); |
+ 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); |
@@ -256,8 +280,8 @@ Status AesCbcEncryptDecrypt( |
buffer_data, |
&output_len, |
buffer->byteLength(), |
- data, |
- data_size)) { |
+ data.bytes(), |
+ data.byte_length())) { |
return Status::Error(); |
} |
@@ -269,7 +293,7 @@ Status AesCbcEncryptDecrypt( |
return Status::Error(); |
} |
- webcrypto::ShrinkBuffer(buffer, final_output_chunk_len + output_len); |
+ ShrinkBuffer(buffer, final_output_chunk_len + output_len); |
return Status::Success(); |
} |
@@ -278,24 +302,13 @@ Status AesCbcEncryptDecrypt( |
// this is the expectation for the input to decryption. |
Status AesGcmEncryptDecrypt( |
bool encrypt, |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+ PlatformSymKey* key, |
+ const blink::WebCryptoAesGcmParams* params, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdAesGcm, algorithm.id()); |
- DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
- DCHECK_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
- |
if (!g_aes_gcm_support.Get().IsSupported()) |
return Status::ErrorUnsupported(); |
- SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
- |
- const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams(); |
- if (!params) |
- return Status::ErrorUnexpected(); |
- |
// TODO(eroman): The spec doesn't define the default value. Assume 128 for now |
// since that is the maximum tag length: |
// http://www.w3.org/2012/webcrypto/track/issues/46 |
@@ -309,9 +322,8 @@ Status AesGcmEncryptDecrypt( |
unsigned int tag_length_bytes = tag_length_bits / 8; |
CK_GCM_PARAMS gcm_params = {0}; |
- gcm_params.pIv = |
- const_cast<unsigned char*>(algorithm.aesGcmParams()->iv().data()); |
- gcm_params.ulIvLen = algorithm.aesGcmParams()->iv().size(); |
+ gcm_params.pIv = const_cast<unsigned char*>(params->iv().data()); |
+ gcm_params.ulIvLen = params->iv().size(); |
gcm_params.pAAD = |
const_cast<unsigned char*>(params->optionalAdditionalData().data()); |
@@ -329,12 +341,12 @@ Status AesGcmEncryptDecrypt( |
// Calculate the output buffer size. |
if (encrypt) { |
// TODO(eroman): This is ugly, abstract away the safe integer arithmetic. |
- if (data_size > (UINT_MAX - tag_length_bytes)) |
+ if (data.byte_length() > (UINT_MAX - tag_length_bytes)) |
return Status::ErrorDataTooLarge(); |
- buffer_size = data_size + tag_length_bytes; |
+ buffer_size = data.byte_length() + tag_length_bytes; |
} else { |
// TODO(eroman): In theory the buffer allocated for the plain text should be |
- // sized as |data_size - tag_length_bytes|. |
+ // sized as |data.byte_length() - tag_length_bytes|. |
// |
// However NSS has a bug whereby it will fail if the output buffer size is |
// not at least as large as the ciphertext: |
@@ -344,7 +356,7 @@ Status AesGcmEncryptDecrypt( |
// From the analysis of that bug it looks like it might be safe to pass a |
// correctly sized buffer but lie about its size. Since resizing the |
// WebCryptoArrayBuffer is expensive that hack may be worth looking into. |
- buffer_size = data_size; |
+ buffer_size = data.byte_length(); |
} |
*buffer = blink::WebArrayBuffer::create(buffer_size, 1); |
@@ -355,16 +367,16 @@ Status AesGcmEncryptDecrypt( |
g_aes_gcm_support.Get().pk11_decrypt_func(); |
unsigned int output_len = 0; |
- SECStatus result = func(sym_key->key(), CKM_AES_GCM, ¶m, |
+ SECStatus result = func(key->key(), CKM_AES_GCM, ¶m, |
buffer_data, &output_len, buffer->byteLength(), |
- data, data_size); |
+ data.bytes(), data.byte_length()); |
if (result != SECSuccess) |
return Status::Error(); |
// Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug |
// above). |
- webcrypto::ShrinkBuffer(buffer, output_len); |
+ ShrinkBuffer(buffer, output_len); |
return Status::Success(); |
} |
@@ -411,9 +423,10 @@ bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { |
algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; |
} |
-Status ImportKeyInternalRaw( |
- const unsigned char* key_data, |
- unsigned int key_data_size, |
+} // namespace |
+ |
+Status PlatformCrypto::PlatformImportKeyRaw( |
+ const CryptoData& key_data, |
const blink::WebCryptoAlgorithm& algorithm, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
@@ -421,19 +434,6 @@ Status ImportKeyInternalRaw( |
DCHECK(!algorithm.isNull()); |
- blink::WebCryptoKeyType type; |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdHmac: |
- case blink::WebCryptoAlgorithmIdAesCbc: |
- case blink::WebCryptoAlgorithmIdAesKw: |
- case blink::WebCryptoAlgorithmIdAesGcm: |
- type = blink::WebCryptoKeyTypeSecret; |
- break; |
- // TODO(bryaneyler): Support more key types. |
- default: |
- return Status::ErrorUnsupported(); |
- } |
- |
// TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. |
// Currently only supporting symmetric. |
CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
@@ -479,11 +479,7 @@ Status ImportKeyInternalRaw( |
DCHECK_NE(CKM_INVALID_MECHANISM, mechanism); |
DCHECK_NE(0ul, flags); |
- SECItem key_item = { |
- siBuffer, |
- const_cast<unsigned char*>(key_data), |
- key_data_size |
- }; |
+ SECItem key_item = MakeSECItemForBuffer(key_data); |
crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
crypto::ScopedPK11SymKey pk11_sym_key( |
@@ -498,37 +494,31 @@ Status ImportKeyInternalRaw( |
if (!pk11_sym_key.get()) |
return Status::Error(); |
- *key = blink::WebCryptoKey::create(new SymKeyHandle(pk11_sym_key.Pass()), |
- type, extractable, algorithm, usage_mask); |
+ *key = blink::WebCryptoKey::create(new PlatformSymKey(pk11_sym_key.Pass()), |
+ blink::WebCryptoKeyTypeSecret, |
+ extractable, |
+ algorithm, |
+ usage_mask); |
return Status::Success(); |
} |
-Status ExportKeyInternalRaw( |
- const blink::WebCryptoKey& key, |
+Status PlatformCrypto::PlatformExportKeyRaw( |
+ PlatformSymKey* key, |
blink::WebArrayBuffer* buffer) { |
- |
- DCHECK(key.handle()); |
- DCHECK(buffer); |
- |
- if (!key.extractable()) |
- return Status::ErrorKeyNotExtractable(); |
- if (key.type() != blink::WebCryptoKeyTypeSecret) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
- |
- if (PK11_ExtractKeyValue(sym_key->key()) != SECSuccess) |
+ if (PK11_ExtractKeyValue(key->key()) != SECSuccess) |
return Status::Error(); |
- const SECItem* key_data = PK11_GetKeyData(sym_key->key()); |
+ const SECItem* key_data = PK11_GetKeyData(key->key()); |
if (!key_data) |
return Status::Error(); |
- *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len); |
+ *buffer = CreateArrayBuffer(key_data->data, key_data->len); |
return Status::Success(); |
} |
+namespace { |
+ |
typedef scoped_ptr<CERTSubjectPublicKeyInfo, |
crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, |
SECKEY_DestroySubjectPublicKeyInfo> > |
@@ -564,9 +554,10 @@ blink::WebCryptoAlgorithm ResolveNssKeyTypeWithInputAlgorithm( |
return blink::WebCryptoAlgorithm::createNull(); |
} |
-Status ImportKeyInternalSpki( |
- const unsigned char* key_data, |
- unsigned int key_data_size, |
+} // namespace |
+ |
+Status PlatformCrypto::PlatformImportKeySpki( |
+ const CryptoData& key_data, |
const blink::WebCryptoAlgorithm& algorithm_or_null, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
@@ -574,13 +565,13 @@ Status ImportKeyInternalSpki( |
DCHECK(key); |
- if (!key_data_size) |
+ if (!key_data.byte_length()) |
return Status::ErrorImportEmptyKeyData(); |
- DCHECK(key_data); |
+ DCHECK(key_data.bytes()); |
// The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
// Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
- SECItem spki_item = {siBuffer, const_cast<uint8*>(key_data), key_data_size}; |
+ SECItem spki_item = MakeSECItemForBuffer(key_data); |
const ScopedCERTSubjectPublicKeyInfo spki( |
SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
if (!spki) |
@@ -598,7 +589,7 @@ Status ImportKeyInternalSpki( |
return Status::Error(); |
*key = blink::WebCryptoKey::create( |
- new PublicKeyHandle(sec_public_key.Pass()), |
+ new PlatformPublicKey(sec_public_key.Pass()), |
blink::WebCryptoKeyTypePublic, |
extractable, |
algorithm, |
@@ -607,37 +598,24 @@ Status ImportKeyInternalSpki( |
return Status::Success(); |
} |
-Status ExportKeyInternalSpki( |
- const blink::WebCryptoKey& key, |
+Status PlatformCrypto::PlatformExportKeySpki( |
+ PlatformPublicKey* key, |
blink::WebArrayBuffer* buffer) { |
- |
- DCHECK(key.handle()); |
- DCHECK(buffer); |
- |
- if (!key.extractable()) |
- return Status::ErrorKeyNotExtractable(); |
- if (key.type() != blink::WebCryptoKeyTypePublic) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- PublicKeyHandle* const pub_key = |
- reinterpret_cast<PublicKeyHandle*>(key.handle()); |
- |
const crypto::ScopedSECItem spki_der( |
- SECKEY_EncodeDERSubjectPublicKeyInfo(pub_key->key())); |
+ SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); |
if (!spki_der) |
return Status::Error(); |
DCHECK(spki_der->data); |
DCHECK(spki_der->len); |
- *buffer = webcrypto::CreateArrayBuffer(spki_der->data, spki_der->len); |
+ *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); |
return Status::Success(); |
} |
-Status ImportKeyInternalPkcs8( |
- const unsigned char* key_data, |
- unsigned int key_data_size, |
+Status PlatformCrypto::PlatformImportKeyPkcs8( |
+ const CryptoData& key_data, |
const blink::WebCryptoAlgorithm& algorithm_or_null, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
@@ -645,13 +623,13 @@ Status ImportKeyInternalPkcs8( |
DCHECK(key); |
- if (!key_data_size) |
+ if (!key_data.byte_length()) |
return Status::ErrorImportEmptyKeyData(); |
- DCHECK(key_data); |
+ DCHECK(key_data.bytes()); |
// The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 |
// private key info object. |
- SECItem pki_der = {siBuffer, const_cast<uint8*>(key_data), key_data_size}; |
+ SECItem pki_der = MakeSECItemForBuffer(key_data); |
SECKEYPrivateKey* seckey_private_key = NULL; |
crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
@@ -677,7 +655,7 @@ Status ImportKeyInternalPkcs8( |
return Status::Error(); |
*key = blink::WebCryptoKey::create( |
- new PrivateKeyHandle(private_key.Pass()), |
+ new PlatformPrivateKey(private_key.Pass()), |
blink::WebCryptoKeyTypePrivate, |
extractable, |
algorithm, |
@@ -690,34 +668,20 @@ Status ImportKeyInternalPkcs8( |
// Hmac |
// ----------------------------------- |
-Status SignHmac( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformSignHmac( |
+ PlatformSymKey* key, |
+ const blink::WebCryptoAlgorithm& hash, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
- |
- const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); |
- if (!params) |
- return Status::ErrorUnexpected(); |
- |
- SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
- |
- DCHECK_EQ(PK11_GetMechanism(sym_key->key()), |
- WebCryptoHashToHMACMechanism(params->hash())); |
+ DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash)); |
SECItem param_item = { siBuffer, NULL, 0 }; |
- SECItem data_item = { |
- siBuffer, |
- const_cast<unsigned char*>(data), |
- data_size |
- }; |
+ SECItem data_item = MakeSECItemForBuffer(data); |
// First call is to figure out the length. |
SECItem signature_item = { siBuffer, NULL, 0 }; |
- if (PK11_SignWithSymKey(sym_key->key(), |
- PK11_GetMechanism(sym_key->key()), |
+ if (PK11_SignWithSymKey(key->key(), |
+ PK11_GetMechanism(key->key()), |
¶m_item, |
&signature_item, |
&data_item) != SECSuccess) { |
@@ -729,8 +693,8 @@ Status SignHmac( |
*buffer = blink::WebArrayBuffer::create(signature_item.len, 1); |
signature_item.data = reinterpret_cast<unsigned char*>(buffer->data()); |
- if (PK11_SignWithSymKey(sym_key->key(), |
- PK11_GetMechanism(sym_key->key()), |
+ if (PK11_SignWithSymKey(key->key(), |
+ PK11_GetMechanism(key->key()), |
¶m_item, |
&signature_item, |
&data_item) != SECSuccess) { |
@@ -741,98 +705,42 @@ Status SignHmac( |
return Status::Success(); |
} |
-Status VerifyHmac( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* signature, |
- unsigned int signature_size, |
- const unsigned char* data, |
- unsigned int data_size, |
- bool* signature_match) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
- |
- blink::WebArrayBuffer result; |
- Status status = SignHmac(algorithm, key, data, data_size, &result); |
- if (status.IsError()) |
- return status; |
- |
- // Handling of truncated signatures is underspecified in the WebCrypto |
- // spec, so here we fail verification if a truncated signature is being |
- // verified. |
- // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 |
- *signature_match = |
- result.byteLength() == signature_size && |
- crypto::SecureMemEqual(result.data(), signature, signature_size); |
- |
- return Status::Success(); |
-} |
- |
// ----------------------------------- |
// RsaEsPkcs1v1_5 |
// ----------------------------------- |
-Status EncryptRsaEsPkcs1v1_5( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformEncryptRsaEsPkcs1v1_5( |
+ PlatformPublicKey* key, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm.id()); |
- |
- // RSAES encryption does not support empty input |
- if (!data_size) |
- return Status::Error(); |
- DCHECK(data); |
- |
- if (key.type() != blink::WebCryptoKeyTypePublic) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- PublicKeyHandle* const public_key = |
- reinterpret_cast<PublicKeyHandle*>(key.handle()); |
- |
const unsigned int encrypted_length_bytes = |
- SECKEY_PublicKeyStrength(public_key->key()); |
+ SECKEY_PublicKeyStrength(key->key()); |
// RSAES can operate on messages up to a length of k - 11, where k is the |
// octet length of the RSA modulus. |
- if (encrypted_length_bytes < 11 || encrypted_length_bytes - 11 < data_size) |
+ if (encrypted_length_bytes < 11 || |
+ 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()); |
- if (PK11_PubEncryptPKCS1(public_key->key(), |
+ if (PK11_PubEncryptPKCS1(key->key(), |
buffer_data, |
- const_cast<unsigned char*>(data), |
- data_size, |
+ const_cast<unsigned char*>(data.bytes()), |
+ data.byte_length(), |
NULL) != SECSuccess) { |
return Status::Error(); |
} |
return Status::Success(); |
} |
-Status DecryptRsaEsPkcs1v1_5( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformDecryptRsaEsPkcs1v1_5( |
+ PlatformPrivateKey* key, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm.id()); |
- |
- // RSAES decryption does not support empty input |
- if (!data_size) |
- return Status::Error(); |
- DCHECK(data); |
- |
- if (key.type() != blink::WebCryptoKeyTypePrivate) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- PrivateKeyHandle* const private_key = |
- reinterpret_cast<PrivateKeyHandle*>(key.handle()); |
- |
- const int modulus_length_bytes = |
- PK11_GetPrivateModulusLen(private_key->key()); |
+ 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; |
@@ -842,16 +750,16 @@ Status DecryptRsaEsPkcs1v1_5( |
reinterpret_cast<unsigned char*>(buffer->data()); |
unsigned int output_length_bytes = 0; |
- if (PK11_PrivDecryptPKCS1(private_key->key(), |
+ if (PK11_PrivDecryptPKCS1(key->key(), |
buffer_data, |
&output_length_bytes, |
max_output_length_bytes, |
- const_cast<unsigned char*>(data), |
- data_size) != SECSuccess) { |
+ const_cast<unsigned char*>(data.bytes()), |
+ data.byte_length()) != SECSuccess) { |
return Status::Error(); |
} |
DCHECK_LE(output_length_bytes, max_output_length_bytes); |
- webcrypto::ShrinkBuffer(buffer, output_length_bytes); |
+ ShrinkBuffer(buffer, output_length_bytes); |
return Status::Success(); |
} |
@@ -859,29 +767,15 @@ Status DecryptRsaEsPkcs1v1_5( |
// RsaSsaPkcs1v1_5 |
// ----------------------------------- |
-Status SignRsaSsaPkcs1v1_5( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformSignRsaSsaPkcs1v1_5( |
+ PlatformPrivateKey* key, |
+ const blink::WebCryptoAlgorithm& hash, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, algorithm.id()); |
- |
- if (key.type() != blink::WebCryptoKeyTypePrivate) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- if (webcrypto::GetInnerHashAlgorithm(algorithm).isNull()) |
- return Status::ErrorUnexpected(); |
- |
- PrivateKeyHandle* const private_key = |
- reinterpret_cast<PrivateKeyHandle*>(key.handle()); |
- DCHECK(private_key); |
- DCHECK(private_key->key()); |
- |
// 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; |
- switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) { |
+ switch (hash.id()) { |
case blink::WebCryptoAlgorithmIdSha1: |
sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
break; |
@@ -903,44 +797,27 @@ Status SignRsaSsaPkcs1v1_5( |
crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); |
if (SEC_SignData(signature_item.get(), |
- data, |
- data_size, |
- private_key->key(), |
+ data.bytes(), |
+ data.byte_length(), |
+ key->key(), |
sign_alg_tag) != SECSuccess) { |
return Status::Error(); |
} |
- *buffer = webcrypto::CreateArrayBuffer(signature_item->data, |
- signature_item->len); |
+ *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); |
return Status::Success(); |
} |
-Status VerifyRsaSsaPkcs1v1_5( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* signature, |
- unsigned int signature_size, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformVerifyRsaSsaPkcs1v1_5( |
+ PlatformPublicKey* key, |
+ const blink::WebCryptoAlgorithm& hash, |
+ const CryptoData& signature, |
+ const CryptoData& data, |
bool* signature_match) { |
- DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, algorithm.id()); |
- |
- if (key.type() != blink::WebCryptoKeyTypePublic) |
- return Status::ErrorUnexpectedKeyType(); |
- |
- PublicKeyHandle* const public_key = |
- reinterpret_cast<PublicKeyHandle*>(key.handle()); |
- DCHECK(public_key); |
- DCHECK(public_key->key()); |
- |
- const SECItem signature_item = { |
- siBuffer, |
- const_cast<unsigned char*>(signature), |
- signature_size |
- }; |
+ const SECItem signature_item = MakeSECItemForBuffer(signature); |
SECOidTag hash_alg_tag; |
- switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) { |
+ switch (hash.id()) { |
case blink::WebCryptoAlgorithmIdSha1: |
hash_alg_tag = SEC_OID_SHA1; |
break; |
@@ -961,9 +838,9 @@ Status VerifyRsaSsaPkcs1v1_5( |
} |
*signature_match = |
- SECSuccess == VFY_VerifyDataDirect(data, |
- data_size, |
- public_key->key(), |
+ SECSuccess == VFY_VerifyDataDirect(data.bytes(), |
+ data.byte_length(), |
+ key->key(), |
&signature_item, |
SEC_OID_PKCS1_RSA_ENCRYPTION, |
hash_alg_tag, |
@@ -972,11 +849,41 @@ Status VerifyRsaSsaPkcs1v1_5( |
return Status::Success(); |
} |
+Status PlatformCrypto::PlatformEncryptAesCbc(PlatformSymKey* key, |
+ const CryptoData& iv, |
+ const CryptoData& data, |
+ blink::WebArrayBuffer* buffer) { |
+ return AesCbcEncryptDecrypt(CKA_ENCRYPT, key, iv, data, buffer); |
+} |
+ |
+Status PlatformCrypto::PlatformDecryptAesCbc(PlatformSymKey* key, |
+ const CryptoData& iv, |
+ const CryptoData& data, |
+ blink::WebArrayBuffer* buffer) { |
+ return AesCbcEncryptDecrypt(CKA_DECRYPT, key, iv, data, buffer); |
+} |
+ |
+Status PlatformCrypto::PlatformEncryptAesGcm( |
+ PlatformSymKey* key, |
+ const blink::WebCryptoAesGcmParams* params, |
+ const CryptoData& data, |
+ blink::WebArrayBuffer* buffer) { |
+ return AesGcmEncryptDecrypt(true, key, params, data, buffer); |
+} |
+ |
+Status PlatformCrypto::PlatformDecryptAesGcm( |
+ PlatformSymKey* key, |
+ const blink::WebCryptoAesGcmParams* params, |
+ const CryptoData& data, |
+ blink::WebArrayBuffer* buffer) { |
+ return AesGcmEncryptDecrypt(false, key, params, data, buffer); |
+} |
+ |
// ----------------------------------- |
// Key generation |
// ----------------------------------- |
-Status GenerateRsaKeyPair( |
+Status PlatformCrypto::PlatformGenerateRsaKeyPair( |
const blink::WebCryptoAlgorithm& algorithm, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
@@ -1040,13 +947,13 @@ Status GenerateRsaKeyPair( |
return Status::Error(); |
*public_key = blink::WebCryptoKey::create( |
- new PublicKeyHandle(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
+ new PlatformPublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
blink::WebCryptoKeyTypePublic, |
true, |
algorithm, |
usage_mask); |
*private_key = blink::WebCryptoKey::create( |
- new PrivateKeyHandle(scoped_sec_private_key.Pass()), |
+ new PlatformPrivateKey(scoped_sec_private_key.Pass()), |
blink::WebCryptoKeyTypePrivate, |
extractable, |
algorithm, |
@@ -1055,106 +962,13 @@ Status GenerateRsaKeyPair( |
return Status::Success(); |
} |
-// Get the secret key length in bytes from generation parameters. This resolves |
-// any defaults. |
-Status GetGenerateSecretKeyLength(const blink::WebCryptoAlgorithm& algorithm, |
- unsigned int* keylen_bytes) { |
- *keylen_bytes = 0; |
- |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdAesCbc: |
- case blink::WebCryptoAlgorithmIdAesGcm: |
- case blink::WebCryptoAlgorithmIdAesKw: { |
- const blink::WebCryptoAesKeyGenParams* params = |
- algorithm.aesKeyGenParams(); |
- DCHECK(params); |
- // Ensure the key length is a multiple of 8 bits. Let NSS verify further |
- // algorithm-specific length restrictions. |
- if (params->lengthBits() % 8) |
- return Status::ErrorGenerateKeyLength(); |
- *keylen_bytes = params->lengthBits() / 8; |
- break; |
- } |
- case blink::WebCryptoAlgorithmIdHmac: { |
- const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
- DCHECK(params); |
- if (params->hasLengthBytes()) |
- *keylen_bytes = params->optionalLengthBytes(); |
- else |
- *keylen_bytes = webcrypto::ShaBlockSizeBytes(params->hash().id()); |
- break; |
- } |
- |
- default: |
- return Status::ErrorUnsupported(); |
- } |
- |
- if (*keylen_bytes == 0) |
- return Status::ErrorGenerateKeyLength(); |
- |
- return Status::Success(); |
-} |
- |
-} // namespace |
- |
-void WebCryptoImpl::Init() { |
+PlatformCrypto::PlatformCrypto() { |
crypto::EnsureNSSInit(); |
} |
-Status WebCryptoImpl::EncryptInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
- blink::WebArrayBuffer* buffer) { |
- |
- DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
- DCHECK(key.handle()); |
- DCHECK(buffer); |
- |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdAesCbc: |
- return AesCbcEncryptDecrypt( |
- CKA_ENCRYPT, algorithm, key, data, data_size, buffer); |
- case blink::WebCryptoAlgorithmIdAesGcm: |
- return AesGcmEncryptDecrypt( |
- true, algorithm, key, data, data_size, buffer); |
- case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
- return EncryptRsaEsPkcs1v1_5(algorithm, key, data, data_size, buffer); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::DecryptInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
- blink::WebArrayBuffer* buffer) { |
- |
- DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
- DCHECK(key.handle()); |
- DCHECK(buffer); |
- |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdAesCbc: |
- return AesCbcEncryptDecrypt( |
- CKA_DECRYPT, algorithm, key, data, data_size, buffer); |
- case blink::WebCryptoAlgorithmIdAesGcm: |
- return AesGcmEncryptDecrypt( |
- false, algorithm, key, data, data_size, buffer); |
- case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
- return DecryptRsaEsPkcs1v1_5(algorithm, key, data, data_size, buffer); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::DigestInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const unsigned char* data, |
- unsigned int data_size, |
+Status PlatformCrypto::PlatformDigestSha( |
+ blink::WebCryptoAlgorithmId algorithm, |
+ const CryptoData& data, |
blink::WebArrayBuffer* buffer) { |
HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); |
if (hash_type == HASH_AlgNULL) |
@@ -1166,7 +980,7 @@ Status WebCryptoImpl::DigestInternal( |
HASH_Begin(context); |
- HASH_Update(context, data, data_size); |
+ HASH_Update(context, data.bytes(), data.byte_length()); |
unsigned int hash_result_length = HASH_ResultLenContext(context); |
DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
@@ -1185,23 +999,18 @@ Status WebCryptoImpl::DigestInternal( |
return Status::Success(); |
} |
-Status WebCryptoImpl::GenerateSecretKeyInternal( |
+Status PlatformCrypto::PlatformGenerateSecretKey( |
const blink::WebCryptoAlgorithm& algorithm, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
+ unsigned keylen_bytes, |
blink::WebCryptoKey* key) { |
- |
CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); |
blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; |
if (mech == CKM_INVALID_MECHANISM) |
return Status::ErrorUnsupported(); |
- unsigned int keylen_bytes = 0; |
- Status status = GetGenerateSecretKeyLength(algorithm, &keylen_bytes); |
- if (status.IsError()) |
- return status; |
- |
crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
if (!slot) |
return Status::Error(); |
@@ -1212,159 +1021,30 @@ Status WebCryptoImpl::GenerateSecretKeyInternal( |
if (!pk11_key) |
return Status::Error(); |
- *key = blink::WebCryptoKey::create( |
- new SymKeyHandle(pk11_key.Pass()), |
- key_type, extractable, algorithm, usage_mask); |
+ *key = blink::WebCryptoKey::create(new PlatformSymKey(pk11_key.Pass()), |
+ key_type, |
+ extractable, |
+ algorithm, |
+ usage_mask); |
return Status::Success(); |
} |
-Status WebCryptoImpl::GenerateKeyPairInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usage_mask, |
- blink::WebCryptoKey* public_key, |
- blink::WebCryptoKey* private_key) { |
- |
- // TODO(padolph): Handle other asymmetric algorithm key generation. |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
- case blink::WebCryptoAlgorithmIdRsaOaep: |
- case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
- return GenerateRsaKeyPair(algorithm, extractable, usage_mask, |
- public_key, private_key); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::ImportKeyInternal( |
- blink::WebCryptoKeyFormat format, |
- const unsigned char* key_data, |
- unsigned int key_data_size, |
- const blink::WebCryptoAlgorithm& algorithm_or_null, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usage_mask, |
- blink::WebCryptoKey* key) { |
- |
- switch (format) { |
- case blink::WebCryptoKeyFormatRaw: |
- // A 'raw'-formatted key import requires an input algorithm. |
- if (algorithm_or_null.isNull()) |
- return Status::ErrorMissingAlgorithmImportRawKey(); |
- return ImportKeyInternalRaw(key_data, |
- key_data_size, |
- algorithm_or_null, |
- extractable, |
- usage_mask, |
- key); |
- case blink::WebCryptoKeyFormatSpki: |
- return ImportKeyInternalSpki(key_data, |
- key_data_size, |
- algorithm_or_null, |
- extractable, |
- usage_mask, |
- key); |
- case blink::WebCryptoKeyFormatPkcs8: |
- return ImportKeyInternalPkcs8(key_data, |
- key_data_size, |
- algorithm_or_null, |
- extractable, |
- usage_mask, |
- key); |
- default: |
- // NOTE: blink::WebCryptoKeyFormatJwk is handled one level above. |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::ExportKeyInternal( |
- blink::WebCryptoKeyFormat format, |
- const blink::WebCryptoKey& key, |
- blink::WebArrayBuffer* buffer) { |
- switch (format) { |
- case blink::WebCryptoKeyFormatRaw: |
- return ExportKeyInternalRaw(key, buffer); |
- case blink::WebCryptoKeyFormatSpki: |
- return ExportKeyInternalSpki(key, buffer); |
- case blink::WebCryptoKeyFormatPkcs8: |
- // TODO(padolph): Implement pkcs8 export |
- return Status::ErrorUnsupported(); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::SignInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* data, |
- unsigned int data_size, |
- blink::WebArrayBuffer* buffer) { |
- |
- // Note: It is not an error to sign empty data. |
- |
- DCHECK(buffer); |
- DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign); |
- |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdHmac: |
- return SignHmac(algorithm, key, data, data_size, buffer); |
- case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
- return SignRsaSsaPkcs1v1_5(algorithm, key, data, data_size, buffer); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::VerifySignatureInternal( |
- const blink::WebCryptoAlgorithm& algorithm, |
- const blink::WebCryptoKey& key, |
- const unsigned char* signature, |
- unsigned int signature_size, |
- const unsigned char* data, |
- unsigned int data_size, |
- bool* signature_match) { |
- |
- if (!signature_size) { |
- // None of the algorithms generate valid zero-length signatures so this |
- // will necessarily fail verification. Early return to protect |
- // implementations from dealing with a NULL signature pointer. |
- *signature_match = false; |
- return Status::Success(); |
- } |
- |
- DCHECK(signature); |
- |
- switch (algorithm.id()) { |
- case blink::WebCryptoAlgorithmIdHmac: |
- return VerifyHmac(algorithm, key, signature, signature_size, |
- data, data_size, signature_match); |
- case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
- return VerifyRsaSsaPkcs1v1_5(algorithm, key, signature, signature_size, |
- data, data_size, signature_match); |
- default: |
- return Status::ErrorUnsupported(); |
- } |
-} |
- |
-Status WebCryptoImpl::ImportRsaPublicKeyInternal( |
- const unsigned char* modulus_data, |
- unsigned int modulus_size, |
- const unsigned char* exponent_data, |
- unsigned int exponent_size, |
+Status PlatformCrypto::PlatformImportRsaPublicKey( |
+ const CryptoData& modulus_data, |
+ const CryptoData& exponent_data, |
const blink::WebCryptoAlgorithm& algorithm, |
bool extractable, |
blink::WebCryptoKeyUsageMask usage_mask, |
blink::WebCryptoKey* key) { |
- if (!modulus_size) |
+ if (!modulus_data.byte_length()) |
return Status::ErrorImportRsaEmptyModulus(); |
- if (!exponent_size) |
+ if (!exponent_data.byte_length()) |
return Status::ErrorImportRsaEmptyExponent(); |
- DCHECK(modulus_data); |
- DCHECK(exponent_data); |
+ DCHECK(modulus_data.bytes()); |
+ DCHECK(exponent_data.bytes()); |
// NSS does not provide a way to create an RSA public key directly from the |
// modulus and exponent values, but it can import an DER-encoded ASN.1 blob |
@@ -1379,10 +1059,10 @@ Status WebCryptoImpl::ImportRsaPublicKeyInternal( |
SECItem exponent; |
}; |
const RsaPublicKeyData pubkey_in = { |
- {siUnsignedInteger, const_cast<unsigned char*>(modulus_data), |
- modulus_size}, |
- {siUnsignedInteger, const_cast<unsigned char*>(exponent_data), |
- exponent_size}}; |
+ {siUnsignedInteger, const_cast<unsigned char*>(modulus_data.bytes()), |
+ modulus_data.byte_length()}, |
+ {siUnsignedInteger, const_cast<unsigned char*>(exponent_data.bytes()), |
+ exponent_data.byte_length()}}; |
const SEC_ASN1Template rsa_public_key_template[] = { |
{SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)}, |
{SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), }, |
@@ -1390,8 +1070,8 @@ Status WebCryptoImpl::ImportRsaPublicKeyInternal( |
{0, }}; |
// DER-encode the public key. |
- crypto::ScopedSECItem pubkey_der(SEC_ASN1EncodeItem( |
- NULL, NULL, &pubkey_in, rsa_public_key_template)); |
+ crypto::ScopedSECItem pubkey_der( |
+ SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); |
if (!pubkey_der) |
return Status::Error(); |
@@ -1401,7 +1081,7 @@ Status WebCryptoImpl::ImportRsaPublicKeyInternal( |
if (!pubkey) |
return Status::Error(); |
- *key = blink::WebCryptoKey::create(new PublicKeyHandle(pubkey.Pass()), |
+ *key = blink::WebCryptoKey::create(new PlatformPublicKey(pubkey.Pass()), |
blink::WebCryptoKeyTypePublic, |
extractable, |
algorithm, |
@@ -1409,4 +1089,5 @@ Status WebCryptoImpl::ImportRsaPublicKeyInternal( |
return Status::Success(); |
} |
+} // namespace webcrypto |
} // namespace content |