Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1758)

Unified Diff: content/renderer/webcrypto/webcrypto_impl_unittest.cc

Issue 68303009: [webcrypto] Add RSASSA-PKCS1-v1_5 sign and verify for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes for eroman Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/webcrypto/webcrypto_impl_unittest.cc
diff --git a/content/renderer/webcrypto/webcrypto_impl_unittest.cc b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
index ffe2377a2b6b8ab2b87327c45dbcc31678969466..c5468ffb448dabec4b39cd9431f5251daa65c8b9 100644
--- a/content/renderer/webcrypto/webcrypto_impl_unittest.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
@@ -40,19 +40,19 @@ blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
}
blink::WebCryptoAlgorithm CreateHmacAlgorithm(
- blink::WebCryptoAlgorithmId hashId) {
+ blink::WebCryptoAlgorithmId hash_id) {
return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
blink::WebCryptoAlgorithmIdHmac,
- new blink::WebCryptoHmacParams(CreateAlgorithm(hashId)));
+ new blink::WebCryptoHmacParams(CreateAlgorithm(hash_id)));
}
blink::WebCryptoAlgorithm CreateHmacKeyAlgorithm(
- blink::WebCryptoAlgorithmId hashId,
+ blink::WebCryptoAlgorithmId hash_id,
unsigned hash_length) {
// hash_length < 0 means unspecified
return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
blink::WebCryptoAlgorithmIdHmac,
- new blink::WebCryptoHmacKeyParams(CreateAlgorithm(hashId),
+ new blink::WebCryptoHmacKeyParams(CreateAlgorithm(hash_id),
(hash_length != 0),
hash_length));
}
@@ -80,8 +80,7 @@ blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(
new blink::WebCryptoAesKeyGenParams(key_length_bits));
}
-#if !defined(USE_OPENSSL)
-blink::WebCryptoAlgorithm CreateRsaAlgorithm(
+blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm(
blink::WebCryptoAlgorithmId algorithm_id,
unsigned modulus_length,
const std::vector<uint8>& public_exponent) {
@@ -93,7 +92,26 @@ blink::WebCryptoAlgorithm CreateRsaAlgorithm(
new blink::WebCryptoRsaKeyGenParams(
modulus_length, Start(public_exponent), public_exponent.size()));
}
-#endif // !defined(USE_OPENSSL)
+
+// TODO(padolph): Move to webcrypto_util
+bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) {
+ return alg_id == blink::WebCryptoAlgorithmIdSha1 ||
+ alg_id == blink::WebCryptoAlgorithmIdSha224 ||
+ alg_id == blink::WebCryptoAlgorithmIdSha256 ||
+ alg_id == blink::WebCryptoAlgorithmIdSha384 ||
+ alg_id == blink::WebCryptoAlgorithmIdSha512;
+}
+
+blink::WebCryptoAlgorithm CreateRsaAlgorithmWithInnerHash(
+ blink::WebCryptoAlgorithmId algorithm_id,
+ blink::WebCryptoAlgorithmId hash_id) {
+ DCHECK(algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
+ algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep);
+ DCHECK(IsHashAlgorithm(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm_id,
+ new blink::WebCryptoRsaSsaParams(CreateAlgorithm(hash_id)));
+}
} // namespace
@@ -697,9 +715,9 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
const unsigned modulus_length = 256;
const std::vector<uint8> public_exponent = HexStringToBytes("010001");
blink::WebCryptoAlgorithm algorithm =
- CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
- modulus_length,
- public_exponent);
+ CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ public_exponent);
bool extractable = false;
const blink::WebCryptoKeyUsageMask usage_mask = 0;
blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
@@ -716,7 +734,7 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
EXPECT_EQ(usage_mask, private_key.usages());
// Fail with bad modulus.
- algorithm = CreateRsaAlgorithm(
+ algorithm = CreateRsaKeyGenAlgorithm(
blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent);
EXPECT_FALSE(GenerateKeyPairInternal(
algorithm, extractable, usage_mask, &public_key, &private_key));
@@ -724,25 +742,28 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
// Fail with bad exponent: larger than unsigned long.
unsigned exponent_length = sizeof(unsigned long) + 1; // NOLINT
const std::vector<uint8> long_exponent(exponent_length, 0x01);
- algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
- modulus_length,
- long_exponent);
+ algorithm = CreateRsaKeyGenAlgorithm(
+ blink::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(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
- modulus_length,
- empty_exponent);
+ algorithm = CreateRsaKeyGenAlgorithm(
+ blink::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(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
- modulus_length,
- exponent_with_leading_zeros);
+ algorithm = CreateRsaKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ exponent_with_leading_zeros);
EXPECT_FALSE(GenerateKeyPairInternal(
algorithm, extractable, usage_mask, &public_key, &private_key));
@@ -750,9 +771,10 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
public_exponent.begin(),
public_exponent.end());
- algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
- modulus_length,
- exponent_with_leading_zeros);
+ algorithm = CreateRsaKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
+ modulus_length,
+ exponent_with_leading_zeros);
EXPECT_TRUE(GenerateKeyPairInternal(
algorithm, extractable, usage_mask, &public_key, &private_key));
EXPECT_FALSE(public_key.isNull());
@@ -765,7 +787,7 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
EXPECT_EQ(usage_mask, private_key.usages());
// Successful WebCryptoAlgorithmIdRsaOaep key generation.
- algorithm = CreateRsaAlgorithm(
+ algorithm = CreateRsaKeyGenAlgorithm(
blink::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent);
EXPECT_TRUE(GenerateKeyPairInternal(
algorithm, extractable, usage_mask, &public_key, &private_key));
@@ -779,9 +801,10 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
EXPECT_EQ(usage_mask, private_key.usages());
// Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation.
- algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
- modulus_length,
- public_exponent);
+ algorithm = CreateRsaKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ modulus_length,
+ public_exponent);
EXPECT_TRUE(GenerateKeyPairInternal(
algorithm, extractable, usage_mask, &public_key, &private_key));
EXPECT_FALSE(public_key.isNull());
@@ -794,6 +817,132 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
EXPECT_EQ(usage_mask, private_key.usages());
}
+TEST_F(WebCryptoImplTest, SignVerifyRsa) {
+
+ // Generate an RSA key pair.
+ blink::WebCryptoAlgorithm algorithm =
+ CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ 1024,
+ HexStringToBytes("010001"));
+ const blink::WebCryptoKeyUsageMask usage_mask =
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify;
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+ EXPECT_TRUE(GenerateKeyPairInternal(
+ algorithm, true, usage_mask, &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+
+ algorithm = CreateRsaAlgorithmWithInnerHash(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1);
+ blink::WebArrayBuffer signature;
+ bool signature_match = false;
+
+ const char* kTestData[] = {"", "00", "010203040506070809"};
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) {
+
+ SCOPED_TRACE(i);
+
+ // Sign data with the private key.
+ const std::vector<uint8> data = HexStringToBytes(kTestData[i]);
+ ASSERT_TRUE(SignInternal(algorithm, private_key, data, &signature));
+
+ // Verify the signature with the public key.
+ signature_match = false;
+ EXPECT_TRUE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ static_cast<const unsigned char*>(signature.data()),
+ signature.byteLength(),
+ data,
+ &signature_match));
+ EXPECT_TRUE(signature_match);
+ }
+
+ const std::vector<uint8> data = HexStringToBytes("010203040506070809");
+ ASSERT_TRUE(SignInternal(algorithm, private_key, data, &signature));
+
+ // Ensure truncated signature does not verify by passing one less byte.
+ signature_match = false;
+ EXPECT_TRUE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ static_cast<const unsigned char*>(signature.data()),
+ signature.byteLength() - 1,
+ data,
+ &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure corrupted signature does not verify.
+ std::vector<uint8> corrupt_sig(
+ static_cast<uint8*>(signature.data()),
+ static_cast<uint8*>(signature.data()) + signature.byteLength());
+ corrupt_sig[corrupt_sig.size() / 2] ^= 0x1;
+ signature_match = false;
+ EXPECT_TRUE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ Start(corrupt_sig),
+ corrupt_sig.size(),
+ data,
+ &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure extra long signature does not cause issues and fails.
+ const unsigned char kLongSignature[1024] = { 0 };
+ EXPECT_TRUE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ kLongSignature,
+ sizeof(kLongSignature),
+ data,
+ &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure can't verify using a private key.
+ EXPECT_FALSE(VerifySignatureInternal(
+ algorithm,
+ private_key,
+ static_cast<const unsigned char*>(signature.data()),
+ signature.byteLength(),
+ data,
+ &signature_match));
+
+ // Ensure can't sign using a public key.
+ EXPECT_FALSE(SignInternal(algorithm, public_key, data, &signature));
+
+ // TODO(padolph): Not sure this kind of test is required here, it might be
+ // more appropriate on the Blink side.
+ // Fail sign and verify with malformed algorithm (no inner hash)
+ algorithm = CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5);
+ EXPECT_FALSE(SignInternal(algorithm, private_key, data, &signature));
+ EXPECT_FALSE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ static_cast<const unsigned char*>(signature.data()),
+ signature.byteLength(),
+ data,
+ &signature_match));
+
+ // TODO(padolph): Not sure this kind of test is required here, it might be
+ // more appropriate on the Blink side.
+ // Fail sign and verify with incompatible algorithm
+ algorithm = CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
+ EXPECT_FALSE(SignInternal(algorithm, private_key, data, &signature));
+ EXPECT_FALSE(VerifySignatureInternal(
+ algorithm,
+ public_key,
+ static_cast<const unsigned char*>(signature.data()),
+ signature.byteLength(),
+ data,
+ &signature_match));
+}
+
+// TODO(padolph): RSA sign sample sets. NIST RSA test keys are in discrete
+// format (primes and coefficients), so we need both public and private JWK key
+// import working first.
+
#endif // #if !defined(USE_OPENSSL)
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698