125 lines
4.5 KiB
C++
125 lines
4.5 KiB
C++
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
|
|
#include <assert.h>
|
|
#include <gtest/gtest.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "cdm.h"
|
|
#include "log.h"
|
|
#include "oec_device_features.h"
|
|
#include "stderr_logger.h"
|
|
#include "test_base.h"
|
|
#include "test_host.h"
|
|
|
|
widevine::StderrLogger g_stderr_logger;
|
|
std::string g_sandbox_id;
|
|
|
|
namespace widevine {
|
|
namespace {
|
|
constexpr char kSandboxIdParam[] = "--sandbox_id=";
|
|
constexpr char kCertPathParam[] = "--cert_path=";
|
|
constexpr char kCertKeyPathParam[] = "--cert_key_path=";
|
|
|
|
// Following the pattern established by help text in test_base.cpp
|
|
constexpr char kExtraHelpText[] =
|
|
" --sandbox_id=<sandbox_id>\n"
|
|
" Specifies the Sandbox ID that should be sent to OEMCrypto via\n"
|
|
" OEMCrypto_SetSandbox(). On most platforms, since Sandbox IDs are not\n"
|
|
" in use, this parameter should be omitted.\n"
|
|
" --cert_path=<cert_path>\n"
|
|
" Path to a preloaded DRM certificate. This may speed up some tests\n"
|
|
" by skipping the provisioning step. On most platforms, this parameter\n"
|
|
" parameter should be omitted.\n"
|
|
" --cert_key_path=<cert_key_path>\n"
|
|
" Path to a key in preloaded DRM certificate. This should only be used\n"
|
|
" if the device has a baked in cert.\n";
|
|
|
|
bool ReadFile(const std::string& path, std::string* output) {
|
|
output->clear();
|
|
std::ifstream fs(path, std::ios::in | std::ios::binary);
|
|
if (!fs) {
|
|
LOGE("Failed to open %s: %s", path.c_str(), strerror(errno));
|
|
return false;
|
|
}
|
|
std::stringstream buffer;
|
|
buffer << fs.rdbuf();
|
|
*output = buffer.str();
|
|
return true;
|
|
}
|
|
|
|
// Reads a file from the command line arguments.
|
|
// The file path is expected to be the first argument after the flag.
|
|
// For example, if the flag is "--cert_path=" and the command line is
|
|
// cdm_test_runner --cert_path=/path/to/cert
|
|
// then the file at /path/to/cert will be read.
|
|
// The flag will be removed from the command line arguments.
|
|
bool ReadFileFromArg(const char* path_flag, std::vector<std::string>& args,
|
|
std::string* data) {
|
|
auto path_iter = std::find_if(std::begin(args) + 1, std::end(args),
|
|
[path_flag](const std::string& elem) -> bool {
|
|
return elem.find(path_flag) == 0;
|
|
});
|
|
if (path_iter != std::end(args)) {
|
|
const std::string path = path_iter->substr(strlen(path_flag));
|
|
args.erase(path_iter);
|
|
return ReadFile(path, data);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int Main(Cdm::IStorage* storage, Cdm::IClock* clock, Cdm::ITimer* timer,
|
|
Cdm::ILogger* logger, int argc, char** argv) {
|
|
// Find and filter out the Sandbox ID, if any.
|
|
std::vector<std::string> args(argv, argv + argc);
|
|
auto sandbox_id_iter = std::find_if(std::begin(args) + 1, std::end(args),
|
|
[](const std::string& elem) -> bool {
|
|
return elem.find(kSandboxIdParam) == 0;
|
|
});
|
|
if (sandbox_id_iter != std::end(args)) {
|
|
g_sandbox_id = sandbox_id_iter->substr(strlen(kSandboxIdParam));
|
|
args.erase(sandbox_id_iter);
|
|
}
|
|
|
|
Cdm::Status status = Cdm::initialize(
|
|
Cdm::kOpaqueHandle, storage, clock, timer, logger,
|
|
static_cast<Cdm::LogLevel>(wvutil::g_cutoff), g_sandbox_id);
|
|
(void)status; // status is now used when assertions are turned off.
|
|
assert(status == Cdm::kSuccess);
|
|
|
|
std::string data;
|
|
if (ReadFileFromArg(kCertPathParam, args, &data)) {
|
|
g_host->set_baked_in_cert(data);
|
|
}
|
|
if (ReadFileFromArg(kCertKeyPathParam, args, &data)) {
|
|
wvoec::global_features.set_rsa_test_key(
|
|
std::vector<uint8_t>(data.begin(), data.end()));
|
|
}
|
|
|
|
std::vector<const char*> new_argv(args.size());
|
|
std::transform(
|
|
std::begin(args), std::end(args), std::begin(new_argv),
|
|
[](const std::string& arg) -> const char* { return arg.c_str(); });
|
|
// This must take place after the call to Cdm::initialize() because it makes
|
|
// calls that are only valid after the library is initialized.
|
|
if (!wvcdm::WvCdmTestBase::Initialize(static_cast<int>(new_argv.size()),
|
|
new_argv.data(), kExtraHelpText)) {
|
|
return 1;
|
|
}
|
|
|
|
// Init gtest after oemcrypto and cdm host have been initialized.
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
return RUN_ALL_TESTS();
|
|
}
|
|
} // namespace widevine
|