In this update we have:
- Added the verified platform tests. These tests show how some
platforms, when verified are allowed to by pass the normal policy
restrictions. This is done with ChromeOS, thus the name of the
tests use "chrome_os".
- Removed WB_RESULT_INVALID_PADDING. This error was when we the
non-license APIs exposed a AES function with padding. However,
those functions have been removed from the API and this error is
no longer used by the API.
- Tests have been updated to avoid signed-vs-unsigned comparison
and to use the Chromium path to gTest (which is mocked in this
library).
- Tests have been updated to use a new test base and golden data
system to make them easier to read.
269 lines
11 KiB
C++
269 lines
11 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright 2016 Google LLC.
|
|
//
|
|
// This software is licensed under the terms defined in the Widevine Master
|
|
// License Agreement. For a copy of this agreement, please contact
|
|
// widevine-licensing@google.com.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Description:
|
|
// Unit test for rsa_key RSA encryption and signing.
|
|
|
|
#include "crypto_utils/rsa_key.h"
|
|
|
|
#include <memory>
|
|
|
|
#include "crypto_utils/rsa_test_keys.h"
|
|
#include "crypto_utils/rsa_util.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace widevine {
|
|
|
|
static const char kTestMessage[] =
|
|
"A fool thinks himself to be wise, but a wise man knows himself to be a "
|
|
"fool.";
|
|
|
|
class RsaKeyTest : public ::testing::Test {
|
|
protected:
|
|
void TestEncryption(std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key);
|
|
|
|
void TestSigning(std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key);
|
|
|
|
void TestSigningSha256Pkcs7(std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key);
|
|
|
|
RsaTestKeys test_keys_;
|
|
RsaKeyFactory factory_;
|
|
};
|
|
|
|
TEST_F(RsaKeyTest, CopyConstructor) {
|
|
std::unique_ptr<RsaPrivateKey> private_key(
|
|
RsaPrivateKey::Create(test_keys_.private_test_key_2_2048_bits()));
|
|
std::unique_ptr<RsaPublicKey> public_key(
|
|
RsaPublicKey::Create(test_keys_.public_test_key_2_2048_bits()));
|
|
|
|
std::unique_ptr<RsaPrivateKey> private_key_copy(
|
|
new RsaPrivateKey(*private_key));
|
|
std::unique_ptr<RsaPublicKey> public_key_copy(new RsaPublicKey(*public_key));
|
|
|
|
EXPECT_TRUE(public_key_copy->MatchesPublicKey(*public_key));
|
|
EXPECT_TRUE(public_key_copy->MatchesPrivateKey(*private_key));
|
|
|
|
EXPECT_TRUE(private_key_copy->MatchesPublicKey(*public_key));
|
|
EXPECT_TRUE(private_key_copy->MatchesPrivateKey(*private_key));
|
|
}
|
|
|
|
void RsaKeyTest::TestEncryption(std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key) {
|
|
ASSERT_TRUE(private_key);
|
|
ASSERT_TRUE(public_key);
|
|
std::string encrypted_message;
|
|
EXPECT_TRUE(public_key->Encrypt(kTestMessage, &encrypted_message));
|
|
std::string decrypted_message;
|
|
EXPECT_TRUE(private_key->Decrypt(encrypted_message, &decrypted_message));
|
|
EXPECT_EQ(kTestMessage, decrypted_message);
|
|
// Add a byte to the encrypted message.
|
|
std::string bad_enc_message(encrypted_message);
|
|
bad_enc_message += '\0';
|
|
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
|
// Remove a byte from the encrypted message.
|
|
bad_enc_message = encrypted_message.substr(0, encrypted_message.size() - 1);
|
|
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
|
// Change a byte in the encrypted message.
|
|
bad_enc_message = encrypted_message;
|
|
bad_enc_message[128] ^= 0x55;
|
|
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
|
}
|
|
|
|
void RsaKeyTest::TestSigning(std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key) {
|
|
ASSERT_TRUE(private_key);
|
|
ASSERT_TRUE(public_key);
|
|
std::string signature;
|
|
EXPECT_TRUE(private_key->GenerateSignature(kTestMessage, &signature));
|
|
EXPECT_TRUE(public_key->VerifySignature(kTestMessage, signature));
|
|
// Add a byte to the signature.
|
|
std::string bad_signature(signature);
|
|
bad_signature += '\0';
|
|
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
|
// Remove a byte from the signature.
|
|
bad_signature = signature.substr(0, signature.size() - 1);
|
|
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
|
// Change a byte in the signature.
|
|
bad_signature = signature;
|
|
bad_signature[32] ^= 0x55;
|
|
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
|
}
|
|
|
|
void RsaKeyTest::TestSigningSha256Pkcs7(
|
|
std::unique_ptr<RsaPrivateKey> private_key,
|
|
std::unique_ptr<RsaPublicKey> public_key) {
|
|
ASSERT_TRUE(private_key);
|
|
ASSERT_TRUE(public_key);
|
|
std::string signature;
|
|
EXPECT_TRUE(
|
|
private_key->GenerateSignatureSha256Pkcs7(kTestMessage, &signature));
|
|
EXPECT_TRUE(public_key->VerifySignatureSha256Pkcs7(kTestMessage, signature));
|
|
// Add a byte to the signature.
|
|
std::string bad_signature(signature);
|
|
bad_signature += '\0';
|
|
EXPECT_FALSE(
|
|
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
|
// Remove a byte from the signature.
|
|
bad_signature = signature.substr(0, signature.size() - 1);
|
|
EXPECT_FALSE(
|
|
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
|
// Change a byte in the signature.
|
|
bad_signature = signature;
|
|
bad_signature[32] ^= 0x55;
|
|
EXPECT_FALSE(
|
|
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, BadKey) {
|
|
std::unique_ptr<RsaPrivateKey> private_key(
|
|
RsaPrivateKey::Create("bad_private_key"));
|
|
EXPECT_TRUE(!private_key);
|
|
std::unique_ptr<RsaPublicKey> public_key(
|
|
RsaPublicKey::Create("bad_public_key"));
|
|
EXPECT_TRUE(!public_key);
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, EncryptAndDecrypt_3072) {
|
|
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
|
TestEncryption(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
TestEncryption(factory_.CreateFromPkcs1PrivateKey(private_key),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, EncryptAndDecrypt_2048) {
|
|
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
|
TestEncryption(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
|
|
std::string pkcs8_key;
|
|
std::string passphrase("passphrase");
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
|
private_key, passphrase, &pkcs8_key));
|
|
TestEncryption(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
|
TestEncryption(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, RsaPublicKeyFromPrivateKey) {
|
|
std::unique_ptr<RsaPrivateKey> private_key(
|
|
RsaPrivateKey::Create(test_keys_.private_test_key_2_2048_bits()));
|
|
ASSERT_TRUE(private_key);
|
|
std::unique_ptr<RsaPublicKey> public_key(new RsaPublicKey(*private_key));
|
|
ASSERT_TRUE(public_key);
|
|
|
|
EXPECT_TRUE(private_key->MatchesPublicKey(*public_key));
|
|
EXPECT_TRUE(public_key->MatchesPrivateKey(*private_key));
|
|
|
|
TestEncryption(std::move(private_key), std::move(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, SignAndVerify_3072) {
|
|
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
|
TestSigning(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
TestSigning(factory_.CreateFromPkcs1PrivateKey(private_key),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, SignAndVerify_2048) {
|
|
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
|
TestSigning(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
|
|
std::string pkcs8_key;
|
|
std::string passphrase("passphrase");
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
|
private_key, passphrase, &pkcs8_key));
|
|
TestSigning(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
|
TestSigning(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, SignAndVerifySha256Pkcs7_3072) {
|
|
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
|
TestSigningSha256Pkcs7(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
TestSigningSha256Pkcs7(factory_.CreateFromPkcs1PrivateKey(private_key),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, SignAndVerifySha256Pkcs7_2048) {
|
|
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
|
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
|
TestSigningSha256Pkcs7(
|
|
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
|
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
|
|
|
std::string pkcs8_key;
|
|
std::string passphrase("passphrase");
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
|
private_key, passphrase, &pkcs8_key));
|
|
TestSigningSha256Pkcs7(
|
|
factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
|
|
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
|
TestSigningSha256Pkcs7(
|
|
factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
|
factory_.CreateFromPkcs1PublicKey(public_key));
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, KeySize) {
|
|
std::unique_ptr<RsaPrivateKey> private_key(
|
|
RsaPrivateKey::Create(test_keys_.private_test_key_2_2048_bits()));
|
|
std::unique_ptr<RsaPublicKey> public_key(
|
|
RsaPublicKey::Create(test_keys_.public_test_key_2_2048_bits()));
|
|
|
|
EXPECT_EQ(256u, private_key->KeySize());
|
|
EXPECT_EQ(256u, public_key->KeySize());
|
|
}
|
|
|
|
TEST_F(RsaKeyTest, RsaKeyMatch) {
|
|
std::unique_ptr<RsaPrivateKey> private_key2(
|
|
RsaPrivateKey::Create(test_keys_.private_test_key_2_2048_bits()));
|
|
std::unique_ptr<RsaPrivateKey> private_key3(
|
|
RsaPrivateKey::Create(test_keys_.private_test_key_3_2048_bits()));
|
|
std::unique_ptr<RsaPublicKey> public_key2(
|
|
RsaPublicKey::Create(test_keys_.public_test_key_2_2048_bits()));
|
|
std::unique_ptr<RsaPublicKey> public_key3(
|
|
RsaPublicKey::Create(test_keys_.public_test_key_3_2048_bits()));
|
|
|
|
EXPECT_TRUE(public_key2->MatchesPublicKey(*public_key2));
|
|
EXPECT_FALSE(public_key2->MatchesPublicKey(*public_key3));
|
|
EXPECT_TRUE(public_key2->MatchesPrivateKey(*private_key2));
|
|
EXPECT_FALSE(public_key2->MatchesPrivateKey(*private_key3));
|
|
|
|
EXPECT_TRUE(private_key2->MatchesPublicKey(*public_key2));
|
|
EXPECT_FALSE(private_key2->MatchesPublicKey(*public_key3));
|
|
EXPECT_TRUE(private_key2->MatchesPrivateKey(*private_key2));
|
|
EXPECT_FALSE(private_key2->MatchesPrivateKey(*private_key3));
|
|
}
|
|
|
|
} // namespace widevine
|