Source release 18.1.0
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <chrono>
|
||||
@@ -163,24 +164,22 @@ void WvCdmTestBase::StripeBuffer(std::vector<uint8_t>* buffer, size_t size,
|
||||
|
||||
std::string WvCdmTestBase::Aes128CbcEncrypt(std::vector<uint8_t> key,
|
||||
const std::vector<uint8_t>& clear,
|
||||
const std::vector<uint8_t> iv) {
|
||||
std::vector<uint8_t> iv) {
|
||||
std::vector<uint8_t> encrypted(clear.size());
|
||||
std::vector<uint8_t> iv_mod(iv.begin(), iv.end());
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0],
|
||||
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0],
|
||||
AES_ENCRYPT);
|
||||
return std::string(encrypted.begin(), encrypted.end());
|
||||
}
|
||||
|
||||
std::string WvCdmTestBase::Aes128CbcDecrypt(std::vector<uint8_t> key,
|
||||
const std::vector<uint8_t>& clear,
|
||||
const std::vector<uint8_t> iv) {
|
||||
std::vector<uint8_t> iv) {
|
||||
std::vector<uint8_t> encrypted(clear.size());
|
||||
std::vector<uint8_t> iv_mod(iv.begin(), iv.end());
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0],
|
||||
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0],
|
||||
AES_DECRYPT);
|
||||
return std::string(encrypted.begin(), encrypted.end());
|
||||
}
|
||||
@@ -198,15 +197,33 @@ std::string WvCdmTestBase::SignHMAC(const std::string& message,
|
||||
|
||||
TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics)
|
||||
: CryptoSession(crypto_metrics) {
|
||||
// The first CryptoSession should have initialized OEMCrypto. This is right
|
||||
// after that, so we should tell oemcrypto to use a test keybox.
|
||||
if (session_count() == 1) {
|
||||
MaybeInstallTestKeybox();
|
||||
}
|
||||
|
||||
TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics,
|
||||
const TestCryptoSessionConfig* config)
|
||||
: CryptoSession(crypto_metrics), config_(config) {
|
||||
MaybeInstallTestKeybox();
|
||||
}
|
||||
|
||||
void TestCryptoSession::MaybeInstallTestKeybox() {
|
||||
if (IsTestKeyboxNeeded()) {
|
||||
CryptoSession::SetAllowTestKeybox(true);
|
||||
ReinitializeForTest();
|
||||
WvCdmTestBase::InstallTestRootOfTrust();
|
||||
}
|
||||
}
|
||||
|
||||
bool TestCryptoSession::IsTestKeyboxNeeded() {
|
||||
// The first CryptoSession should have initialized OEMCrypto. This is right
|
||||
// after that.
|
||||
if (session_count() != 1) return false;
|
||||
// If config is not available, assume keybox is required.
|
||||
if (config_ == nullptr) return true;
|
||||
// Unless disabled, test keybox is required.
|
||||
return !config_->disable_test_keybox;
|
||||
}
|
||||
|
||||
CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) {
|
||||
CdmResponseType status = CryptoSession::GenerateNonce(nonce);
|
||||
for (int i = 0; status != NO_ERROR; i++) {
|
||||
@@ -215,10 +232,11 @@ CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) {
|
||||
wvutil::TestSleep::Sleep(1);
|
||||
status = CryptoSession::GenerateNonce(nonce);
|
||||
}
|
||||
return NO_ERROR;
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
|
||||
class TestCryptoSessionFactory : public CryptoSessionFactory {
|
||||
public:
|
||||
CryptoSession* MakeCryptoSession(
|
||||
metrics::CryptoMetrics* crypto_metrics) override {
|
||||
// We need to add extra locking here because we need to make sure that there
|
||||
@@ -228,9 +246,18 @@ class TestCryptoSessionFactory : public CryptoSessionFactory {
|
||||
// InstallTestRootOfTrust is only called in the constructor of the
|
||||
// TestCryptoSession, above.
|
||||
std::unique_lock<std::mutex> auto_lock(init_lock_);
|
||||
return new TestCryptoSession(crypto_metrics);
|
||||
return new TestCryptoSession(crypto_metrics, &session_config_);
|
||||
}
|
||||
|
||||
void SetDisableTestKeybox(bool disable) {
|
||||
std::unique_lock<std::mutex> auto_lock(init_lock_);
|
||||
session_config_.disable_test_keybox = disable;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex init_lock_;
|
||||
// Shared with all TestCryptoSession instances created by this factory.
|
||||
TestCryptoSessionConfig session_config_;
|
||||
};
|
||||
|
||||
void WvCdmTestBase::SetUp() {
|
||||
@@ -250,7 +277,13 @@ void WvCdmTestBase::SetUp() {
|
||||
std::string(test_info->test_case_name()) + "." + test_info->name();
|
||||
int overwrite = 1; // Set value even if already set.
|
||||
setenv("MODEL_NAME", model_name.c_str(), overwrite);
|
||||
CryptoSession::SetCryptoSessionFactory(new TestCryptoSessionFactory());
|
||||
TestCryptoSessionFactory* factory = new TestCryptoSessionFactory();
|
||||
CryptoSession::SetCryptoSessionFactory(factory);
|
||||
const char* const disable_test_keybox_flag = getenv("DISABLE_TEST_KEYBOX");
|
||||
if (disable_test_keybox_flag != nullptr &&
|
||||
strcmp(disable_test_keybox_flag, "yes") == 0) {
|
||||
factory->SetDisableTestKeybox(true);
|
||||
}
|
||||
// TODO(fredgc): Add a test version of DeviceFiles.
|
||||
}
|
||||
|
||||
@@ -291,15 +324,11 @@ void WvCdmTestBase::Provision() {
|
||||
const CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::unique_ptr<wvutil::FileSystem> file_system(CreateTestFileSystem());
|
||||
TestCdmEngine cdm_engine(file_system.get(),
|
||||
std::shared_ptr<EngineMetrics>(new EngineMetrics));
|
||||
std::make_shared<EngineMetrics>());
|
||||
ProvisioningHolder provisioner(&cdm_engine, config_);
|
||||
provisioner.Provision(cert_type, binary_provisioning_);
|
||||
}
|
||||
|
||||
// TODO(fredgc): Replace this with a pre-defined DRM certificate. We could do
|
||||
// that because either the device is using a known test keybox with a known
|
||||
// device key, or the device is using an OEM certificate, and we can extract
|
||||
// that certificate from the provisioning request.
|
||||
void WvCdmTestBase::EnsureProvisioned() {
|
||||
CdmSessionId session_id;
|
||||
std::unique_ptr<wvutil::FileSystem> file_system(CreateTestFileSystem());
|
||||
@@ -307,7 +336,7 @@ void WvCdmTestBase::EnsureProvisioned() {
|
||||
// GenerateKeyRequest will actually load the wrapped private key.
|
||||
// Either may return a NEED_PROVISIONING error, so both have to be checked.
|
||||
TestCdmEngine cdm_engine(file_system.get(),
|
||||
std::shared_ptr<EngineMetrics>(new EngineMetrics));
|
||||
std::make_shared<EngineMetrics>());
|
||||
CdmResponseType status = cdm_engine.OpenSession(config_.key_system(), nullptr,
|
||||
nullptr, &session_id);
|
||||
CdmAppParameterMap app_parameters;
|
||||
@@ -339,6 +368,36 @@ void WvCdmTestBase::EnsureProvisioned() {
|
||||
ASSERT_EQ(NO_ERROR, cdm_engine.CloseSession(session_id));
|
||||
}
|
||||
|
||||
bool WvCdmTestBase::ExtractSignedMessage(const std::string& response,
|
||||
std::string* result) {
|
||||
static const std::string kMessageStart = "\"signedResponse\": \"";
|
||||
static const std::string kMessageEnd = "\"";
|
||||
std::string response_string;
|
||||
size_t start = response.find(kMessageStart);
|
||||
|
||||
if (start == response.npos) {
|
||||
// Assume serialized protobuf message.
|
||||
result->assign(response);
|
||||
} else {
|
||||
// Assume JSON-wrapped protobuf.
|
||||
size_t end = response.find(kMessageEnd, start + kMessageStart.length());
|
||||
if (end == response.npos) {
|
||||
LOGE("ExtractSignedMessage cannot locate end substring");
|
||||
result->clear();
|
||||
return false;
|
||||
}
|
||||
size_t result_string_size = end - start - kMessageStart.length();
|
||||
result->assign(response, start + kMessageStart.length(),
|
||||
result_string_size);
|
||||
}
|
||||
|
||||
if (result->empty()) {
|
||||
LOGE("ExtractSignedMessage: Response message is empty");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WvCdmTestBase::Initialize(int argc, const char* const argv[],
|
||||
const std::string& extra_help_text) {
|
||||
Properties::Init();
|
||||
@@ -457,7 +516,13 @@ bool WvCdmTestBase::Initialize(int argc, const char* const argv[],
|
||||
// Figure out which tests are appropriate for OEMCrypto, based on features
|
||||
// supported.
|
||||
wvoec::global_features.Initialize();
|
||||
wvoec::global_features.set_cast_receiver(is_cast_receiver);
|
||||
if (is_cast_receiver) {
|
||||
// Turn it on if passed in on the command line. Do not turn these tests off
|
||||
// automtically -- instead, we'll let the caller filter them out if they
|
||||
// need to. These tests will normally only run if the device claims to
|
||||
// support being a cast receiver.
|
||||
wvoec::global_features.set_cast_receiver(is_cast_receiver);
|
||||
}
|
||||
// If the user requests --no_filter, we don't change the filter, otherwise, we
|
||||
// filter out features that are not supported.
|
||||
if (filter_tests) {
|
||||
|
||||
Reference in New Issue
Block a user