149 lines
6.0 KiB
C++
149 lines
6.0 KiB
C++
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine Master
|
|
// License Agreement.
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <chrono>
|
|
#include <memory>
|
|
#include <thread>
|
|
|
|
#include "create_test_file_system.h"
|
|
#include "crypto_session.h"
|
|
#include "oec_device_features.h"
|
|
#include "properties.h"
|
|
#include "provisioning_holder.h"
|
|
#include "test_base.h"
|
|
#include "test_printers.h"
|
|
#include "test_sleep.h"
|
|
#include "url_request.h"
|
|
|
|
using wvcdm::metrics::EngineMetrics;
|
|
|
|
namespace wvcdm {
|
|
class CdmOtaKeyboxTest : public ::testing::Test {
|
|
public:
|
|
void SetUp() override {
|
|
if (wvoec::global_features.provisioning_method != OEMCrypto_Keybox) {
|
|
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
|
|
}
|
|
::testing::Test::SetUp();
|
|
Properties::Init();
|
|
if (wvoec::global_features.provisioning_method != OEMCrypto_Keybox) {
|
|
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
|
|
}
|
|
const ::testing::TestInfo* const test_info =
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name());
|
|
// Some test environments allow the model name of the device to be set
|
|
// dynamically using an environment variable. The model name will show up
|
|
// in the license server logs as the part of the device idenfication as
|
|
// "model_name".
|
|
std::string model_name =
|
|
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);
|
|
// Reset the crypto session factory, so that a default one will be created.
|
|
// For these tests, we do *not* want to use the test crypto session factory
|
|
// because it automatically installs the test keybox on initialization. We
|
|
// do not want that because we are testing keybox provisioning.
|
|
CryptoSession::SetCryptoSessionFactory(nullptr);
|
|
}
|
|
|
|
void Provision(TestCdmEngine* cdm_engine) {
|
|
ConfigTestEnv config = *WvCdmTestBase::default_config_;
|
|
ProvisioningHolder provisioner(cdm_engine, config);
|
|
CdmCertificateType cert_type = kCertificateWidevine;
|
|
constexpr bool binary_provisioning = false;
|
|
provisioner.Provision(cert_type, binary_provisioning);
|
|
}
|
|
};
|
|
|
|
TEST_F(CdmOtaKeyboxTest, TestThatTheBuildFilesWork) { ASSERT_TRUE(true); }
|
|
|
|
/** Verify that the CDM can open a session with at most two provisioning
|
|
* steps. Unlike almost all of the other Widevine CDM tests, this test does
|
|
* **not** install a test keybox before running. For that reason, this test is
|
|
* expected to fail if the device does not either support Keybox OTA recover or
|
|
* have an existing keybox or OEM Certificate. For those devices, this test
|
|
* should be skipped.
|
|
*/
|
|
TEST_F(CdmOtaKeyboxTest, BasicTest) {
|
|
std::unique_ptr<wvutil::FileSystem> file_system(CreateTestFileSystem());
|
|
TestCdmEngine cdm_engine(file_system.get(),
|
|
std::shared_ptr<EngineMetrics>(new EngineMetrics));
|
|
// Remove any existing certificate.
|
|
cdm_engine.Unprovision(kSecurityLevelL1);
|
|
std::string system_id;
|
|
CdmResponseType system_id_status =
|
|
cdm_engine.QueryStatus(kLevelDefault, QUERY_KEY_SYSTEM_ID, &system_id);
|
|
if (system_id_status == NO_ERROR) {
|
|
std::cout << " "
|
|
<< "System ID before test: " << system_id << "\n";
|
|
} else {
|
|
std::cout << " "
|
|
<< "Could not find system id before test. ";
|
|
PrintTo(system_id_status, &std::cout);
|
|
std::cout << "\n";
|
|
}
|
|
|
|
CdmSessionId session_id;
|
|
ConfigTestEnv config = *WvCdmTestBase::default_config_;
|
|
|
|
CdmResponseType status = cdm_engine.OpenSession(config.key_system(), nullptr,
|
|
nullptr, &session_id);
|
|
// If there is no keybox or there is no drm cert, we should get a
|
|
// NEED_PROVISIONING response. If there is a keybox and a drm cert, there
|
|
// should be no other error and this test is finished.
|
|
if (status != NEED_PROVISIONING) {
|
|
ASSERT_EQ(NO_ERROR, status);
|
|
std::cout << "Device does not need provisioning. Skipping rest of test.\n";
|
|
return;
|
|
}
|
|
std::cout << "First provisioning process.\n";
|
|
Provision(&cdm_engine);
|
|
system_id_status =
|
|
cdm_engine.QueryStatus(kLevelDefault, QUERY_KEY_SYSTEM_ID, &system_id);
|
|
if (system_id_status == NO_ERROR) {
|
|
std::cout << " "
|
|
<< "System ID after first provisioning: " << system_id << "\n";
|
|
} else {
|
|
std::cout << " "
|
|
<< "Could not find system id after first provisioning. ";
|
|
PrintTo(system_id_status, &std::cout);
|
|
std::cout << "\n";
|
|
}
|
|
|
|
// After the first provisioning pass, we try to open a session again. If the
|
|
// first provisioning was to install a keybox, this provisioning should be to
|
|
// install a drm cert. If the first provisioning step installed a drm cert,
|
|
// there should be no other error and this test is finished.
|
|
status = cdm_engine.OpenSession(config.key_system(), nullptr, nullptr,
|
|
&session_id);
|
|
if (status != NEED_PROVISIONING) {
|
|
ASSERT_EQ(NO_ERROR, status);
|
|
std::cout << "Device does not need provisioning. Skipping rest of test.\n";
|
|
return;
|
|
}
|
|
std::cout << "Second provisioning process.\n";
|
|
Provision(&cdm_engine);
|
|
system_id_status =
|
|
cdm_engine.QueryStatus(kLevelDefault, QUERY_KEY_SYSTEM_ID, &system_id);
|
|
if (system_id_status == NO_ERROR) {
|
|
std::cout << " "
|
|
<< "System ID after second provisioning: " << system_id << "\n";
|
|
} else {
|
|
std::cout << " "
|
|
<< "Could not find system id after second provisioning. ";
|
|
PrintTo(system_id_status, &std::cout);
|
|
std::cout << "\n";
|
|
}
|
|
|
|
// After the second provisioning pass, we should be able to open a session
|
|
// and continue.
|
|
status = cdm_engine.OpenSession(config.key_system(), nullptr, nullptr,
|
|
&session_id);
|
|
ASSERT_EQ(NO_ERROR, status);
|
|
// Full recovery will be tested with higher level integration tests.
|
|
}
|
|
} // namespace wvcdm
|