Support Offline Licenses
Bug: 8621588 Merge of the following CLs from the Widevine CDM repository: https://widevine-internal-review.googlesource.com/#/c/5602/ https://widevine-internal-review.googlesource.com/#/c/5431/ https://widevine-internal-review.googlesource.com/#/c/5660/ Change-Id: If37940e2535e1a1eca95e4394d8cf9bf689e9c3a
This commit is contained in:
@@ -18,10 +18,14 @@ namespace wvcdm {
|
||||
const char* DeviceFiles::kBasePath = "/data/mediadrm/IDM";
|
||||
const char* DeviceFiles::kPathDelimiter = "/";
|
||||
const char* DeviceFiles::kDeviceCertificateFileName = "cert.bin";
|
||||
const char* DeviceFiles::kLicenseFileNameExt = ".lic";
|
||||
|
||||
// Protobuf generated classes.
|
||||
using video_widevine_client::sdk::DeviceCertificate;
|
||||
using video_widevine_client::sdk::HashedFile;
|
||||
using video_widevine_client::sdk::License;
|
||||
using video_widevine_client::sdk::License_LicenseState_ACTIVE;
|
||||
using video_widevine_client::sdk::License_LicenseState_RELEASING;
|
||||
|
||||
bool DeviceFiles::StoreCertificate(const std::string& certificate,
|
||||
const std::string& wrapped_private_key) {
|
||||
@@ -107,6 +111,148 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreLicense(
|
||||
const std::string& key_set_id,
|
||||
const LicenseState state,
|
||||
const CdmInitData& pssh_data,
|
||||
const CdmKeyMessage& license_request,
|
||||
const CdmKeyResponse& license_message,
|
||||
const CdmKeyMessage& license_renewal_request,
|
||||
const CdmKeyResponse& license_renewal,
|
||||
const std::string& release_server_url) {
|
||||
// Fill in file information
|
||||
video_widevine_client::sdk::File file;
|
||||
|
||||
file.set_type(video_widevine_client::sdk::File::LICENSE);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
|
||||
License* license = file.mutable_license();
|
||||
switch(state) {
|
||||
case kLicenseStateActive:
|
||||
license->set_state(License_LicenseState_ACTIVE);
|
||||
break;
|
||||
case kLicenseStateReleasing:
|
||||
license->set_state(License_LicenseState_RELEASING);
|
||||
break;
|
||||
default:
|
||||
LOGW("DeviceFiles::StoreLicense: Unknown license state: %u", state);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
license->set_pssh_data(pssh_data);
|
||||
license->set_license_request(license_request);
|
||||
license->set_license(license_message);
|
||||
license->set_renewal_request(license_renewal_request);
|
||||
license->set_renewal(license_renewal);
|
||||
license->set_release_server_url(release_server_url);
|
||||
|
||||
std::string serialized_string;
|
||||
file.SerializeToString(&serialized_string);
|
||||
|
||||
// calculate SHA hash
|
||||
std::string hash;
|
||||
if (!Hash(serialized_string, &hash)) {
|
||||
LOGW("DeviceFiles::StoreLicense: Hash computation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// File in hashed file data
|
||||
HashedFile hashed_file;
|
||||
hashed_file.set_file(serialized_string);
|
||||
hashed_file.set_hash(hash);
|
||||
|
||||
hashed_file.SerializeToString(&serialized_string);
|
||||
|
||||
std::string file_name = key_set_id + kLicenseFileNameExt;
|
||||
return StoreFile(file_name.c_str(), serialized_string);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveLicense(
|
||||
const std::string& key_set_id,
|
||||
LicenseState* state,
|
||||
CdmInitData* pssh_data,
|
||||
CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_message,
|
||||
CdmKeyMessage* license_renewal_request,
|
||||
CdmKeyResponse* license_renewal,
|
||||
std::string* release_server_url) {
|
||||
std::string serialized_hashed_file;
|
||||
std::string file_name = key_set_id + kLicenseFileNameExt;
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_hashed_file))
|
||||
return false;
|
||||
|
||||
HashedFile hashed_file;
|
||||
if (!hashed_file.ParseFromString(serialized_hashed_file)) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Unable to parse hash file");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string hash;
|
||||
if (!Hash(hashed_file.file(), &hash)) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Hash computation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hash.compare(hashed_file.hash())) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Hash mismatch");
|
||||
return false;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(hashed_file.file())) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Unable to parse file");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.type() != video_widevine_client::sdk::File::LICENSE) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Incorrect file type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.version() != video_widevine_client::sdk::File::VERSION_1) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: Incorrect file version");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.has_license()) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: License not present");
|
||||
return false;
|
||||
}
|
||||
|
||||
License license = file.license();
|
||||
|
||||
switch(license.state()) {
|
||||
case License_LicenseState_ACTIVE:
|
||||
*state = kLicenseStateActive;
|
||||
break;
|
||||
case License_LicenseState_RELEASING:
|
||||
*state = kLicenseStateReleasing;
|
||||
break;
|
||||
default:
|
||||
LOGW("DeviceFiles::RetrieveLicense: Unrecognized license state: %u",
|
||||
kLicenseStateUnknown);
|
||||
*state = kLicenseStateUnknown;
|
||||
break;
|
||||
}
|
||||
*pssh_data = license.pssh_data();
|
||||
*license_request = license.license_request();
|
||||
*license_message = license.license();
|
||||
*license_renewal_request = license.renewal_request();
|
||||
*license_renewal = license.renewal();
|
||||
*release_server_url = license.release_server_url();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteLicense(const std::string& key_set_id) {
|
||||
std::string path = GetBasePath(kBasePath) + key_set_id + kLicenseFileNameExt;
|
||||
return File::Remove(path);
|
||||
}
|
||||
|
||||
bool DeviceFiles::LicenseExists(const std::string& key_set_id) {
|
||||
std::string path = GetBasePath(kBasePath) + key_set_id + kLicenseFileNameExt;
|
||||
return File::Exists(path);
|
||||
}
|
||||
|
||||
bool DeviceFiles::Hash(const std::string& data, std::string* hash) {
|
||||
if (!hash)
|
||||
return false;
|
||||
@@ -147,6 +293,7 @@ bool DeviceFiles::StoreFile(const char* name, const std::string& data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("DeviceFiles::StoreFile: success: %s (%db)", path.c_str(), data.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -184,6 +331,8 @@ bool DeviceFiles::RetrieveFile(const char* name, std::string* data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("DeviceFiles::RetrieveFile: success: %s (%db)", path.c_str(),
|
||||
data->size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user