Code Drop Three (Update Two)
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.
This commit is contained in:
14
api/BUILD
14
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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
205
api/license_whitebox_chromeos_test.cc
Normal file
205
api/license_whitebox_chromeos_test.cc
Normal file
@@ -0,0 +1,205 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#include "api/license_whitebox.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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<Key, RemoteAttestation, VerificationStatus>> {
|
||||
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<uint8_t> 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<uint8_t> 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
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "api/test_data.h"
|
||||
#include "testing/include/gtest/gtest.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& 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.
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include <vector>
|
||||
|
||||
#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) {
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& 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.
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& 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(),
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& 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<uint8_t> signing_key_ = LicenseBuilder::DefaultSigningKey();
|
||||
const std::vector<uint8_t> signing_key_ =
|
||||
TestLicenseBuilder::DefaultSigningKey();
|
||||
|
||||
size_t signature_size_;
|
||||
std::vector<uint8_t> 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;
|
||||
|
||||
@@ -26,7 +26,7 @@ void LicenseWhiteboxTestBase::TearDown() {
|
||||
|
||||
void LicenseWhiteboxTestBase::Modify(std::vector<uint8_t>* 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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& 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<uint8_t> Sign(const std::vector<uint8_t>& 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
264
api/test_license_builder.cc
Normal file
264
api/test_license_builder.cc
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#include "api/test_license_builder.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#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<uint8_t>& plaintext) {
|
||||
AesCbcEncryptor encryptor;
|
||||
encryptor.SetKey(reinterpret_cast<const uint8_t*>(key.data()), key.size());
|
||||
|
||||
std::vector<uint8_t> ciphertext(plaintext.size());
|
||||
CHECK(encryptor.Encrypt(reinterpret_cast<const uint8_t*>(iv.data()),
|
||||
iv.size(), plaintext.data(), plaintext.size(),
|
||||
ciphertext.data()));
|
||||
|
||||
return std::string(ciphertext.begin(), ciphertext.end());
|
||||
}
|
||||
|
||||
std::string DeriveIV(const std::vector<uint8_t>& context) {
|
||||
const std::string context_str(context.begin(), context.end());
|
||||
return crypto_util::DeriveIv(context_str);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
std::vector<uint8_t> TestLicenseBuilder::NoPadding() {
|
||||
return {};
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<uint8_t> TestLicenseBuilder::PKSC8Padding() {
|
||||
return {
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
};
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<uint8_t> 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<uint8_t>& key,
|
||||
const std::vector<uint8_t>& 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<uint8_t> 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<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& 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<uint8_t> 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<uint8_t>& 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<uint8_t>(serialized_request_.begin(),
|
||||
serialized_request_.end());
|
||||
license->message =
|
||||
std::vector<uint8_t>(message_str.begin(), message_str.end());
|
||||
license->signature =
|
||||
std::vector<uint8_t>(signature_str.begin(), signature_str.end());
|
||||
license->session_key =
|
||||
std::vector<uint8_t>(session_key_str.begin(), session_key_str.end());
|
||||
}
|
||||
} // namespace widevine
|
||||
86
api/test_license_builder.h
Normal file
86
api/test_license_builder.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#ifndef WHITEBOX_API_LICENSE_BUILDER_H_
|
||||
#define WHITEBOX_API_LICENSE_BUILDER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cdm/protos/license_protocol.pb.h"
|
||||
#include "crypto_utils/rsa_key.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
struct License {
|
||||
std::vector<uint8_t> request;
|
||||
std::vector<uint8_t> message;
|
||||
std::vector<uint8_t> 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<uint8_t> 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<uint8_t> NoPadding();
|
||||
static std::vector<uint8_t> PKSC8Padding();
|
||||
|
||||
// Returns a default signing key that can be used with AddSigningKey().
|
||||
static std::vector<uint8_t> DefaultSigningKey();
|
||||
|
||||
TestLicenseBuilder();
|
||||
|
||||
void AddSigningKey(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& 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<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& 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<uint8_t>& 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_
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
|
||||
11
chromium_deps/testing/include/gmock/BUILD
Normal file
11
chromium_deps/testing/include/gmock/BUILD
Normal file
@@ -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"],
|
||||
)
|
||||
11
chromium_deps/testing/include/gtest/BUILD
Normal file
11
chromium_deps/testing/include/gtest/BUILD
Normal file
@@ -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"],
|
||||
)
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#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[];
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<RsaPublicKey> 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) {
|
||||
|
||||
@@ -783,4 +783,6 @@ RsaTestKeys::RsaTestKeys()
|
||||
std::begin(kTestRsaPrivateKey4CarmichaelTotient_2048),
|
||||
std::end(kTestRsaPrivateKey4CarmichaelTotient_2048)) {}
|
||||
|
||||
RsaTestKeys::~RsaTestKeys() = default;
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#include <memory>
|
||||
|
||||
#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) {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#include <memory>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t> 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(
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
#include <vector>
|
||||
|
||||
#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<const char*>(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<RsaPrivateKey> key(RsaPrivateKey::Create(
|
||||
AsString(whitebox_init_data, whitebox_init_data_size)));
|
||||
std::unique_ptr<RsaPrivateKey> 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,7 +299,8 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
||||
}
|
||||
|
||||
std::string decrypted_session_key;
|
||||
if (!whitebox->key->Decrypt(AsString(session_key, session_key_size),
|
||||
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;
|
||||
@@ -272,7 +308,7 @@ WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
||||
|
||||
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<std::string, ContentKey> 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user