| 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
|
|
|