Index: content/renderer/webcrypto/webcrypto_impl_nss.cc |
diff --git a/content/renderer/webcrypto/webcrypto_impl_nss.cc b/content/renderer/webcrypto/webcrypto_impl_nss.cc |
index c384dade4fe21775fd0d4deecc903b3979f85ce9..bf6fcdac8179fcba8f65c315b3ee54ed6803d62b 100644 |
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc |
+++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc |
@@ -491,9 +491,47 @@ bool WebCryptoImpl::EncryptInternal( |
const unsigned char* data, |
unsigned data_size, |
blink::WebArrayBuffer* buffer) { |
+ |
+ DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
+ DCHECK(key.handle()); |
+ DCHECK(buffer); |
+ |
if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
return AesCbcEncryptDecrypt( |
CKA_ENCRYPT, algorithm, key, data, data_size, buffer); |
+ } else if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5) { |
+ |
+ // RSAES encryption does not support empty input |
+ if (!data_size) |
+ return false; |
+ DCHECK(data); |
+ |
+ if (key.type() != blink::WebCryptoKeyTypePublic) |
+ return false; |
+ |
+ PublicKeyHandle* const public_key = |
+ reinterpret_cast<PublicKeyHandle*>(key.handle()); |
+ |
+ const unsigned encrypted_length_bytes = |
+ SECKEY_PublicKeyStrength(public_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) |
+ return false; |
+ |
+ *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(), |
+ buffer_data, |
+ const_cast<unsigned char*>(data), |
+ data_size, |
+ NULL) != SECSuccess) { |
+ return false; |
+ } |
+ return true; |
} |
return false; |
@@ -505,9 +543,49 @@ bool WebCryptoImpl::DecryptInternal( |
const unsigned char* data, |
unsigned data_size, |
blink::WebArrayBuffer* buffer) { |
+ |
+ DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
+ DCHECK(key.handle()); |
+ DCHECK(buffer); |
+ |
if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
return AesCbcEncryptDecrypt( |
CKA_DECRYPT, algorithm, key, data, data_size, buffer); |
+ } else if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5) { |
+ |
+ // RSAES decryption does not support empty input |
+ if (!data_size) |
+ return false; |
+ DCHECK(data); |
+ |
+ if (key.type() != blink::WebCryptoKeyTypePrivate) |
+ return false; |
+ |
+ PrivateKeyHandle* const private_key = |
+ reinterpret_cast<PrivateKeyHandle*>(key.handle()); |
+ |
+ const int modulus_length_bytes = |
+ PK11_GetPrivateModulusLen(private_key->key()); |
+ if (modulus_length_bytes <= 0) |
+ return false; |
+ const unsigned 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()); |
+ |
+ unsigned output_length_bytes = 0; |
+ if (PK11_PrivDecryptPKCS1(private_key->key(), |
+ buffer_data, |
+ &output_length_bytes, |
+ max_output_length_bytes, |
+ const_cast<unsigned char*>(data), |
+ data_size) != SECSuccess) { |
+ return false; |
+ } |
+ DCHECK_LE(output_length_bytes, max_output_length_bytes); |
+ WebCryptoImpl::ShrinkBuffer(buffer, output_length_bytes); |
+ return true; |
} |
return false; |