| 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 e8a0237a7d79088cde466e70a8f7b40935df7b7b..ad1a1a9d999bcfaaa8567a4844a472c9f59cf383 100644
|
| --- a/content/child/webcrypto/platform_crypto_nss.cc
|
| +++ b/content/child/webcrypto/platform_crypto_nss.cc
|
| @@ -292,6 +292,50 @@ Status NssSupportsRsaOaep() {
|
| "later");
|
| }
|
|
|
| +#if defined(USE_NSS) && !defined(OS_CHROMEOS)
|
| +Status ErrorRsaKeyImportNotSupported() {
|
| + return Status::ErrorUnsupported(
|
| + "NSS version must be at least 3.16.2 for RSA key import. See "
|
| + "http://crbug.com/380424");
|
| +}
|
| +
|
| +Status NssSupportsKeyImport(blink::WebCryptoAlgorithmId algorithm) {
|
| + // Prior to NSS 3.16.2 RSA key parameters were not validated. This is
|
| + // a security problem for RSA private key import from JWK which uses a
|
| + // CKA_ID based on the public modulus to retrieve the private key.
|
| +
|
| + if (!IsAlgorithmRsa(algorithm))
|
| + return Status::Success();
|
| +
|
| + if (!NSS_VersionCheck("3.16.2"))
|
| + return ErrorRsaKeyImportNotSupported();
|
| +
|
| + // Also ensure that the version of Softoken is 3.16.2 or later.
|
| + crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
|
| + CK_SLOT_INFO info = {};
|
| + if (PK11_GetSlotInfo(slot.get(), &info) != SECSuccess)
|
| + return ErrorRsaKeyImportNotSupported();
|
| +
|
| + // CK_SLOT_INFO.hardwareVersion contains the major.minor
|
| + // version info for Softoken in the corresponding .major/.minor
|
| + // fields, and .firmwareVersion contains the patch.build
|
| + // version info (in the .major/.minor fields)
|
| + if ((info.hardwareVersion.major > 3) ||
|
| + (info.hardwareVersion.major == 3 &&
|
| + (info.hardwareVersion.minor > 16 ||
|
| + (info.hardwareVersion.minor == 16 &&
|
| + info.firmwareVersion.major >= 2)))) {
|
| + return Status::Success();
|
| + }
|
| +
|
| + return ErrorRsaKeyImportNotSupported();
|
| +}
|
| +#else
|
| +Status NssSupportsKeyImport(blink::WebCryptoAlgorithmId) {
|
| + return Status::Success();
|
| +}
|
| +#endif
|
| +
|
| // 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) {
|
| @@ -987,6 +1031,10 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
|
| bool extractable,
|
| blink::WebCryptoKeyUsageMask usage_mask,
|
| blink::WebCryptoKey* key) {
|
| + Status status = NssSupportsKeyImport(algorithm.id());
|
| + if (status.IsError())
|
| + return status;
|
| +
|
| DCHECK(key);
|
|
|
| if (!key_data.byte_length())
|
| @@ -1016,7 +1064,7 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
|
| return Status::ErrorUnexpected();
|
|
|
| scoped_ptr<PublicKey> key_handle;
|
| - Status status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
|
| + status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
|
| if (status.IsError())
|
| return status;
|
|
|
| @@ -1156,6 +1204,10 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
|
| bool extractable,
|
| blink::WebCryptoKeyUsageMask usage_mask,
|
| blink::WebCryptoKey* key) {
|
| + Status status = NssSupportsKeyImport(algorithm.id());
|
| + if (status.IsError())
|
| + return status;
|
| +
|
| DCHECK(key);
|
|
|
| if (!key_data.byte_length())
|
| @@ -1191,8 +1243,7 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
|
| return Status::ErrorUnexpected();
|
|
|
| scoped_ptr<PrivateKey> key_handle;
|
| - Status status =
|
| - PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
|
| + status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
|
| if (status.IsError())
|
| return status;
|
|
|
| @@ -1689,6 +1740,10 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
|
| const CryptoData& exponent2,
|
| const CryptoData& coefficient,
|
| blink::WebCryptoKey* key) {
|
| + Status status = NssSupportsKeyImport(algorithm.id());
|
| + if (status.IsError())
|
| + return status;
|
| +
|
| CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
|
| CK_KEY_TYPE key_type = CKK_RSA;
|
| CK_BBOOL ck_false = CK_FALSE;
|
| @@ -1770,8 +1825,7 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
|
| return Status::ErrorUnexpected();
|
|
|
| scoped_ptr<PrivateKey> key_handle;
|
| - Status status =
|
| - PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
|
| + status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
|
| if (status.IsError())
|
| return status;
|
|
|
|
|