diff --git a/api/BUILD b/api/BUILD index 244fe12..055748d 100644 --- a/api/BUILD +++ b/api/BUILD @@ -56,12 +56,11 @@ cc_library( ) cc_library( - name = "license_builder", + name = "test_license_builder", testonly = True, - srcs = ["license_builder.cc"], - hdrs = ["license_builder.h"], + srcs = ["test_license_builder.cc"], + hdrs = ["test_license_builder.h"], deps = [ - "//chromium_deps/base", "//chromium_deps/cdm/keys:dev_certs", "//chromium_deps/cdm/protos:license_protocol_proto", "//crypto_utils:aes_cbc_encryptor", @@ -83,7 +82,7 @@ cc_library( deps = [ ":aead_whitebox", ":test_data", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", ], ) @@ -91,6 +90,7 @@ cc_library( name = "license_whitebox_test", testonly = True, srcs = [ + "license_whitebox_chromeos_test.cc", "license_whitebox_create_test.cc", "license_whitebox_decrypt_test.cc", "license_whitebox_get_secret_string_test.cc", @@ -107,12 +107,12 @@ cc_library( visibility = ["//visibility:public"], deps = [ ":golden_data", - ":license_builder", ":license_whitebox", ":test_data", + ":test_license_builder", "//chromium_deps/cdm/keys:api", "//chromium_deps/cdm/protos:license_protocol_proto", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", "//crypto_utils:rsa_key", ], ) diff --git a/api/aead_whitebox_create_test.cc b/api/aead_whitebox_create_test.cc index 4ca4a9d..1ff0f85 100644 --- a/api/aead_whitebox_create_test.cc +++ b/api/aead_whitebox_create_test.cc @@ -4,7 +4,7 @@ #include "api/aead_whitebox.h" #include "api/test_data.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace { diff --git a/api/aead_whitebox_cross_instance_test.cc b/api/aead_whitebox_cross_instance_test.cc index 5fa1e84..f486fc1 100644 --- a/api/aead_whitebox_cross_instance_test.cc +++ b/api/aead_whitebox_cross_instance_test.cc @@ -4,7 +4,7 @@ #include "api/aead_whitebox.h" #include "api/test_data.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace { // These tests focus on functionality that should and should not exist between diff --git a/api/aead_whitebox_decrypt_test.cc b/api/aead_whitebox_decrypt_test.cc index f7ad50a..a26e63e 100644 --- a/api/aead_whitebox_decrypt_test.cc +++ b/api/aead_whitebox_decrypt_test.cc @@ -4,7 +4,7 @@ #include "api/aead_whitebox.h" #include "api/test_data.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace { // For our decrypt tests, we assume that WB_Aead_Create() and WB_Aead_Encrypt() diff --git a/api/aead_whitebox_encrypt_test.cc b/api/aead_whitebox_encrypt_test.cc index b57ee0f..485d404 100644 --- a/api/aead_whitebox_encrypt_test.cc +++ b/api/aead_whitebox_encrypt_test.cc @@ -4,7 +4,7 @@ #include "api/aead_whitebox.h" #include "api/test_data.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace { // Regardless of implementation, we need to have enough room in our output diff --git a/api/license_whitebox_chromeos_test.cc b/api/license_whitebox_chromeos_test.cc new file mode 100644 index 0000000..8a93653 --- /dev/null +++ b/api/license_whitebox_chromeos_test.cc @@ -0,0 +1,205 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#include "api/license_whitebox.h" + +#include + +#include "api/golden_data.h" +#include "api/license_whitebox_test_base.h" +#include "api/result.h" +#include "api/test_license_builder.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace widevine { +namespace { +using RemoteAttestation = TestLicenseBuilder::RemoteAttestation; +using VerificationStatus = TestLicenseBuilder::VerificationStatus; + +// We can't use the actual keys with TEST_P, so define an enum that we can use +// to communicate which key to use. +enum class Key { + kCrypto, + kDecode, + kHardware, +}; + +} // namespace + +class LicenseWhiteboxChromeOSTest + : public LicenseWhiteboxTestBase, + public testing::WithParamInterface< + std::tuple> { + protected: + void SetUp() override { + LicenseWhiteboxTestBase::SetUp(); + + std::tie(key_, remote_attestation_, verification_status_) = GetParam(); + + LoadLicense(); + + // We know that the plaintext will be smaller than the ciphertext, so we + // use that to ensure the buffer is large enough. + plaintext_size_ = golden_data_.CBCContent().ciphertext.size(); + plaintext_.resize(plaintext_size_); + + // We make the assumption that the secret string can never be longer than + // the ciphertext. + secret_string_size_ = golden_data_.CBCContent().ciphertext.size(); + secret_string_.resize(secret_string_size_); + } + + // This requires that the remote attestation and verification status to be + // set before being called. + void LoadLicense() { + TestLicenseBuilder builder; + + // Only use CBC keys so that we can always use the CBC content. + builder.AddContentKey(golden_data_.CBCCryptoKey().level, + golden_data_.CBCCryptoKey().id, + golden_data_.CBCCryptoKey().content->key); + + builder.AddContentKey(golden_data_.CBCDecodeKey().level, + golden_data_.CBCDecodeKey().id, + golden_data_.CBCDecodeKey().content->key); + + builder.AddContentKey(golden_data_.CBCHardwareKey().level, + golden_data_.CBCHardwareKey().id, + golden_data_.CBCHardwareKey().content->key); + + builder.SetRemoteAttestation(remote_attestation_); + builder.SetVerificationStatus(verification_status_); + + License license; + builder.Build(*public_key_, &license); + + ASSERT_EQ(WB_License_ProcessLicenseResponse( + whitebox_, license.message.data(), license.message.size(), + license.signature.data(), license.signature.size(), + license.session_key.data(), license.session_key.size(), + license.request.data(), license.request.size()), + WB_RESULT_OK); + } + + // This is the strictest level of enforcement. It will be the last one + // checked. Any basic overrides, for example a crypto key in decrypt, + // will short-circuit it. + WB_Result GetExpectedPlatformVerificationResult() { + if (remote_attestation_ == RemoteAttestation::kUnverified) { + return WB_RESULT_INSUFFICIENT_SECURITY_LEVEL; + } + + if (verification_status_ == VerificationStatus::kOther) { + return WB_RESULT_INSUFFICIENT_SECURITY_LEVEL; + } + + if (remote_attestation_ == RemoteAttestation::kVerified) { + return WB_RESULT_OK; + } + + if (verification_status_ == VerificationStatus::kHardwareVerified) { + return WB_RESULT_OK; + } + + return WB_RESULT_INSUFFICIENT_SECURITY_LEVEL; + } + + WB_Result GetExpectedDecryptResult() { + if (key_ == Key::kCrypto) { + return WB_RESULT_OK; + } + + return GetExpectedPlatformVerificationResult(); + } + + // Since MaskedDecrypt() and GetSecretString() go hand-in-hand. This function + // will be used for both. + WB_Result GetExpectedMaskedDecryptResult() { + if (key_ == Key::kCrypto || key_ == Key::kDecode) { + return WB_RESULT_OK; + } + + return GetExpectedPlatformVerificationResult(); + } + + const GoldenData::Key* GetContentKey() const { + switch (key_) { + case Key::kCrypto: + return &golden_data_.CBCCryptoKey(); + case Key::kDecode: + return &golden_data_.CBCDecodeKey(); + case Key::kHardware: + return &golden_data_.CBCHardwareKey(); + } + return nullptr; + } + + Key key_; + RemoteAttestation remote_attestation_; + VerificationStatus verification_status_; + + // This is the buffer used to store the output of each decrypt and unmask + // call. + size_t plaintext_size_; + std::vector plaintext_; + + // This is the buffer used to store the secret string used to demask the + // result of WB_License_MaskedDecrypt(). + size_t secret_string_size_; + std::vector secret_string_; +}; + +TEST_P(LicenseWhiteboxChromeOSTest, Decrypt) { + const WB_Result expected_result = GetExpectedDecryptResult(); + + const GoldenData::Key* key = GetContentKey(); + ASSERT_NE(key, nullptr); + + const auto* content = key->content; + ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, key->id.data(), + key->id.size(), content->ciphertext.data(), + content->plaintext.size(), content->iv.data(), + content->iv.size(), plaintext_.data(), + &plaintext_size_), + expected_result); +} + +TEST_P(LicenseWhiteboxChromeOSTest, MaskedDecrypt) { + const WB_Result expected_result = GetExpectedMaskedDecryptResult(); + + const GoldenData::Key* key = GetContentKey(); + ASSERT_NE(key, nullptr); + + const auto* content = key->content; + ASSERT_EQ(WB_License_MaskedDecrypt( + whitebox_, WB_CIPHER_MODE_CBC, key->id.data(), key->id.size(), + content->ciphertext.data(), content->plaintext.size(), + content->iv.data(), content->iv.size(), plaintext_.data(), + &plaintext_size_), + expected_result); +} + +TEST_P(LicenseWhiteboxChromeOSTest, GetSecretString) { + const WB_Result expected_result = GetExpectedMaskedDecryptResult(); + + const GoldenData::Key* key = GetContentKey(); + ASSERT_NE(key, nullptr); + + ASSERT_EQ(WB_License_GetSecretString( + whitebox_, WB_CIPHER_MODE_CBC, key->id.data(), key->id.size(), + secret_string_.data(), &secret_string_size_), + expected_result); +} + +INSTANTIATE_TEST_SUITE_P( + AllCombinations, + LicenseWhiteboxChromeOSTest, + ::testing::Combine( + ::testing::Values(Key::kCrypto, Key::kDecode, Key::kHardware), + ::testing::Values(RemoteAttestation::kUnavailable, + RemoteAttestation::kUnverified, + RemoteAttestation::kVerified), + ::testing::Values(VerificationStatus::kUnavailable, + VerificationStatus::kOther, + VerificationStatus::kHardwareVerified))); + +} // namespace widevine diff --git a/api/license_whitebox_create_test.cc b/api/license_whitebox_create_test.cc index 33fe166..221b89e 100644 --- a/api/license_whitebox_create_test.cc +++ b/api/license_whitebox_create_test.cc @@ -5,7 +5,7 @@ #include #include "api/test_data.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace { diff --git a/api/license_whitebox_decrypt_test.cc b/api/license_whitebox_decrypt_test.cc index 365349f..b8df56a 100644 --- a/api/license_whitebox_decrypt_test.cc +++ b/api/license_whitebox_decrypt_test.cc @@ -7,11 +7,11 @@ #include #include "api/golden_data.h" -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -31,7 +31,7 @@ class LicenseWhiteboxDecryptTest : public LicenseWhiteboxTestBase { } void LoadLicense(const std::vector& padding) { - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, @@ -73,7 +73,7 @@ class LicenseWhiteboxDecryptTest : public LicenseWhiteboxTestBase { }; TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -90,7 +90,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCbcMode) { } TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, @@ -109,7 +109,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) { // We try to decrypt CBC encrypted data in CTR mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, @@ -128,7 +128,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCtrMode) { // We try to decrypt CTR encrypted data in CBC mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -145,7 +145,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCbcMode) { } TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -162,7 +162,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) { } TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, @@ -181,7 +181,7 @@ TEST_F(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) { // Try decrypting two different sets of content to make sure that two // different keys can be used at the same time. TEST_F(LicenseWhiteboxDecryptTest, SuccessWithMultipleKeys) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -217,7 +217,7 @@ TEST_F(LicenseWhiteboxDecryptTest, SuccessWithMultipleKeys) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(nullptr, WB_CIPHER_MODE_CBC, @@ -232,7 +232,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCipherMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // In order to trick the compiler into letting us pass an invalid enum value // to WB__License_Decrypt(), we need to cast it. If we don't do this, the @@ -251,7 +251,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCipherMode) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullKeyId) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, nullptr, @@ -265,7 +265,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullKeyId) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForZeroKeyIdSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -279,7 +279,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForZeroKeyIdSize) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullInputData) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -295,7 +295,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullInputData) { // AES CBC requires that the input be block aligned (multiple of 16). CTR does // not care. TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCBCInputDataSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -310,7 +310,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCBCInputDataSize) { // The white-box (using any cipher mode) should reject input with size zero. TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForZeroInputDataSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -324,7 +324,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForZeroInputDataSize) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullIV) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt( @@ -339,7 +339,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullIV) { // IV size should be 16. Any number other than 16 should fail. TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidIVSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -353,7 +353,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidIVSize) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutput) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -368,7 +368,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutput) { } TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutputSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -386,7 +386,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutputSize) { // in the license to start with. This is different than "non content key" // and "dropped content key", as those keys were in the license but ignored. TEST_F(LicenseWhiteboxDecryptTest, KeyUnavailableForMissingKeyId) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, missing_key_id_.data(), @@ -400,7 +400,7 @@ TEST_F(LicenseWhiteboxDecryptTest, KeyUnavailableForMissingKeyId) { } TEST_F(LicenseWhiteboxDecryptTest, KeyUnavailableForNonContentKey) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, @@ -417,7 +417,7 @@ TEST_F(LicenseWhiteboxDecryptTest, KeyUnavailableForNonContentKey) { // to this rule is on ChromeOS with a special license. TEST_F(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForHardwareContentKey) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_Decrypt( whitebox_, WB_CIPHER_MODE_CBC, @@ -432,7 +432,7 @@ TEST_F(LicenseWhiteboxDecryptTest, } TEST_F(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForDecodeKey) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // Use the software decode key as they are limited to // WB_License_Decrypt(). @@ -449,7 +449,7 @@ TEST_F(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForDecodeKey) { } TEST_F(LicenseWhiteboxDecryptTest, BufferTooSmall) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // Our ciphertext will be large enough that we should not need to worry about // using a constant here. diff --git a/api/license_whitebox_get_secret_string_test.cc b/api/license_whitebox_get_secret_string_test.cc index d1e3fa9..226d59b 100644 --- a/api/license_whitebox_get_secret_string_test.cc +++ b/api/license_whitebox_get_secret_string_test.cc @@ -6,11 +6,11 @@ #include #include "api/golden_data.h" -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -29,7 +29,7 @@ class LicenseWhiteboxGetSecretStringTest : public LicenseWhiteboxTestBase { } void LoadLicense() { - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, @@ -74,7 +74,7 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCBCWithCryptoKey) { golden_data_.CBCCryptoKey().id.size(), secret_string_.data(), &secret_string_size_), WB_RESULT_OK); - ASSERT_GT(secret_string_size_, 0); + ASSERT_GT(secret_string_size_, 0u); } TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithCryptoKey) { @@ -86,7 +86,7 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithCryptoKey) { golden_data_.CBCCryptoKey().id.size(), secret_string_.data(), &secret_string_size_), WB_RESULT_OK); - ASSERT_GT(secret_string_size_, 0); + ASSERT_GT(secret_string_size_, 0u); } TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCBCWithDecodeKey) { @@ -98,7 +98,7 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCBCWithDecodeKey) { golden_data_.CBCDecodeKey().id.size(), secret_string_.data(), &secret_string_size_), WB_RESULT_OK); - ASSERT_GT(secret_string_size_, 0); + ASSERT_GT(secret_string_size_, 0u); } TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithDecodeKey) { @@ -110,7 +110,7 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithDecodeKey) { golden_data_.CBCDecodeKey().id.size(), secret_string_.data(), &secret_string_size_), WB_RESULT_OK); - ASSERT_GT(secret_string_size_, 0); + ASSERT_GT(secret_string_size_, 0u); } TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidParameterForNullWhitebox) { @@ -237,7 +237,7 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, BufferTooSmall) { // Make sure that the output included the required size. We don't know what // it is, so we rely on checking that it is just bigger than the "too small" // size. - ASSERT_GT(secret_string_size_, 1); + ASSERT_GT(secret_string_size_, 1u); } TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidState) { diff --git a/api/license_whitebox_masked_decrypt_test.cc b/api/license_whitebox_masked_decrypt_test.cc index f6a69db..17db729 100644 --- a/api/license_whitebox_masked_decrypt_test.cc +++ b/api/license_whitebox_masked_decrypt_test.cc @@ -8,13 +8,13 @@ #include #include "api/golden_data.h" -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "base/logging.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -39,7 +39,7 @@ class LicenseWhiteboxMaskedDecryptTest : public LicenseWhiteboxTestBase { } void LoadLicense(const std::vector& padding) { - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, @@ -87,7 +87,7 @@ class LicenseWhiteboxMaskedDecryptTest : public LicenseWhiteboxTestBase { }; TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -121,7 +121,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCbcMode) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -157,7 +157,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCtrMode) { // We try to decrypt CBC encrypted data in CTR mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -192,7 +192,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCtrMode) { // We try to decrypt CTR encrypted data in CBC mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -225,7 +225,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCbcMode) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -259,7 +259,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCbcMode) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -295,7 +295,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCtrMode) { // We try to decrypt CBC encrypted data in CTR mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCtrMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -330,7 +330,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCtrMode) { // We try to decrypt CTR encrypted data in CBC mode. All operations should be // successful, but the resulting plaintext should not match. TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCbcMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -363,7 +363,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCbcMode) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -397,7 +397,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -436,7 +436,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) { // Since we have two CBC keys, try using the decode key and then the crypto // key. TEST_F(LicenseWhiteboxMaskedDecryptTest, SuccessWithMultipleKeys) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -508,7 +508,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, SuccessWithMultipleKeys) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullWhitebox) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -523,7 +523,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullWhitebox) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidCipherMode) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // In order to trick the compiler into letting us pass an invalid enum value // to WB__License_MaskedDecrypt(), we need to cast it. If we don't do this, @@ -542,7 +542,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidCipherMode) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullKeyId) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, nullptr, @@ -556,7 +556,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullKeyId) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullZeroKeyIdSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -570,7 +570,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullZeroKeyIdSize) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullInputData) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -587,7 +587,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullInputData) { // not care. TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidCBCInputDataSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -602,7 +602,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, // The white-box (using any cipher mode) should reject input with size zero. TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForZeroInputDataSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -616,7 +616,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForZeroInputDataSize) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullIV) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -631,7 +631,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullIV) { // IV size should be 16. Any number other than 16 should fail. TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidIVSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -645,7 +645,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidIVSize) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutput) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -660,7 +660,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutput) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutputSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_MaskedDecrypt( @@ -678,7 +678,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutputSize) { // in the license to start with. This is different than "non content key" // and "dropped content key", as those keys were in the license but ignored. TEST_F(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForMissingKeyId) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, missing_key_id_.data(), @@ -692,7 +692,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForMissingKeyId) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForNonContentKey) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, non_content_key_id_.data(), @@ -709,7 +709,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForNonContentKey) { // to this rule is on ChromeOS with a special license. TEST_F(LicenseWhiteboxMaskedDecryptTest, InsufficientSecurityLevelForHardwareContentKey) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, @@ -740,7 +740,7 @@ TEST_F(LicenseWhiteboxMaskedDecryptTest, InvalidState) { } TEST_F(LicenseWhiteboxMaskedDecryptTest, BufferTooSmall) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // Our ciphertext will be large enough that we should not need to worry about // using a constant here. diff --git a/api/license_whitebox_process_license_response_test.cc b/api/license_whitebox_process_license_response_test.cc index 83aac8e..23ddbae 100644 --- a/api/license_whitebox_process_license_response_test.cc +++ b/api/license_whitebox_process_license_response_test.cc @@ -6,12 +6,12 @@ #include #include "api/golden_data.h" -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -19,14 +19,14 @@ class LicenseWhiteboxProcessLicenseResponseTest : public LicenseWhiteboxTestBase { protected: void UseLicenseWithoutSigningKey() { - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddStubbedContentKey(); builder.Build(*public_key_, &license_); } void UseLicenseWithSigningKey(const std::vector& padding) { - LicenseBuilder builder; - builder.AddSigningKey(LicenseBuilder::DefaultSigningKey(), padding); + TestLicenseBuilder builder; + builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey(), padding); builder.AddStubbedContentKey(); builder.Build(*public_key_, &license_); } @@ -47,7 +47,7 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest, SuccessWithoutSigningKey) { TEST_F(LicenseWhiteboxProcessLicenseResponseTest, SuccessWithSigningKeyNoPadding) { - UseLicenseWithSigningKey(LicenseBuilder::NoPadding()); + UseLicenseWithSigningKey(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_ProcessLicenseResponse( whitebox_, license_.message.data(), license_.message.size(), @@ -59,7 +59,7 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest, TEST_F(LicenseWhiteboxProcessLicenseResponseTest, SuccessWithSigningKeyPKSC8Padding) { - UseLicenseWithSigningKey(LicenseBuilder::PKSC8Padding()); + UseLicenseWithSigningKey(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ(WB_License_ProcessLicenseResponse( whitebox_, license_.message.data(), license_.message.size(), diff --git a/api/license_whitebox_sign_license_request_test.cc b/api/license_whitebox_sign_license_request_test.cc index 7bfdef6..4cf901c 100644 --- a/api/license_whitebox_sign_license_request_test.cc +++ b/api/license_whitebox_sign_license_request_test.cc @@ -6,11 +6,11 @@ #include #include -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -19,7 +19,7 @@ class LicenseWhiteboxSignLicenseRequestTest : public LicenseWhiteboxTestBase { void SetUp() override { LicenseWhiteboxTestBase::SetUp(); - LicenseBuilder builder; + TestLicenseBuilder builder; builder.Build(*public_key_, &license_); // We must make the default size large to hold the signature returned by @@ -123,6 +123,6 @@ TEST_F(LicenseWhiteboxSignLicenseRequestTest, BufferTooSmall) { // When WB_RESULT_BUFFER_TOO_SMALL is returned, the required buffer size // should be returned via |signature_size|. Since we don't know what it is, we // must rely on it being larger than the original "too small" size. - ASSERT_GT(signature_size_, 1); + ASSERT_GT(signature_size_, 1u); } } // namespace widevine diff --git a/api/license_whitebox_sign_renewal_request_test.cc b/api/license_whitebox_sign_renewal_request_test.cc index 25088a3..f660b0e 100644 --- a/api/license_whitebox_sign_renewal_request_test.cc +++ b/api/license_whitebox_sign_renewal_request_test.cc @@ -6,12 +6,12 @@ #include #include -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -27,7 +27,7 @@ class LicenseWhiteboxSignRenewalRequestTest : public LicenseWhiteboxTestBase { } void LoadLicense(const std::vector& padding) { - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddSigningKey(signing_key_, padding); // Add a throw away key. We just need a key in the license since a license // should always have a content key. @@ -60,7 +60,8 @@ class LicenseWhiteboxSignRenewalRequestTest : public LicenseWhiteboxTestBase { const std::string session_key_ = "0123456789ABCDEF"; - const std::vector signing_key_ = LicenseBuilder::DefaultSigningKey(); + const std::vector signing_key_ = + TestLicenseBuilder::DefaultSigningKey(); size_t signature_size_; std::vector signature_; @@ -75,7 +76,7 @@ class LicenseWhiteboxSignRenewalRequestTest : public LicenseWhiteboxTestBase { }; TEST_F(LicenseWhiteboxSignRenewalRequestTest, SuccessWithInvalidRequest) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(), garbage_request_.size(), @@ -88,7 +89,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, SuccessWithInvalidRequest) { TEST_F(LicenseWhiteboxSignRenewalRequestTest, SuccessWithSigningKeyPKSC8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(), garbage_request_.size(), @@ -100,7 +101,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, } TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullWhitebox) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_SignRenewalRequest(nullptr, garbage_request_.data(), garbage_request_.size(), @@ -109,7 +110,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullWhitebox) { } TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullMessage) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_SignRenewalRequest(whitebox_, nullptr, garbage_request_.size(), @@ -119,7 +120,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullMessage) { TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForZeroMessageSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(), 0, signature_.data(), &signature_size_), @@ -128,7 +129,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullSignature) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(), garbage_request_.size(), nullptr, @@ -138,7 +139,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidParameterForNullSignatureSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(), garbage_request_.size(), @@ -147,7 +148,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, } TEST_F(LicenseWhiteboxSignRenewalRequestTest, BufferTooSmall) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); // We need the signature to be too small. While it would be possible to use // zero, using a non-zero value ensures that we are not combining "empty" and @@ -162,7 +163,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, BufferTooSmall) { // Since the API does not limit the signature size, we can't specify the // actual expected size, however, it should at least be greater than our "too // small" size. - ASSERT_GT(signature_size_, 1); + ASSERT_GT(signature_size_, 1u); } TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidStateForNoLicense) { @@ -179,7 +180,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidStateForNoLicense) { TEST_F(LicenseWhiteboxSignRenewalRequestTest, InvalidStateForNoSigningKey) { // Make a license with no signing key but has a content key. Every license // must have a content key. - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddStubbedContentKey(); License license; diff --git a/api/license_whitebox_test_base.cc b/api/license_whitebox_test_base.cc index 4276ab9..bce98b6 100644 --- a/api/license_whitebox_test_base.cc +++ b/api/license_whitebox_test_base.cc @@ -26,7 +26,7 @@ void LicenseWhiteboxTestBase::TearDown() { void LicenseWhiteboxTestBase::Modify(std::vector* data) const { ASSERT_TRUE(data); - ASSERT_GT(data->size(), 0); + ASSERT_GT(data->size(), 0u); // Bitwise-not the first byte so that we are guaranteed to have at least one // byte different from the original data. diff --git a/api/license_whitebox_test_base.h b/api/license_whitebox_test_base.h index 0733c70..dc6ef14 100644 --- a/api/license_whitebox_test_base.h +++ b/api/license_whitebox_test_base.h @@ -8,7 +8,7 @@ #include "api/golden_data.h" #include "api/license_whitebox.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { diff --git a/api/license_whitebox_verify_renewal_response_test.cc b/api/license_whitebox_verify_renewal_response_test.cc index 933a1fd..89df2af 100644 --- a/api/license_whitebox_verify_renewal_response_test.cc +++ b/api/license_whitebox_verify_renewal_response_test.cc @@ -6,12 +6,12 @@ #include #include -#include "api/license_builder.h" #include "api/license_whitebox_test_base.h" #include "api/test_data.h" +#include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -24,12 +24,12 @@ class LicenseWhiteboxVerifyRenewalResponseTest } void LoadLicense(const std::vector& padding) { - const auto signing_key = LicenseBuilder::DefaultSigningKey(); + const auto signing_key = TestLicenseBuilder::DefaultSigningKey(); // We need a license so that we can always have a valid signature for our // message(s), but don't load the license as some test will need no // license loaded. - LicenseBuilder builder; + TestLicenseBuilder builder; builder.AddSigningKey(signing_key, padding); builder.AddStubbedContentKey(); @@ -45,7 +45,7 @@ class LicenseWhiteboxVerifyRenewalResponseTest } std::vector Sign(const std::vector& message) { - const auto key = LicenseBuilder::DefaultSigningKey(); + const auto key = TestLicenseBuilder::DefaultSigningKey(); // The server signing key is the first half of the signing key. std::string server_key = std::string( @@ -83,7 +83,7 @@ class LicenseWhiteboxVerifyRenewalResponseTest // SuccessForGarbageMessage - to use the real serialized response. TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, SuccessForGarbageMessage) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_VerifyRenewalResponse(whitebox_, garbage_renewal_message_.data(), @@ -95,7 +95,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, SuccessForGarbageMessage) { TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, SuccessWithSigningKeyPKSC8Padding) { - LoadLicense(LicenseBuilder::PKSC8Padding()); + LoadLicense(TestLicenseBuilder::PKSC8Padding()); ASSERT_EQ(WB_License_VerifyRenewalResponse(whitebox_, garbage_renewal_message_.data(), @@ -107,7 +107,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidParameterForNullWhitebox) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ( WB_License_VerifyRenewalResponse(nullptr, garbage_renewal_message_.data(), @@ -119,7 +119,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidParameterForNullMessage) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_VerifyRenewalResponse(whitebox_, nullptr, garbage_renewal_message_.size(), @@ -130,7 +130,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidParameterForZeroMessageSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_VerifyRenewalResponse(whitebox_, garbage_renewal_message_.data(), 0, @@ -141,7 +141,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidParameterForNullSignature) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_VerifyRenewalResponse( whitebox_, garbage_renewal_message_.data(), @@ -152,7 +152,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidParameterForInvalidSignatureSize) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); ASSERT_EQ(WB_License_VerifyRenewalResponse( whitebox_, garbage_renewal_message_.data(), @@ -163,7 +163,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidSignatureForModifiedMessage) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); Modify(&garbage_renewal_message_); @@ -177,7 +177,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidSignatureForModifiedSignature) { - LoadLicense(LicenseBuilder::NoPadding()); + LoadLicense(TestLicenseBuilder::NoPadding()); Modify(&garbage_renewal_signature_); @@ -204,7 +204,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidStateForNoLicense) { TEST_F(LicenseWhiteboxVerifyRenewalResponseTest, InvalidStateForNoSigningKey) { // Create a license with no signing key and one content key (every license // must have a content key). - widevine::LicenseBuilder builder; + widevine::TestLicenseBuilder builder; builder.AddStubbedContentKey(); License license; diff --git a/api/result.h b/api/result.h index 0d9935c..173d887 100644 --- a/api/result.h +++ b/api/result.h @@ -39,10 +39,6 @@ typedef enum { // The input data failed to be verified. This may happen if the data was // corrupted or tampered. WB_RESULT_DATA_VERIFICATION_ERROR = 8, - - // The padding at the end of the decrypted data does not match the - // specification. - WB_RESULT_INVALID_PADDING = 9, } WB_Result; #ifdef __cplusplus diff --git a/api/test_license_builder.cc b/api/test_license_builder.cc new file mode 100644 index 0000000..3fc533f --- /dev/null +++ b/api/test_license_builder.cc @@ -0,0 +1,264 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#include "api/test_license_builder.h" + +#include + +#include "base/logging.h" +#include "cdm/keys/certs.h" +#include "crypto_utils/aes_cbc_encryptor.h" +#include "crypto_utils/crypto_util.h" +#include "crypto_utils/sha_util.h" + +namespace widevine { + +namespace { + +void InitializeRequest(video_widevine::LicenseRequest* request) { + request->set_request_time(std::time(nullptr)); // Use time=now. + + auto* client_id = request->mutable_client_id(); + auto* capabilities = client_id->mutable_client_capabilities(); + capabilities->set_video_resolution_constraints(true); + capabilities->set_client_token(true); + capabilities->set_session_token(false); + capabilities->set_max_hdcp_version( + video_widevine::ClientIdentification::ClientCapabilities::HDCP_V1); + + auto* client_info = client_id->add_client_info(); + client_info->set_name("architecture_name"); + client_info->set_value("x86-64"); + client_info = client_id->add_client_info(); + client_info->set_name("company_name"); + client_info->set_value("Google"); + client_info = client_id->add_client_info(); + client_info->set_name("model_name"); + client_info->set_value("ChromeCDM"); + client_info = client_id->add_client_info(); + client_info->set_name("platform_name"); + client_info->set_value("Windows"); + client_info = client_id->add_client_info(); + client_info->set_name("widevine_cdm_version"); + client_info->set_value("4.10.1686.29"); + + client_id->set_type( + video_widevine::ClientIdentification_TokenType_DRM_DEVICE_CERTIFICATE); + client_id->set_token(wvcdm::kRsaDrmCertificate, + wvcdm::kRsaDrmCertificateSize); + + auto* content_id = request->mutable_content_id(); + auto* webm_key_id = content_id->mutable_webm_key_id(); + webm_key_id->set_license_type(video_widevine::STREAMING); + webm_key_id->set_request_id("REQUEST_ID"); + webm_key_id->set_header("01234567890123456"); + + request->set_protocol_version(video_widevine::VERSION_2_1); + request->set_type(video_widevine::LicenseRequest::NEW); +} + +void InitializeResponse(const video_widevine::LicenseRequest& request, + video_widevine::License* response) { + auto* id = response->mutable_id(); + id->set_request_id("REQUEST_ID"); + id->set_session_id("SESSION_ID"); + id->set_type(video_widevine::STREAMING); + id->set_version(0); + + auto* policy = response->mutable_policy(); + policy->set_can_play(true); + policy->set_can_persist(false); + policy->set_can_renew(true); + policy->set_license_duration_seconds(600); + policy->set_renewal_delay_seconds(30); + policy->set_renewal_retry_interval_seconds(10); + policy->set_renew_with_usage(false); + + response->set_license_start_time(request.request_time()); + response->set_remote_attestation_verified(false); + response->set_platform_verification_status( + video_widevine::PlatformVerificationStatus::PLATFORM_UNVERIFIED); +} + +std::string EncryptKey(const std::string& key, + const std::string& iv, + const std::vector& plaintext) { + AesCbcEncryptor encryptor; + encryptor.SetKey(reinterpret_cast(key.data()), key.size()); + + std::vector ciphertext(plaintext.size()); + CHECK(encryptor.Encrypt(reinterpret_cast(iv.data()), + iv.size(), plaintext.data(), plaintext.size(), + ciphertext.data())); + + return std::string(ciphertext.begin(), ciphertext.end()); +} + +std::string DeriveIV(const std::vector& context) { + const std::string context_str(context.begin(), context.end()); + return crypto_util::DeriveIv(context_str); +} + +} // namespace + +// static +std::vector TestLicenseBuilder::NoPadding() { + return {}; +} + +// static +std::vector TestLicenseBuilder::PKSC8Padding() { + return { + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + }; +} + +// static +std::vector TestLicenseBuilder::DefaultSigningKey() { + return { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + }; +} + +TestLicenseBuilder::TestLicenseBuilder() { + DCHECK_EQ(session_key_.size(), 16u); + + // Initialize the request and the response with the static fields that will + // be common across all licences. + InitializeRequest(&request_); + InitializeResponse(request_, &response_); + + serialized_request_ = request_.SerializeAsString(); + container_key_ = crypto_util::DeriveKey( + session_key_, crypto_util::kWrappingKeyLabel, serialized_request_, + crypto_util::kWrappingKeySizeBits); +} + +void TestLicenseBuilder::AddSigningKey(const std::vector& key, + const std::vector& padding) { + DCHECK_EQ(key.size(), 64u); // 512 bits + + auto* container = response_.add_key(); + container->set_type(video_widevine::License_KeyContainer_KeyType_SIGNING); + + // To avoid having to define a key iv for each key, derive a key iv from the + // key. This will allows us to have a different IVs between keys but keep it + // deterministic. + const auto key_iv = DeriveIV(key); + container->set_iv(key_iv); + + std::vector final_key = key; + final_key.insert(final_key.end(), padding.begin(), padding.end()); + container->set_key(EncryptKey(container_key_, key_iv, final_key)); +} + +void TestLicenseBuilder::AddStubbedContentKey() { + auto* container = response_.add_key(); + + container->set_type(video_widevine::License_KeyContainer_KeyType_CONTENT); + container->set_id("stubbed-content-key"); + container->set_level( + video_widevine::License_KeyContainer_SecurityLevel_SW_SECURE_CRYPTO); + container->set_iv("0000000000000000"); + + // We don't bother encrypting the key, it should never be used and there is no + // way to verify it. + container->set_key("0000000000000000"); +} + +void TestLicenseBuilder::AddContentKey( + video_widevine::License_KeyContainer_SecurityLevel level, + const std::vector& key_id, + const std::vector& key, + const std::vector& padding) { + DCHECK_GT(key_id.size(), 0u); + DCHECK_EQ(key.size(), 16u); + + auto* container = response_.add_key(); + + container->set_type(video_widevine::License_KeyContainer_KeyType_CONTENT); + container->set_id(key_id.data(), key_id.size()); + container->set_level(level); + + // To avoid having to define a key iv for each key, derive a key iv from the + // key. This will allows us to have a different IVs between keys but keep it + // deterministic. + const auto key_iv = DeriveIV(key); + container->set_iv(key_iv); + + std::vector final_key = key; + final_key.insert(final_key.end(), padding.begin(), padding.end()); + container->set_key(EncryptKey(container_key_, key_iv, final_key)); +} + +void TestLicenseBuilder::AddOperatorSessionKey( + const std::vector& key_id) { + DCHECK_GT(key_id.size(), 0u); + + // We only set the type and id because the key should not actually be used. + auto* container = response_.add_key(); + container->set_type( + video_widevine::License_KeyContainer_KeyType_OPERATOR_SESSION); + container->set_id(key_id.data(), key_id.size()); +} + +void TestLicenseBuilder::SetRemoteAttestation(RemoteAttestation setting) { + switch (setting) { + case RemoteAttestation::kUnavailable: + response_.clear_remote_attestation_verified(); + break; + case RemoteAttestation::kVerified: + response_.set_remote_attestation_verified(true); + break; + case RemoteAttestation::kUnverified: + response_.set_remote_attestation_verified(false); + break; + } +} + +void TestLicenseBuilder::SetVerificationStatus(VerificationStatus setting) { + switch (setting) { + case VerificationStatus::kUnavailable: + response_.clear_platform_verification_status(); + break; + case VerificationStatus::kHardwareVerified: + response_.set_platform_verification_status( + video_widevine::PLATFORM_HARDWARE_VERIFIED); + break; + case VerificationStatus::kOther: + response_.set_platform_verification_status( + video_widevine::PLATFORM_UNVERIFIED); + break; + } +} + +void TestLicenseBuilder::Build(const RsaPublicKey& public_key, + License* license) const { + DCHECK(license); + + const std::string message_str = response_.SerializeAsString(); + + std::string signing_key = crypto_util::DeriveKey( + session_key_, crypto_util::kSigningKeyLabel, serialized_request_, + crypto_util::kSigningKeySizeBits * 2); + signing_key.resize(crypto_util::kSigningKeySizeBytes); + + const std::string signature_str = + crypto_util::CreateSignatureHmacSha256(signing_key, message_str); + + std::string session_key_str; + CHECK(public_key.Encrypt(session_key_, &session_key_str)); + + license->request = std::vector(serialized_request_.begin(), + serialized_request_.end()); + license->message = + std::vector(message_str.begin(), message_str.end()); + license->signature = + std::vector(signature_str.begin(), signature_str.end()); + license->session_key = + std::vector(session_key_str.begin(), session_key_str.end()); +} +} // namespace widevine diff --git a/api/test_license_builder.h b/api/test_license_builder.h new file mode 100644 index 0000000..939817f --- /dev/null +++ b/api/test_license_builder.h @@ -0,0 +1,86 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#ifndef WHITEBOX_API_LICENSE_BUILDER_H_ +#define WHITEBOX_API_LICENSE_BUILDER_H_ + +#include +#include +#include + +#include "cdm/protos/license_protocol.pb.h" +#include "crypto_utils/rsa_key.h" + +namespace widevine { + +struct License { + std::vector request; + std::vector message; + std::vector signature; + + // |session_key_| encrypted using the public key. The white-box expects the + // session key to be encrypted, so we use the name "session_key_" (even if it + // is encrypted), we omit the term "encrypted" to match the naming in the API. + std::vector session_key; +}; + +class TestLicenseBuilder { + public: + enum class RemoteAttestation { + kUnavailable, + kVerified, + kUnverified, + }; + + enum class VerificationStatus { + kUnavailable, + kHardwareVerified, + kOther, + }; + + // Returns padding data the can be used as |padding| when calling + // AddSigningKey() or AddContentKey(). + static std::vector NoPadding(); + static std::vector PKSC8Padding(); + + // Returns a default signing key that can be used with AddSigningKey(). + static std::vector DefaultSigningKey(); + + TestLicenseBuilder(); + + void AddSigningKey(const std::vector& key, + const std::vector& padding = NoPadding()); + + // Add a content key so that there is some key in the license. This should not + // be used with AddContentKey(). + void AddStubbedContentKey(); + + void AddContentKey(video_widevine::License_KeyContainer_SecurityLevel level, + const std::vector& key_id, + const std::vector& key, + const std::vector& padding = NoPadding()); + + // The key id will matter as we will need to reference it, but the key won't + // matter since we are only using it as a means to verify that a non-content + // key can't be used as a content key. + void AddOperatorSessionKey(const std::vector& key_id); + + void SetRemoteAttestation(RemoteAttestation setting); + + void SetVerificationStatus(VerificationStatus setting); + + // Gets the serialized license request and response (in components) that would + // have been used in the license exchange. + void Build(const RsaPublicKey& public_key, License* license) const; + + private: + const std::string session_key_ = "0123456789ABCDEF"; + + video_widevine::LicenseRequest request_; + video_widevine::License response_; + std::string serialized_request_; + std::string container_key_; +}; + +} // namespace widevine + +#endif // WHITEBOX_API_LICENSE_BUILDER_H_ diff --git a/chromium_deps/base/BUILD b/chromium_deps/base/BUILD index 9141c4b..8c6f6f5 100644 --- a/chromium_deps/base/BUILD +++ b/chromium_deps/base/BUILD @@ -1,22 +1,12 @@ # Copyright 2020 Google LLC. All Rights Reserved. cc_library( - name = "base", - srcs = [ - "base64.cc", - "strings/string_number_conversions.cc", - ], - hdrs = [ - "base64.h", - "logging.h", - "strings/string_number_conversions.h", - ], + name = "glog", + hdrs = ["logging.h"], strip_include_prefix = "//chromium_deps", visibility = ["//visibility:public"], deps = [ "//external:gflags", "//external:glog", - "@abseil_repo//absl/base", - "@abseil_repo//absl/strings", ], ) diff --git a/chromium_deps/testing/BUILD b/chromium_deps/testing/BUILD index 6a5c972..0c3cb61 100644 --- a/chromium_deps/testing/BUILD +++ b/chromium_deps/testing/BUILD @@ -1,14 +1,11 @@ # Copyright 2020 Google LLC. All Rights Reserved. cc_library( - name = "gtest", - hdrs = [ - "include/gmock/gmock.h", - "include/gtest/gtest.h", - ], - strip_include_prefix = "//chromium_deps", + name = "testing", visibility = ["//visibility:public"], deps = [ + "//chromium_deps/testing/include/gmock", + "//chromium_deps/testing/include/gtest", "//external:gtest", "//external:gtest_main", ], diff --git a/chromium_deps/testing/include/gmock/BUILD b/chromium_deps/testing/include/gmock/BUILD new file mode 100644 index 0000000..2e78941 --- /dev/null +++ b/chromium_deps/testing/include/gmock/BUILD @@ -0,0 +1,11 @@ +# Copyright 2020 Google LLC. All Rights Reserved. + +cc_library( + name = "gmock", + hdrs = [ + "gmock.h", + ], + include_prefix = "testing/gmock/include/gmock/", + strip_include_prefix = "//chromium_deps/testing/include/gmock/", + visibility = ["//visibility:public"], +) diff --git a/chromium_deps/testing/include/gtest/BUILD b/chromium_deps/testing/include/gtest/BUILD new file mode 100644 index 0000000..2cb7027 --- /dev/null +++ b/chromium_deps/testing/include/gtest/BUILD @@ -0,0 +1,11 @@ +# Copyright 2020 Google LLC. All Rights Reserved. + +cc_library( + name = "gtest", + hdrs = [ + "gtest.h", + ], + include_prefix = "testing/gtest/include/gtest/", + strip_include_prefix = "//chromium_deps/testing/include/gtest/", + visibility = ["//visibility:public"], +) diff --git a/crypto_utils/BUILD b/crypto_utils/BUILD index 5dd6800..58e90ad 100644 --- a/crypto_utils/BUILD +++ b/crypto_utils/BUILD @@ -14,7 +14,7 @@ cc_library( hdrs = ["aes_cbc_decryptor.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", ], ) @@ -25,7 +25,7 @@ cc_test( srcs = ["aes_cbc_decryptor_test.cc"], deps = [ ":aes_cbc_decryptor", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", ], ) @@ -35,7 +35,7 @@ cc_library( hdrs = ["aes_cbc_encryptor.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", ], ) @@ -46,7 +46,8 @@ cc_test( srcs = ["aes_cbc_encryptor_test.cc"], deps = [ ":aes_cbc_encryptor", - "//chromium_deps/testing:gtest", + "//chromium_deps/base:glog", + "//chromium_deps/testing", ], ) @@ -56,7 +57,7 @@ cc_library( hdrs = ["aes_ctr_encryptor.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", ], ) @@ -67,7 +68,7 @@ cc_test( srcs = ["aes_ctr_encryptor_test.cc"], deps = [ ":aes_ctr_encryptor", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", ], ) @@ -77,11 +78,8 @@ cc_library( hdrs = ["crypto_util.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", - # TODO(hmchen): replace absl::string_view with std::string so that - # these files can be used by other projects which does not use absl. - "@abseil_repo//absl/strings", ], ) @@ -91,7 +89,8 @@ cc_test( srcs = ["crypto_util_test.cc"], deps = [ ":crypto_util", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", + "@abseil_repo//absl/strings", ], ) @@ -100,7 +99,6 @@ cc_library( hdrs = ["private_key_util.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", "//chromium_deps/third_party/boringssl", ], ) @@ -112,7 +110,7 @@ cc_library( visibility = ["//visibility:public"], deps = [ ":private_key_util", - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", ], ) @@ -125,8 +123,7 @@ cc_test( deps = [ ":rsa_test_keys", ":rsa_util", - "//chromium_deps/base", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", "//chromium_deps/third_party/boringssl", ], ) @@ -146,7 +143,7 @@ cc_library( hdrs = ["random_util.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", + "//chromium_deps/base:glog", "//chromium_deps/third_party/boringssl", ], ) @@ -157,7 +154,7 @@ cc_test( srcs = ["random_util_test.cc"], deps = [ ":random_util", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", ], ) @@ -169,7 +166,6 @@ cc_library( deps = [ ":rsa_util", ":sha_util", - "//chromium_deps/base", "//chromium_deps/third_party/boringssl", ], ) @@ -183,7 +179,7 @@ cc_test( ":rsa_key", ":rsa_test_keys", ":rsa_util", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", ], ) @@ -194,7 +190,6 @@ cc_library( hdrs = ["rsa_test_keys.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", ], ) @@ -204,7 +199,6 @@ cc_library( hdrs = ["sha_util.h"], visibility = ["//visibility:public"], deps = [ - "//chromium_deps/base", "//chromium_deps/third_party/boringssl", ], ) @@ -214,7 +208,7 @@ cc_test( srcs = ["sha_util_test.cc"], deps = [ ":sha_util", - "//chromium_deps/testing:gtest", + "//chromium_deps/testing", "@abseil_repo//absl/strings", ], ) diff --git a/crypto_utils/aes_cbc_decryptor_test.cc b/crypto_utils/aes_cbc_decryptor_test.cc index 7c1965f..2e67b7c 100644 --- a/crypto_utils/aes_cbc_decryptor_test.cc +++ b/crypto_utils/aes_cbc_decryptor_test.cc @@ -5,8 +5,8 @@ #include #include -#include "testing/include/gmock/gmock.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" using ::testing::ElementsAreArray; diff --git a/crypto_utils/aes_cbc_encryptor_test.cc b/crypto_utils/aes_cbc_encryptor_test.cc index 935ca1e..5082905 100644 --- a/crypto_utils/aes_cbc_encryptor_test.cc +++ b/crypto_utils/aes_cbc_encryptor_test.cc @@ -5,8 +5,8 @@ #include #include -#include "testing/include/gmock/gmock.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" using ::testing::ElementsAreArray; diff --git a/crypto_utils/aes_ctr_encryptor_test.cc b/crypto_utils/aes_ctr_encryptor_test.cc index f5b226f..6f6dc40 100644 --- a/crypto_utils/aes_ctr_encryptor_test.cc +++ b/crypto_utils/aes_ctr_encryptor_test.cc @@ -3,8 +3,8 @@ #include #include -#include "testing/include/gmock/gmock.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" using ::testing::ElementsAreArray; diff --git a/crypto_utils/crypto_util.cc b/crypto_utils/crypto_util.cc index 9075e16..6b4cd81 100644 --- a/crypto_utils/crypto_util.cc +++ b/crypto_utils/crypto_util.cc @@ -10,7 +10,6 @@ #include "crypto_utils/crypto_util.h" -#include "absl/strings/string_view.h" #include "base/logging.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "third_party/boringssl/src/include/openssl/cmac.h" diff --git a/crypto_utils/crypto_util.h b/crypto_utils/crypto_util.h index 5673702..fbc11bb 100644 --- a/crypto_utils/crypto_util.h +++ b/crypto_utils/crypto_util.h @@ -14,11 +14,14 @@ #include -#include "absl/strings/string_view.h" - namespace widevine { -namespace crypto_util { +// Sub in the string view so that we can more easily use this file with code +// that does not have access to absl. +namespace absl { +using string_view = const std::string&; +} +namespace crypto_util { // Default constants used for key derivation for encryption and signing. // TODO(user): These are duplicated in session.cc in the sdk. de-dup. extern const char kWrappingKeyLabel[]; diff --git a/crypto_utils/crypto_util_test.cc b/crypto_utils/crypto_util_test.cc index 4c31a12..423a8ec 100644 --- a/crypto_utils/crypto_util_test.cc +++ b/crypto_utils/crypto_util_test.cc @@ -15,13 +15,12 @@ #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" -#include "testing/include/gmock/gmock.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/aes.h" namespace widevine { namespace crypto_util { - const char kCENCStr[] = "cenc"; const char kCBC1Str[] = "cbc1"; const char kCENSStr[] = "cens"; @@ -108,7 +107,7 @@ TEST_F(CryptoUtilTest, DeriveAes256MasterKeyTest) { std::string result = DeriveKey(aes_256_key_, label_str, context_str, 128); EXPECT_EQ(std::string(expected_128, expected_128 + sizeof(expected_128)), result) - << absl::BytesToHexString(result); + << ::absl::BytesToHexString(result); const unsigned char expected_256[] = { 0xfb, 0x8f, 0xdf, 0x0e, 0x22, 0xfe, 0xf7, 0x2b, 0xd1, 0x9a, 0x1d, @@ -117,7 +116,7 @@ TEST_F(CryptoUtilTest, DeriveAes256MasterKeyTest) { result = DeriveKey(aes_256_key_, label_str, context_str, 256); EXPECT_EQ(std::string(expected_256, expected_256 + sizeof(expected_256)), result) - << absl::BytesToHexString(result); + << ::absl::BytesToHexString(result); const unsigned char expected_384[] = { 0x65, 0xbc, 0xe3, 0xf3, 0xfb, 0xfa, 0xce, 0x1d, 0x24, 0x63, 0x9c, 0x8f, @@ -127,7 +126,7 @@ TEST_F(CryptoUtilTest, DeriveAes256MasterKeyTest) { result = DeriveKey(aes_256_key_, label_str, context_str, 384); EXPECT_EQ(std::string(expected_384, expected_384 + sizeof(expected_384)), result) - << absl::BytesToHexString(result); + << ::absl::BytesToHexString(result); } TEST_F(CryptoUtilTest, DeriveAesInvalidSizeModulus) { @@ -138,7 +137,7 @@ TEST_F(CryptoUtilTest, DeriveAesInvalidSizeModulus) { TEST_F(CryptoUtilTest, DeriveAesMaxBlocks) { EXPECT_EQ( - 255 * AES_BLOCK_SIZE, + 255u * AES_BLOCK_SIZE, DeriveKey(aes_128_key_, "foo", "bar", AES_BLOCK_SIZE * 8 * 255).size()); } @@ -176,7 +175,7 @@ TEST_F(CryptoUtilTest, TestCreateAndVerifySignatureHmacSha256) { std::string message(message_data, message_data + sizeof(message_data)); std::string signature(CreateSignatureHmacSha256(aes_128_key_, message)); - ASSERT_EQ(signature.size(), 32); + ASSERT_EQ(signature.size(), 32u); ASSERT_TRUE(VerifySignatureHmacSha256(aes_128_key_, signature, message)); } @@ -196,7 +195,7 @@ TEST_F(CryptoUtilTest, TestFailCreateAndVerifyHmacSha256) { std::string signature(CreateSignatureHmacSha256(bogus_key, message)); // This should still produce an hmac signature. - ASSERT_EQ(signature.size(), 32); + ASSERT_EQ(signature.size(), 32u); // Create valid signature to compare. signature = CreateSignatureHmacSha256(aes_128_key_, message); @@ -224,7 +223,7 @@ TEST_F(CryptoUtilTest, TestCreateAndVerifySignatureHmacSha1) { std::string message(message_data, message_data + sizeof(message_data)); std::string signature(CreateSignatureHmacSha1(aes_128_key_, message)); - ASSERT_EQ(20, signature.size()); + ASSERT_EQ(20u, signature.size()); ASSERT_TRUE(VerifySignatureHmacSha1(aes_128_key_, signature, message)); } @@ -243,7 +242,7 @@ TEST_F(CryptoUtilTest, TestFailCreateAndVerifyHmacSha1) { std::string signature(CreateSignatureHmacSha1(bogus_key, message)); // This should still produce an hmac signature. - ASSERT_EQ(20, signature.size()); + ASSERT_EQ(20u, signature.size()); // Create valid signature to compare. signature = CreateSignatureHmacSha1(aes_128_key_, message); // Test with bogus key. @@ -261,12 +260,12 @@ TEST_F(CryptoUtilTest, DeriveIv) { {"1234567890123456", "3278234c7682d1a2e153af4912975f5f"}, {"0987654321098765", "cf09abd30f04b60544910791a6b904cf"}}; for (const auto& id_iv_pair : id_iv_pairs) { - SCOPED_TRACE(absl::StrCat("test case:", id_iv_pair.first)); + SCOPED_TRACE(::absl::StrCat("test case:", id_iv_pair.first)); EXPECT_EQ(id_iv_pair.second, - absl::BytesToHexString(DeriveIv(id_iv_pair.first))); + ::absl::BytesToHexString(DeriveIv(id_iv_pair.first))); // Repeat same call to verify derivied result is repeatable. EXPECT_EQ(id_iv_pair.second, - absl::BytesToHexString(DeriveIv(id_iv_pair.first))); + ::absl::BytesToHexString(DeriveIv(id_iv_pair.first))); } } @@ -276,12 +275,12 @@ TEST_F(CryptoUtilTest, DeriveKeyId) { {"1234567890123456", "a3c4a8c0d0e24e96f38f492254186a9d"}, {"0987654321098765", "084fc6bece9688ccce6b1672d9b47e22"}}; for (const auto& context_id_pair : context_id_pairs) { - SCOPED_TRACE(absl::StrCat("test case:", context_id_pair.first)); + SCOPED_TRACE(::absl::StrCat("test case:", context_id_pair.first)); EXPECT_EQ(context_id_pair.second, - absl::BytesToHexString(DeriveKeyId(context_id_pair.first))); + ::absl::BytesToHexString(DeriveKeyId(context_id_pair.first))); // Repeat same call to verify derivied result is repeatable. EXPECT_EQ(context_id_pair.second, - absl::BytesToHexString(DeriveKeyId(context_id_pair.first))); + ::absl::BytesToHexString(DeriveKeyId(context_id_pair.first))); } } diff --git a/crypto_utils/random_util_test.cc b/crypto_utils/random_util_test.cc index fec1de2..ba0cc89 100644 --- a/crypto_utils/random_util_test.cc +++ b/crypto_utils/random_util_test.cc @@ -8,7 +8,7 @@ #include "crypto_utils/random_util.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { diff --git a/crypto_utils/rsa_key.cc b/crypto_utils/rsa_key.cc index fc68026..eacfe58 100644 --- a/crypto_utils/rsa_key.cc +++ b/crypto_utils/rsa_key.cc @@ -26,13 +26,13 @@ #include "crypto_utils/rsa_key.h" #include "base/logging.h" +#include "crypto_utils/rsa_util.h" +#include "crypto_utils/sha_util.h" #include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/err.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/rsa.h" #include "third_party/boringssl/src/include/openssl/sha.h" -#include "crypto_utils/rsa_util.h" -#include "crypto_utils/sha_util.h" static const int kPssSaltLength = 20; diff --git a/crypto_utils/rsa_key_test.cc b/crypto_utils/rsa_key_test.cc index 2e10ad6..6f88f38 100644 --- a/crypto_utils/rsa_key_test.cc +++ b/crypto_utils/rsa_key_test.cc @@ -14,9 +14,9 @@ #include -#include "testing/include/gtest/gtest.h" #include "crypto_utils/rsa_test_keys.h" #include "crypto_utils/rsa_util.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { @@ -240,8 +240,8 @@ TEST_F(RsaKeyTest, KeySize) { std::unique_ptr public_key( RsaPublicKey::Create(test_keys_.public_test_key_2_2048_bits())); - EXPECT_EQ(256, private_key->KeySize()); - EXPECT_EQ(256, public_key->KeySize()); + EXPECT_EQ(256u, private_key->KeySize()); + EXPECT_EQ(256u, public_key->KeySize()); } TEST_F(RsaKeyTest, RsaKeyMatch) { diff --git a/crypto_utils/rsa_test_keys.cc b/crypto_utils/rsa_test_keys.cc index 7262328..55cc003 100644 --- a/crypto_utils/rsa_test_keys.cc +++ b/crypto_utils/rsa_test_keys.cc @@ -783,4 +783,6 @@ RsaTestKeys::RsaTestKeys() std::begin(kTestRsaPrivateKey4CarmichaelTotient_2048), std::end(kTestRsaPrivateKey4CarmichaelTotient_2048)) {} +RsaTestKeys::~RsaTestKeys() = default; + } // namespace widevine diff --git a/crypto_utils/rsa_test_keys.h b/crypto_utils/rsa_test_keys.h index a44cafa..d7b35db 100644 --- a/crypto_utils/rsa_test_keys.h +++ b/crypto_utils/rsa_test_keys.h @@ -25,6 +25,7 @@ namespace widevine { class RsaTestKeys { public: RsaTestKeys(); + ~RsaTestKeys(); // Returns 3072-bit private RSA test key 1 const std::string& private_test_key_1_3072_bits() const { diff --git a/crypto_utils/rsa_util.cc b/crypto_utils/rsa_util.cc index 38ee96a..24de338 100644 --- a/crypto_utils/rsa_util.cc +++ b/crypto_utils/rsa_util.cc @@ -18,9 +18,9 @@ #include #include "base/logging.h" +#include "crypto_utils/private_key_util.h" #include "third_party/boringssl/src/include/openssl/pem.h" #include "third_party/boringssl/src/include/openssl/x509.h" -#include "crypto_utils/private_key_util.h" namespace { int BigNumGreaterThanPow2(const BIGNUM* b, int n) { diff --git a/crypto_utils/rsa_util_test.cc b/crypto_utils/rsa_util_test.cc index deb4fe0..1d7fd6b 100644 --- a/crypto_utils/rsa_util_test.cc +++ b/crypto_utils/rsa_util_test.cc @@ -18,10 +18,10 @@ #include #include "base/logging.h" -#include "testing/include/gmock/gmock.h" -#include "testing/include/gtest/gtest.h" -#include "third_party/boringssl/src/include/openssl/bn.h" #include "crypto_utils/rsa_test_keys.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/include/openssl/bn.h" using ::testing::NotNull; diff --git a/crypto_utils/sha_util_test.cc b/crypto_utils/sha_util_test.cc index fd8b2b8..df56b8d 100644 --- a/crypto_utils/sha_util_test.cc +++ b/crypto_utils/sha_util_test.cc @@ -9,7 +9,7 @@ #include "crypto_utils/sha_util.h" #include "absl/strings/escaping.h" -#include "testing/include/gtest/gtest.h" +#include "testing/gtest/include/gtest/gtest.h" namespace widevine { diff --git a/impl/reference/BUILD b/impl/reference/BUILD index 12d527c..6ef1918 100644 --- a/impl/reference/BUILD +++ b/impl/reference/BUILD @@ -12,10 +12,8 @@ cc_library( visibility = ["//visibility:public"], deps = [ ":memory_util", - ":string_view_util", "//api:aead_whitebox", "//api:result", - "//chromium_deps/base", "//chromium_deps/third_party/boringssl", "//crypto_utils:crypto_util", ], @@ -28,10 +26,8 @@ cc_library( ], deps = [ ":memory_util", - ":string_view_util", "//api:license_whitebox", "//api:result", - "//chromium_deps/base", "//chromium_deps/cdm/keys:dev_certs", "//chromium_deps/cdm/protos:license_protocol_proto", "//crypto_utils:aes_cbc_decryptor", @@ -73,15 +69,6 @@ cc_test( ], ) -cc_library( - name = "string_view_util", - srcs = ["string_view_util.cc"], - hdrs = ["string_view_util.h"], - deps = [ - "@abseil_repo//absl/strings", - ], -) - cc_library( name = "memory_util", srcs = ["memory_util.cc"], diff --git a/impl/reference/aead_whitebox_impl.cc b/impl/reference/aead_whitebox_impl.cc index 74e14c8..cffa098 100644 --- a/impl/reference/aead_whitebox_impl.cc +++ b/impl/reference/aead_whitebox_impl.cc @@ -6,10 +6,8 @@ #include #include "base/logging.h" -#include "base/strings/string_number_conversions.h" #include "crypto_utils/crypto_util.h" #include "impl/reference/memory_util.h" -#include "impl/reference/string_view_util.h" #include "third_party/boringssl/src/include/openssl/aead.h" #include "third_party/boringssl/src/include/openssl/rand.h" @@ -41,8 +39,8 @@ std::vector DeriveKey(const WB_Aead_Whitebox* whitebox, // needs to be some fixed, arbitrary non-trivial string. constexpr char kLabel[] = "Covfefe"; - const auto init_data_view = widevine::AsStringView(init_data, init_data_size); - const auto context_view = widevine::AsStringView(context, context_size); + const std::string init_data_view(init_data, init_data + init_data_size); + const std::string context_view(context, context + context_size); // While we get the key size in bytes, DeriveKey() needs the key size in bits. const auto derived_key = widevine::crypto_util::DeriveKey( diff --git a/impl/reference/license_whitebox_impl.cc b/impl/reference/license_whitebox_impl.cc index 2d1f142..49a32dc 100644 --- a/impl/reference/license_whitebox_impl.cc +++ b/impl/reference/license_whitebox_impl.cc @@ -9,14 +9,12 @@ #include #include "base/logging.h" -#include "base/strings/string_number_conversions.h" #include "cdm/protos/license_protocol.pb.h" #include "crypto_utils/aes_cbc_decryptor.h" #include "crypto_utils/aes_ctr_encryptor.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" #include "impl/reference/memory_util.h" -#include "impl/reference/string_view_util.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "third_party/boringssl/src/include/openssl/cmac.h" #include "third_party/boringssl/src/include/openssl/err.h" @@ -66,10 +64,6 @@ const size_t kSecretStringPatternSize = sizeof(kSecretStringPattern); static_assert(kSecretStringPatternSize == AES_BLOCK_SIZE, "Secret string must be AES_BLOCK_SIZE."); -std::string AsString(const uint8_t* buffer, size_t buffer_size) { - return std::string(reinterpret_cast(buffer), buffer_size); -} - void ApplyPattern(const uint8_t* input_buffer, size_t input_buffer_size, const uint8_t* pattern, @@ -92,7 +86,7 @@ const ContentKey* FindKey(const WB_License_Whitebox* whitebox, DCHECK(whitebox); DCHECK(id); DCHECK_GT(id_size, 0u); - const std::string key_id = AsString(id, id_size); + const std::string key_id(id, id + id_size); const auto found = whitebox->content_keys.find(key_id); return found == whitebox->content_keys.end() ? nullptr : &found->second; } @@ -160,6 +154,46 @@ WB_Result DecryptBuffer(WB_CipherMode mode, return WB_RESULT_OK; } + +// We use "remote_attestation_verified" and "platform_verification_status" to +// determine whether the platform is hardware verified. +// +// Each variable can be in one of three states. Each variable has a missing +// value, a true value, and a false value. +// +// |----------------------------------------------------------| +// | | RA N/A | RA VERIFIED | RA NOT VERIFIED | +// |----------------------------------------------------------| +// | VMP N/A | 0 | 1 | 0 | +// | VMP HW_VERIFIED | 1 | 1 | 0 | +// | VMP OTHER | 0 | 0 | 0 | +// |----------------------------------------------------------| +bool IsPlatformHardwareVerified(const video_widevine::License& license) { + const bool has_ra = license.has_remote_attestation_verified(); + const bool has_vmp = license.has_platform_verification_status(); + + if (!has_ra && !has_vmp) { + return false; + } + + // We trust "missing" more than "false". Now that we know we have some values, + // default to "it's okay" and only override it if we have a new value from the + // license. + bool flags[2] = {true, true}; + + if (has_ra) { + flags[0] = license.remote_attestation_verified(); + } + + if (has_vmp) { + flags[1] = license.platform_verification_status() == + video_widevine::PLATFORM_HARDWARE_VERIFIED; + } + + // If we were missing a value, that flag will still be true. But if we see any + // false values, then we know something was found to be invalid. + return flags[0] && flags[1]; +} } // namespace WB_Result WB_License_Create(const uint8_t* whitebox_init_data, @@ -177,8 +211,8 @@ WB_Result WB_License_Create(const uint8_t* whitebox_init_data, // |whitebox_init_data| is simply the bytes of a PKCS #8 PrivateKeyInfo block // of a RSA 2048 bit key. - std::unique_ptr key(RsaPrivateKey::Create( - AsString(whitebox_init_data, whitebox_init_data_size))); + std::unique_ptr key(RsaPrivateKey::Create(std::string( + whitebox_init_data, whitebox_init_data + whitebox_init_data_size))); if (!key) { DVLOG(1) << "Invalid parameter: invalid init data."; return WB_RESULT_INVALID_PARAMETER; @@ -214,7 +248,8 @@ WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox, std::string result; DCHECK(whitebox->key->GenerateSignature( - AsString(license_request, license_request_size), &result)); + std::string(license_request, license_request + license_request_size), + &result)); if (!widevine::MemCopy(result.data(), result.size(), signature, *signature_size)) { @@ -264,15 +299,16 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, } std::string decrypted_session_key; - if (!whitebox->key->Decrypt(AsString(session_key, session_key_size), - &decrypted_session_key)) { + if (!whitebox->key->Decrypt( + std::string(session_key, session_key + session_key_size), + &decrypted_session_key)) { DVLOG(1) << "Invalid parameter: invalid session key."; return WB_RESULT_INVALID_PARAMETER; } std::string signing_key_material = widevine::crypto_util::DeriveKey( decrypted_session_key, widevine::crypto_util::kSigningKeyLabel, - widevine::AsStringView(license_request, license_request_size), + std::string(license_request, license_request + license_request_size), widevine::crypto_util::kSigningKeySizeBits * 2); if (signing_key_material.size() < kSigningKeySizeBytes * 2) { @@ -283,15 +319,16 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, const std::string server_signing_key = signing_key_material.substr(0, kSigningKeySizeBytes); if (!widevine::crypto_util::VerifySignatureHmacSha256( - server_signing_key, widevine::AsStringView(signature, signature_size), - widevine::AsStringView(message, message_size))) { + server_signing_key, + std::string(signature, signature + signature_size), + std::string(message, message + message_size))) { DVLOG(1) << "Failed to verify signed message."; return WB_RESULT_INVALID_SIGNATURE; } std::string decryption_key = widevine::crypto_util::DeriveKey( decrypted_session_key, widevine::crypto_util::kWrappingKeyLabel, - widevine::AsStringView(license_request, license_request_size), + std::string(license_request, license_request + license_request_size), widevine::crypto_util::kWrappingKeySizeBits); if (decryption_key.empty()) { DVLOG(1) << "Failed to decrypt decryption key"; @@ -313,6 +350,12 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, std::string client_renewal_key; std::map content_keys; + // When the platform is hardware verified, all keys are unlocked and are + // available to be used with either decrypt function. Use this flag to + // overwrite the default values internal our internal policies to enable + // this behaviour. + const bool is_verified = IsPlatformHardwareVerified(license); + for (const auto& key : license.key()) { // If this is not a key we're interested in, skip it as soon as possible. // Don't even bother unwrapping it. @@ -340,8 +383,7 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, return WB_RESULT_INVALID_PARAMETER; } - const std::string signing_key = - AsString(unwrapped_key.data(), unwrapped_key.size()); + const std::string signing_key(unwrapped_key.begin(), unwrapped_key.end()); server_renewal_key = signing_key.substr(0, kSigningKeySizeBytes); client_renewal_key = signing_key.substr(kSigningKeySizeBytes, kSigningKeySizeBytes); @@ -362,23 +404,28 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, License_KeyContainer_SecurityLevel_SW_SECURE_CRYPTO: content_key.allow_decrypt = true; content_key.allow_masked_decrypt = true; - content_key.key = std::move(unwrapped_key); break; case video_widevine:: License_KeyContainer_SecurityLevel_SW_SECURE_DECODE: content_key.allow_decrypt = false; content_key.allow_masked_decrypt = true; - content_key.key = std::move(unwrapped_key); break; default: content_key.allow_decrypt = false; content_key.allow_masked_decrypt = false; - // Don't set key. We don't want to save this key as we should never - // be using it. We only have an entry so that we can handle errors - // correctly. break; } + content_key.allow_decrypt |= is_verified; + content_key.allow_masked_decrypt |= is_verified; + + // Unless we are going to use the key, we don't want to save this key as + // it will only risk exposing it. We only have an entry for it so we can + // handle errors correctly. + if (content_key.allow_decrypt || content_key.allow_masked_decrypt) { + content_key.key = std::move(unwrapped_key); + } + content_keys[key.id()] = content_key; } else { // We should have already skipped over this key. @@ -423,7 +470,7 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox, const std::string computed_signature = widevine::crypto_util::CreateSignatureHmacSha256( whitebox->client_signing_key, - widevine::AsStringView(message, message_size)); + std::string(message, message + message_size)); if (!widevine::MemCopy(computed_signature.data(), computed_signature.size(), signature, *signature_size)) { @@ -465,14 +512,15 @@ WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox, const std::string computed_signature = widevine::crypto_util::CreateSignatureHmacSha256( whitebox->server_signing_key, - widevine::AsStringView(message, message_size)); + std::string(message, message + message_size)); if (signature_size != computed_signature.size()) { DVLOG(1) << "Invalid parameters: invalid signature size."; return WB_RESULT_INVALID_PARAMETER; } - if (computed_signature != widevine::AsStringView(signature, signature_size)) { + if (computed_signature != + std::string(signature, signature + signature_size)) { DVLOG(1) << "Data verification error: signatures do not match."; return WB_RESULT_INVALID_SIGNATURE; }