summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorpadolph@netflix.com <padolph@netflix.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-02 13:27:30 +0000
committerpadolph@netflix.com <padolph@netflix.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-02 13:27:30 +0000
commit043cf1d3648a1ef67f4a1471375c78c6ee7bdcb5 (patch)
treec27f11461458cb668335d325f0a756259526c383 /content
parent1868df58c9036ff732383908401963fda5c5bd9b (diff)
downloadchromium_src-043cf1d3648a1ef67f4a1471375c78c6ee7bdcb5.zip
chromium_src-043cf1d3648a1ef67f4a1471375c78c6ee7bdcb5.tar.gz
chromium_src-043cf1d3648a1ef67f4a1471375c78c6ee7bdcb5.tar.bz2
[webcrypto] Add RSA key generation using NSS.
BUG=267888 TEST=content_unittests --gtest_filter="WebCryptoImpl*" R=bryaneyler@google.com,eroman@chromium.org,rsleevi@chromium.org Review URL: https://codereview.chromium.org/34583010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232598 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/renderer/webcrypto/webcrypto_impl.cc53
-rw-r--r--content/renderer/webcrypto/webcrypto_impl.h6
-rw-r--r--content/renderer/webcrypto/webcrypto_impl_nss.cc146
-rw-r--r--content/renderer/webcrypto/webcrypto_impl_openssl.cc11
-rw-r--r--content/renderer/webcrypto/webcrypto_impl_unittest.cc147
5 files changed, 342 insertions, 21 deletions
diff --git a/content/renderer/webcrypto/webcrypto_impl.cc b/content/renderer/webcrypto/webcrypto_impl.cc
index 9275783..47b7ef5 100644
--- a/content/renderer/webcrypto/webcrypto_impl.cc
+++ b/content/renderer/webcrypto/webcrypto_impl.cc
@@ -12,6 +12,18 @@
namespace content {
+namespace {
+
+bool IsAlgorithmAsymmetric(const WebKit::WebCryptoAlgorithm& algorithm) {
+ // TODO(padolph): include all other asymmetric algorithms once they are
+ // defined, e.g. EC and DH.
+ return (algorithm.id() == WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
+ algorithm.id() == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
+ algorithm.id() == WebKit::WebCryptoAlgorithmIdRsaOaep);
+}
+
+} // namespace
+
WebCryptoImpl::WebCryptoImpl() {
Init();
}
@@ -94,15 +106,38 @@ void WebCryptoImpl::generateKey(
WebKit::WebCryptoKeyUsageMask usage_mask,
WebKit::WebCryptoResult result) {
DCHECK(!algorithm.isNull());
- WebKit::WebCryptoKey key = NullKey();
- if (!GenerateKeyInternal(algorithm, extractable, usage_mask, &key)) {
- result.completeWithError();
+ if (IsAlgorithmAsymmetric(algorithm)) {
+ WebKit::WebCryptoKey public_key = WebKit::WebCryptoKey::createNull();
+ WebKit::WebCryptoKey private_key = WebKit::WebCryptoKey::createNull();
+ if (!GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key)) {
+ result.completeWithError();
+ } 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());
+ // TODO(padolph): The public key should probably always be extractable,
+ // regardless of the input 'extractable' parameter, but that is not called
+ // out in the Web Crypto API spec.
+ // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23695
+ DCHECK_EQ(extractable, 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 {
- DCHECK(key.handle());
- DCHECK_EQ(algorithm.id(), key.algorithm().id());
- DCHECK_EQ(extractable, key.extractable());
- DCHECK_EQ(usage_mask, key.usages());
- result.completeWithKey(key);
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
+ if (!GenerateKeyInternal(algorithm, extractable, usage_mask, &key)) {
+ result.completeWithError();
+ } 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);
+ }
}
}
@@ -114,7 +149,7 @@ void WebCryptoImpl::importKey(
bool extractable,
WebKit::WebCryptoKeyUsageMask usage_mask,
WebKit::WebCryptoResult result) {
- WebKit::WebCryptoKey key = NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
if (!ImportKeyInternal(format,
key_data,
key_data_size,
diff --git a/content/renderer/webcrypto/webcrypto_impl.h b/content/renderer/webcrypto/webcrypto_impl.h
index 5979b62..c1c5592 100644
--- a/content/renderer/webcrypto/webcrypto_impl.h
+++ b/content/renderer/webcrypto/webcrypto_impl.h
@@ -92,6 +92,12 @@ class CONTENT_EXPORT WebCryptoImpl
bool extractable,
WebKit::WebCryptoKeyUsageMask usage_mask,
WebKit::WebCryptoKey* key);
+ bool GenerateKeyPairInternal(
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ WebKit::WebCryptoKeyUsageMask usage_mask,
+ WebKit::WebCryptoKey* public_key,
+ WebKit::WebCryptoKey* private_key);
bool ImportKeyInternal(
WebKit::WebCryptoKeyFormat format,
const unsigned char* key_data,
diff --git a/content/renderer/webcrypto/webcrypto_impl_nss.cc b/content/renderer/webcrypto/webcrypto_impl_nss.cc
index 452d2a7..2b143a5 100644
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
@@ -24,10 +24,7 @@ namespace {
class SymKeyHandle : public WebKit::WebCryptoKeyHandle {
public:
- explicit SymKeyHandle(crypto::ScopedPK11SymKey key) {
- DCHECK(!key_.get());
- key_ = key.Pass();
- }
+ explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
PK11SymKey* key() { return key_.get(); }
@@ -37,6 +34,32 @@ class SymKeyHandle : public WebKit::WebCryptoKeyHandle {
DISALLOW_COPY_AND_ASSIGN(SymKeyHandle);
};
+class PublicKeyHandle : public WebKit::WebCryptoKeyHandle {
+ public:
+ explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key)
+ : key_(key.Pass()) {}
+
+ SECKEYPublicKey* key() { return key_.get(); }
+
+ private:
+ crypto::ScopedSECKEYPublicKey key_;
+
+ DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle);
+};
+
+class PrivateKeyHandle : public WebKit::WebCryptoKeyHandle {
+ public:
+ explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key)
+ : key_(key.Pass()) {}
+
+ SECKEYPrivateKey* key() { return key_.get(); }
+
+ private:
+ crypto::ScopedSECKEYPrivateKey key_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle);
+};
+
HASH_HashType WebCryptoAlgorithmToNSSHashType(
const WebKit::WebCryptoAlgorithm& algorithm) {
switch (algorithm.id()) {
@@ -102,7 +125,7 @@ bool AesCbcEncryptDecrypt(
if (!context.get())
return false;
- // Oddly PK11_CipherOp takes input and output lenths as "int" rather than
+ // Oddly PK11_CipherOp takes input and output lengths as "int" rather than
// "unsigned". Do some checks now to avoid integer overflowing.
if (data_size >= INT_MAX - AES_BLOCK_SIZE) {
// TODO(eroman): Handle this by chunking the input fed into NSS. Right now
@@ -193,6 +216,28 @@ unsigned int WebCryptoHmacAlgorithmToBlockSize(
}
}
+// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
+// to unsigned long.
+bool BigIntegerToLong(const uint8* data,
+ unsigned data_size,
+ unsigned long* result) {
+ // TODO(padolph): Is it correct to say that empty data is an error, or does it
+ // mean value 0? See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23655
+ if (data_size == 0)
+ return false;
+
+ *result = 0;
+ for (size_t i = 0; i < data_size; ++i) {
+ size_t reverse_i = data_size - i - 1;
+
+ if (reverse_i >= sizeof(unsigned long) && data[i])
+ return false; // Too large for a long.
+
+ *result |= data[i] << 8 * reverse_i;
+ }
+ return true;
+}
+
} // namespace
void WebCryptoImpl::Init() {
@@ -324,6 +369,97 @@ bool WebCryptoImpl::GenerateKeyInternal(
return true;
}
+bool WebCryptoImpl::GenerateKeyPairInternal(
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ WebKit::WebCryptoKeyUsageMask usage_mask,
+ WebKit::WebCryptoKey* public_key,
+ WebKit::WebCryptoKey* private_key) {
+
+ // TODO(padolph): Handle other asymmetric algorithm key generation.
+ switch (algorithm.id()) {
+ case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
+ case WebKit::WebCryptoAlgorithmIdRsaOaep:
+ case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
+ const WebKit::WebCryptoRsaKeyGenParams* const params =
+ algorithm.rsaKeyGenParams();
+ DCHECK(params);
+
+ crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
+ unsigned long public_exponent;
+ if (!slot || !params->modulusLength() ||
+ !BigIntegerToLong(params->publicExponent().data(),
+ params->publicExponent().size(),
+ &public_exponent) ||
+ !public_exponent) {
+ return false;
+ }
+
+ PK11RSAGenParams rsa_gen_params;
+ rsa_gen_params.keySizeInBits = params->modulusLength();
+ rsa_gen_params.pe = public_exponent;
+
+ // Flags are verified at the Blink layer; here the flags are set to all
+ // possible operations for the given key type.
+ CK_FLAGS operation_flags;
+ switch (algorithm.id()) {
+ case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
+ case WebKit::WebCryptoAlgorithmIdRsaOaep:
+ operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
+ break;
+ case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
+ operation_flags = CKF_SIGN | CKF_VERIFY;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT |
+ CKF_SIGN | CKF_VERIFY | CKF_WRAP |
+ CKF_UNWRAP;
+ const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags.
+
+ // Note: NSS does not generate an sec_public_key if the call below fails,
+ // so there is no danger of a leaked sec_public_key.
+ SECKEYPublicKey* sec_public_key;
+ crypto::ScopedSECKEYPrivateKey scoped_sec_private_key(
+ PK11_GenerateKeyPairWithOpFlags(slot.get(),
+ CKM_RSA_PKCS_KEY_PAIR_GEN,
+ &rsa_gen_params,
+ &sec_public_key,
+ attribute_flags,
+ operation_flags,
+ operation_flags_mask,
+ NULL));
+ if (!private_key) {
+ return false;
+ }
+
+ // One extractable input parameter is provided, and the Web Crypto API
+ // spec at this time says it applies to both members of the key pair.
+ // This is probably not correct: it makes more operational sense to have
+ // extractable apply only to the private key and make the public key
+ // always extractable. For now implement what the spec says and track the
+ // spec bug here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=23695
+ *public_key = WebKit::WebCryptoKey::create(
+ new PublicKeyHandle(crypto::ScopedSECKEYPublicKey(sec_public_key)),
+ WebKit::WebCryptoKeyTypePublic,
+ extractable, // probably should be 'true' always
+ algorithm,
+ usage_mask);
+ *private_key = WebKit::WebCryptoKey::create(
+ new PrivateKeyHandle(scoped_sec_private_key.Pass()),
+ WebKit::WebCryptoKeyTypePrivate,
+ extractable,
+ algorithm,
+ usage_mask);
+
+ return true;
+ }
+ default:
+ return false;
+ }
+}
bool WebCryptoImpl::ImportKeyInternal(
WebKit::WebCryptoKeyFormat format,
diff --git a/content/renderer/webcrypto/webcrypto_impl_openssl.cc b/content/renderer/webcrypto/webcrypto_impl_openssl.cc
index 83ae45c..23f89c2 100644
--- a/content/renderer/webcrypto/webcrypto_impl_openssl.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_openssl.cc
@@ -299,6 +299,17 @@ bool WebCryptoImpl::GenerateKeyInternal(
return true;
}
+bool WebCryptoImpl::GenerateKeyPairInternal(
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ WebKit::WebCryptoKeyUsageMask usage_mask,
+ WebKit::WebCryptoKey* public_key,
+ WebKit::WebCryptoKey* private_key) {
+ // TODO(padolph): Placeholder for OpenSSL implementation.
+ // Issue http://crbug.com/267888.
+ return false;
+}
+
bool WebCryptoImpl::ImportKeyInternal(
WebKit::WebCryptoKeyFormat format,
const unsigned char* key_data,
diff --git a/content/renderer/webcrypto/webcrypto_impl_unittest.cc b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
index 99d71ea..503bdb8 100644
--- a/content/renderer/webcrypto/webcrypto_impl_unittest.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
@@ -15,6 +15,7 @@
#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/WebCryptoKey.h"
namespace {
@@ -77,6 +78,19 @@ WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(
new WebKit::WebCryptoAesKeyGenParams(key_length_bits));
}
+WebKit::WebCryptoAlgorithm CreateRsaAlgorithm(
+ WebKit::WebCryptoAlgorithmId algorithm_id,
+ unsigned modulus_length,
+ const std::vector<uint8>& public_exponent) {
+ DCHECK(algorithm_id == WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
+ algorithm_id == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
+ algorithm_id == WebKit::WebCryptoAlgorithmIdRsaOaep);
+ return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm_id,
+ new WebKit::WebCryptoRsaKeyGenParams(
+ modulus_length, Start(public_exponent), public_exponent.size()));
+}
+
} // namespace
namespace content {
@@ -89,7 +103,7 @@ class WebCryptoImplTest : public testing::Test {
WebKit::WebCryptoKeyUsageMask usage) {
std::vector<uint8> key_raw = HexStringToBytes(key_hex);
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
bool extractable = true;
EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw,
Start(key_raw),
@@ -122,6 +136,16 @@ class WebCryptoImplTest : public testing::Test {
return crypto_.GenerateKeyInternal(algorithm, extractable, usage_mask, key);
}
+ bool GenerateKeyPairInternal(
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ WebKit::WebCryptoKeyUsageMask usage_mask,
+ WebKit::WebCryptoKey* public_key,
+ WebKit::WebCryptoKey* private_key) {
+ return crypto_.GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, public_key, private_key);
+ }
+
bool ImportKeyInternal(
WebKit::WebCryptoKeyFormat format,
const std::vector<uint8>& key_data,
@@ -473,7 +497,7 @@ TEST_F(WebCryptoImplTest, AesCbcFailures) {
std::vector<uint8> key_raw(1);
std::vector<uint8> iv(16);
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw,
key_raw,
CreateAesCbcAlgorithm(iv),
@@ -617,20 +641,20 @@ TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
TEST_F(WebCryptoImplTest, GenerateKeyAes) {
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key));
EXPECT_TRUE(key.handle());
EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
}
TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key));
EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key));
}
TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
WebKit::WebCryptoAlgorithm algorithm =
CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128);
ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
@@ -639,7 +663,7 @@ TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
}
TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
WebKit::WebCryptoAlgorithm algorithm =
CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0);
ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
@@ -648,7 +672,7 @@ TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
}
TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) {
- WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
+ WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
// This fails because the algorithm is null.
EXPECT_FALSE(ImportKeyInternal(
@@ -659,4 +683,113 @@ TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) {
&key));
}
+#if !defined(USE_OPENSSL)
+
+TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
+
+ // Note: using unrealistic short key lengths here to avoid bogging down tests.
+
+ // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation.
+ const unsigned modulus_length = 256;
+ const std::vector<uint8> public_exponent = HexStringToBytes("010001");
+ WebKit::WebCryptoAlgorithm algorithm =
+ CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ public_exponent);
+ const bool extractable = false;
+ const WebKit::WebCryptoKeyUsageMask usage_mask = 0;
+ WebKit::WebCryptoKey public_key = WebKit::WebCryptoKey::createNull();
+ WebKit::WebCryptoKey private_key = WebKit::WebCryptoKey::createNull();
+ EXPECT_TRUE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(extractable, public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(usage_mask, public_key.usages());
+ EXPECT_EQ(usage_mask, private_key.usages());
+
+ // Fail with bad modulus.
+ algorithm = CreateRsaAlgorithm(
+ WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent);
+ EXPECT_FALSE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+
+ // Fail with bad exponent: larger than unsigned long.
+ unsigned exponent_length = sizeof(unsigned long) + 1;
+ const std::vector<uint8> long_exponent(exponent_length, 0x01);
+ algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ long_exponent);
+ EXPECT_FALSE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+
+ // Fail with bad exponent: empty.
+ const std::vector<uint8> empty_exponent;
+ algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ empty_exponent);
+ EXPECT_FALSE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+
+ // Fail with bad exponent: all zeros.
+ std::vector<uint8> exponent_with_leading_zeros(15, 0x00);
+ algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ exponent_with_leading_zeros);
+ EXPECT_FALSE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+
+ // Key generation success using exponent with leading zeros.
+ exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
+ public_exponent.begin(),
+ public_exponent.end());
+ algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ exponent_with_leading_zeros);
+ EXPECT_TRUE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(extractable, public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(usage_mask, public_key.usages());
+ EXPECT_EQ(usage_mask, private_key.usages());
+
+ // Successful WebCryptoAlgorithmIdRsaOaep key generation.
+ algorithm = CreateRsaAlgorithm(
+ WebKit::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent);
+ EXPECT_TRUE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(extractable, public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(usage_mask, public_key.usages());
+ EXPECT_EQ(usage_mask, private_key.usages());
+
+ // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation.
+ algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ modulus_length,
+ public_exponent);
+ EXPECT_TRUE(GenerateKeyPairInternal(
+ algorithm, extractable, usage_mask, &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(extractable, public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(usage_mask, public_key.usages());
+ EXPECT_EQ(usage_mask, private_key.usages());
+}
+
+#endif // #if !defined(USE_OPENSSL)
+
} // namespace content