Remove old test license holder

[ Merged from http://go/wvgerrit/143750 ]

The old test license holder would generate a minimal license response,
but could not correctly mimic important server logic introduced in the
v16 server. Since all integration tests now have policies on the UAT
server, we do not need these minimalist license responses anymore.

Bug: 192700112
Test: GtsMediaTestCases on sunfish
Change-Id: I78c1b6085a6d0239840a11f2b904902210e5e61c
This commit is contained in:
Rahul Frias
2022-03-14 02:15:04 -07:00
parent 13da693dd6
commit fd00a8af24
2 changed files with 0 additions and 323 deletions

View File

@@ -576,266 +576,6 @@ bool WvCdmTestBase::Initialize(int argc, const char* const argv[],
return true;
}
TestLicenseHolder::TestLicenseHolder(CdmEngine* cdm_engine)
: cdm_engine_(cdm_engine),
oemcrypto_api_(0),
session_opened_(false),
// Keys are initialized with simple values, and the correct size:
derived_mac_key_server_(MAC_KEY_SIZE, 'a'),
derived_mac_key_client_(MAC_KEY_SIZE, 'b'),
mac_key_server_(MAC_KEY_SIZE, 'c'),
mac_key_client_(MAC_KEY_SIZE, 'd'),
enc_key_(CONTENT_KEY_SIZE, 'e'),
session_key_(CONTENT_KEY_SIZE, 'f') {}
TestLicenseHolder::~TestLicenseHolder() { CloseSession(); }
void TestLicenseHolder::OpenSession(const std::string& key_system) {
CdmResponseType status =
cdm_engine_->OpenSession(key_system, nullptr, nullptr, &session_id_);
ASSERT_EQ(status, NO_ERROR);
ASSERT_NE("", session_id_) << "Could not open CDM session.";
ASSERT_TRUE(cdm_engine_->IsOpenSession(session_id_));
session_opened_ = true;
}
void TestLicenseHolder::CloseSession() {
if (session_opened_) {
cdm_engine_->CloseSession(session_id_);
session_opened_ = false;
}
}
void TestLicenseHolder::GenerateKeyRequest(
const std::string& key_id, const std::string& init_data_type_string) {
ASSERT_TRUE(session_opened_);
CdmAppParameterMap app_parameters;
CdmKeySetId key_set_id;
InitializationData init_data(init_data_type_string, key_id);
if (wvutil::g_cutoff >= wvutil::CDM_LOG_DEBUG) init_data.DumpToLogs();
CdmKeyRequest key_request;
CdmResponseType result = cdm_engine_->GenerateKeyRequest(
session_id_, key_set_id, init_data, kLicenseTypeStreaming, app_parameters,
&key_request);
EXPECT_EQ(KEY_MESSAGE, result);
signed_license_request_data_ = key_request.message;
EXPECT_EQ(kKeyRequestTypeInitial, key_request.type);
}
void TestLicenseHolder::CreateDefaultLicense() {
video_widevine::SignedMessage signed_message;
EXPECT_TRUE(signed_message.ParseFromString(signed_license_request_data_));
license_request_data_ = signed_message.msg();
video_widevine::LicenseRequest license_request;
EXPECT_TRUE(license_request.ParseFromString(license_request_data_));
video_widevine::ClientIdentification client_id = license_request.client_id();
EXPECT_EQ(
video_widevine::ClientIdentification_TokenType_DRM_DEVICE_CERTIFICATE,
client_id.type());
oemcrypto_api_ =
(client_id.has_client_capabilities() &&
client_id.client_capabilities().has_oem_crypto_api_version())
? client_id.client_capabilities().oem_crypto_api_version()
: 0;
std::string signed_buffer = license_request_data_;
std::string core_message = signed_message.has_oemcrypto_core_message()
? signed_message.oemcrypto_core_message()
: "";
if (oemcrypto_api_ >= 17) {
signed_buffer = signed_message.oemcrypto_core_message() + signed_buffer;
}
// Extract the RSA key from the DRM certificate.
std::string token = client_id.token();
video_widevine::SignedDrmCertificate signed_drm_cert;
EXPECT_TRUE(signed_drm_cert.ParseFromString(token));
video_widevine::DrmCertificate drm_cert;
EXPECT_TRUE(drm_cert.ParseFromString(signed_drm_cert.drm_certificate()));
EXPECT_TRUE(rsa_key_.Init(drm_cert.public_key()));
EXPECT_TRUE(
rsa_key_.VerifySignature(signed_buffer, signed_message.signature()));
DeriveKeysFromSessionKey();
video_widevine::LicenseIdentification* license_id = license()->mutable_id();
license_id->set_request_id("TestCase");
license_id->set_session_id(session_id_);
license_id->set_type(video_widevine::STREAMING);
license_id->set_version(0);
::video_widevine::License_Policy* policy = license()->mutable_policy();
policy->set_can_play(true);
policy->set_can_persist(false);
policy->set_can_renew(false);
policy->set_playback_duration_seconds(0);
policy->set_license_duration_seconds(0);
AddMacKey();
}
void TestLicenseHolder::AddMacKey() {
video_widevine::License_KeyContainer* key_container = license()->add_key();
std::vector<uint8_t> iv(KEY_IV_SIZE, 'v');
std::string iv_s(iv.begin(), iv.end());
key_container->set_iv(iv_s);
key_container->set_type(video_widevine::License_KeyContainer_KeyType_SIGNING);
// Combine server and client mac keys.
std::vector<uint8_t> keys(mac_key_server_);
keys.insert(keys.end(), mac_key_client_.begin(), mac_key_client_.end());
std::string encrypted_keys =
WvCdmTestBase::Aes128CbcEncrypt(enc_key_, keys, iv);
key_container->set_key(encrypted_keys);
}
video_widevine::License_KeyContainer* TestLicenseHolder::AddKey(
const KeyId& key_id, const std::vector<uint8_t>& key_data,
const wvoec::KeyControlBlock& block_in) {
video_widevine::License_KeyContainer* key_container = license()->add_key();
wvoec::KeyControlBlock block = block_in;
if (block.verification[0] == 0) {
block.verification[0] = 'k';
block.verification[1] = 'c';
block.verification[2] = '1';
// This will work until oemcrypto api 20.
block.verification[3] = '0' + wvoec::global_features.api_version - 10;
}
key_container->set_id(key_id);
key_container->set_type(video_widevine::License_KeyContainer_KeyType_CONTENT);
key_container->set_level(
video_widevine::License_KeyContainer_SecurityLevel_SW_SECURE_CRYPTO);
std::vector<uint8_t> iv(KEY_IV_SIZE, 'v');
std::string iv_s(iv.begin(), iv.end());
key_container->set_iv(iv_s);
std::string encrypted_key_data =
WvCdmTestBase::Aes128CbcEncrypt(enc_key_, key_data, iv);
// TODO(b/111069024): remove this!
std::string padding(CONTENT_KEY_SIZE, '-');
key_container->set_key(encrypted_key_data + padding);
// TODO(b/192700112): This mock license server should parse the core message
// request, and only encrypt the key control block if the API is greater than
// or equal to 16.5. For now, we can pass tests on the v17 branch by checking
// against v17.0.
if (oemcrypto_api_ >= 17) {
std::string block_s(reinterpret_cast<const char*>(&block),
reinterpret_cast<const char*>(&block) + sizeof(block));
key_container->mutable_key_control()->set_key_control_block(block_s);
} else {
std::vector<uint8_t> block_v(
reinterpret_cast<const uint8_t*>(&block),
reinterpret_cast<const uint8_t*>(&block) + sizeof(block));
std::vector<uint8_t> block_iv(KEY_IV_SIZE, 'w');
std::string block_iv_s(block_iv.begin(), block_iv.end());
std::string encrypted_block =
WvCdmTestBase::Aes128CbcEncrypt(key_data, block_v, block_iv);
key_container->mutable_key_control()->set_iv(block_iv_s);
key_container->mutable_key_control()->set_key_control_block(
encrypted_block);
}
return key_container;
}
void TestLicenseHolder::SignAndLoadLicense() {
#if 0 // Need to turn off protobuf_lite to use this.
LOGV("License = %s\n", license_.DebugString().c_str());
#endif
std::string license_data;
license_.SerializeToString(&license_data);
std::string signature =
WvCdmTestBase::SignHMAC(license_data, derived_mac_key_server_);
std::string session_key_s(session_key_.begin(), session_key_.end());
std::string encrypted_session_key;
EXPECT_TRUE(rsa_key_.Encrypt(session_key_s, &encrypted_session_key));
video_widevine::SignedMessage signed_response;
signed_response.set_msg(license_data);
signed_response.set_type(video_widevine::SignedMessage_MessageType_LICENSE);
signed_response.set_session_key(encrypted_session_key);
signed_response.set_signature(signature);
std::string response_data;
signed_response.SerializeToString(&response_data);
CdmKeySetId key_set_id;
CdmLicenseType license_type; // Required for AddKey. Result value ignored.
EXPECT_EQ(KEY_ADDED, cdm_engine_->AddKey(session_id_, response_data,
&license_type, &key_set_id));
}
void TestLicenseHolder::DeriveKeysFromSessionKey() {
std::string context;
GenerateMacContext(license_request_data_, &context);
std::vector<uint8_t> mac_key_context(context.begin(), context.end());
GenerateEncryptContext(license_request_data_, &context);
std::vector<uint8_t> enc_key_context(context.begin(), context.end());
ASSERT_TRUE(
DeriveKey(session_key_, mac_key_context, 1, &derived_mac_key_server_));
std::vector<uint8_t> mac_key_part2;
ASSERT_TRUE(DeriveKey(session_key_, mac_key_context, 2, &mac_key_part2));
derived_mac_key_server_.insert(derived_mac_key_server_.end(),
mac_key_part2.begin(), mac_key_part2.end());
ASSERT_TRUE(
DeriveKey(session_key_, mac_key_context, 3, &derived_mac_key_client_));
ASSERT_TRUE(DeriveKey(session_key_, mac_key_context, 4, &mac_key_part2));
derived_mac_key_client_.insert(derived_mac_key_client_.end(),
mac_key_part2.begin(), mac_key_part2.end());
std::vector<uint8_t> enc_key;
ASSERT_TRUE(DeriveKey(session_key_, enc_key_context, 1, &enc_key_));
}
bool TestLicenseHolder::DeriveKey(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& context,
int counter, std::vector<uint8_t>* out) {
if (key.empty() || counter > 4 || context.empty() || out == nullptr) {
LOGE("DeriveKey(): bad context");
return false;
}
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
CMAC_CTX* cmac_ctx = CMAC_CTX_new();
if (!cmac_ctx) {
LOGE("DeriveKey(): cmac failure");
return false;
}
if (!CMAC_Init(cmac_ctx, &key[0], key.size(), cipher, nullptr)) {
LOGE("DeriveKey(): CMAC_Init");
CMAC_CTX_free(cmac_ctx);
return false;
}
std::vector<uint8_t> message;
message.push_back(counter);
message.insert(message.end(), context.begin(), context.end());
if (!CMAC_Update(cmac_ctx, &message[0], message.size())) {
LOGE("DeriveKey(): CMAC_Update");
CMAC_CTX_free(cmac_ctx);
return false;
}
size_t reslen;
uint8_t res[128];
if (!CMAC_Final(cmac_ctx, res, &reslen)) {
LOGE("DeriveKey(): CMAC_Final");
CMAC_CTX_free(cmac_ctx);
return false;
}
out->assign(res, res + reslen);
CMAC_CTX_free(cmac_ctx);
return true;
}
std::string MakePSSH(const video_widevine::WidevinePsshData& header) {
std::string data;
header.SerializeToString(&data);