Chromium Code Reviews| 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..2ae4a8d2c791e9531936f119f0eba40c56837127 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,7 +715,7 @@ TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { |
| const unsigned modulus_length = 256; |
| const std::vector<uint8> public_exponent = HexStringToBytes("010001"); |
| blink::WebCryptoAlgorithm algorithm = |
| - CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| + CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| modulus_length, |
|
eroman
2013/11/20 23:57:44
indentation needs to change
padolph
2013/11/21 01:20:13
Done.
|
| public_exponent); |
| bool extractable = false; |
| @@ -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 |