Merge "Generate Key Set IDs at Key Request Generation Time"
This commit is contained in:
committed by
Android (Google) Code Review
commit
dff91b48c1
@@ -174,7 +174,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters,
|
||||
CdmKeyMessage* key_request,
|
||||
std::string* server_url) {
|
||||
std::string* server_url,
|
||||
CdmKeySetId* key_set_id_out) {
|
||||
LOGI("CdmEngine::GenerateKeyRequest");
|
||||
|
||||
CdmSessionId id = session_id;
|
||||
@@ -227,7 +228,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
|
||||
sts = iter->second->GenerateKeyRequest(init_data, license_type,
|
||||
app_parameters, key_request,
|
||||
server_url);
|
||||
server_url, key_set_id_out);
|
||||
|
||||
if (KEY_MESSAGE != sts) {
|
||||
if (sts == NEED_PROVISIONING) {
|
||||
|
||||
@@ -194,7 +194,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
|
||||
CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
const InitializationData& init_data, const CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
|
||||
std::string* server_url) {
|
||||
std::string* server_url, CdmKeySetId* key_set_id) {
|
||||
if (crypto_session_.get() == NULL) {
|
||||
LOGW("CdmSession::GenerateKeyRequest: Invalid crypto session");
|
||||
return UNKNOWN_ERROR;
|
||||
@@ -229,6 +229,10 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
LOGW("CdmSession::GenerateKeyRequest: init data absent");
|
||||
return KEY_ERROR;
|
||||
}
|
||||
if (is_offline_ && !GenerateKeySetId(&key_set_id_)) {
|
||||
LOGE("CdmSession::GenerateKeyRequest: Unable to generate key set ID");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
if (!license_parser_->PrepareKeyRequest(init_data, license_type,
|
||||
app_parameters, session_id_,
|
||||
@@ -242,6 +246,7 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
offline_release_server_url_ = *server_url;
|
||||
}
|
||||
|
||||
if (key_set_id) *key_set_id = key_set_id_;
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +282,7 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response,
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
|
||||
*key_set_id = key_set_id_;
|
||||
if (key_set_id) *key_set_id = key_set_id_;
|
||||
return KEY_ADDED;
|
||||
}
|
||||
}
|
||||
@@ -465,13 +470,15 @@ bool CdmSession::GenerateKeySetId(CdmKeySetId* key_set_id) {
|
||||
key_set_id->clear();
|
||||
}
|
||||
}
|
||||
// Reserve the license ID to avoid collisions.
|
||||
file_handle_->ReserveLicenseId(*key_set_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::StoreLicense() {
|
||||
if (is_offline_) {
|
||||
if (!GenerateKeySetId(&key_set_id_)) {
|
||||
LOGE("CdmSession::StoreLicense: Unable to generate key set Id");
|
||||
if (key_set_id_.empty()) {
|
||||
LOGE("CdmSession::StoreLicense: No key set ID");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ const char* kSecurityLevelPathCompatibilityExclusionList[] = {"ay64.dat"};
|
||||
size_t kSecurityLevelPathCompatibilityExclusionListSize =
|
||||
sizeof(kSecurityLevelPathCompatibilityExclusionList) /
|
||||
sizeof(*kSecurityLevelPathCompatibilityExclusionList);
|
||||
// Some platforms cannot store a truly blank file, so we use a W for Widevine.
|
||||
const char kBlankFileData[] = "W";
|
||||
|
||||
bool Hash(const std::string& data, std::string* hash) {
|
||||
if (!hash) return false;
|
||||
@@ -102,7 +104,7 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate,
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
|
||||
return StoreFile(kCertificateFileName, serialized_file);
|
||||
return StoreFileWithHash(kCertificateFileName, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveCertificate(std::string* certificate,
|
||||
@@ -117,7 +119,7 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
|
||||
}
|
||||
|
||||
std::string serialized_file;
|
||||
if (!RetrieveFile(kCertificateFileName, &serialized_file))
|
||||
if (!RetrieveHashedFile(kCertificateFileName, &serialized_file))
|
||||
return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
@@ -195,7 +197,7 @@ bool DeviceFiles::StoreLicense(const std::string& key_set_id,
|
||||
file.SerializeToString(&serialized_file);
|
||||
|
||||
std::string file_name = key_set_id + kLicenseFileNameExt;
|
||||
return StoreFile(file_name.c_str(), serialized_file);
|
||||
return StoreFileWithHash(file_name.c_str(), serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveLicense(const std::string& key_set_id,
|
||||
@@ -214,7 +216,7 @@ bool DeviceFiles::RetrieveLicense(const std::string& key_set_id,
|
||||
|
||||
std::string serialized_file;
|
||||
std::string file_name = key_set_id + kLicenseFileNameExt;
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_file)) return false;
|
||||
if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(serialized_file)) {
|
||||
@@ -320,7 +322,7 @@ bool DeviceFiles::LicenseExists(const std::string& key_set_id) {
|
||||
|
||||
std::string path;
|
||||
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
|
||||
LOGW("DeviceFiles::StoreFile: Unable to get base path");
|
||||
LOGW("DeviceFiles::LicenseExists: Unable to get base path");
|
||||
return false;
|
||||
}
|
||||
path.append(key_set_id);
|
||||
@@ -329,6 +331,16 @@ bool DeviceFiles::LicenseExists(const std::string& key_set_id) {
|
||||
return file_->Exists(path);
|
||||
}
|
||||
|
||||
bool DeviceFiles::ReserveLicenseId(const std::string& key_set_id) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::ReserveLicenseId: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file_name = key_set_id + kLicenseFileNameExt;
|
||||
return StoreFileRaw(file_name.c_str(), kBlankFileData);
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
const CdmKeyMessage& key_request,
|
||||
const CdmKeyResponse& key_response,
|
||||
@@ -341,7 +353,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
std::string serialized_file;
|
||||
video_widevine_client::sdk::File file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_file)) {
|
||||
if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) {
|
||||
file.set_type(video_widevine_client::sdk::File::USAGE_INFO);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
} else {
|
||||
@@ -362,7 +374,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
key_response.size());
|
||||
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFile(file_name.c_str(), serialized_file);
|
||||
return StoreFileWithHash(file_name.c_str(), serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
|
||||
@@ -374,7 +386,7 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
|
||||
|
||||
std::string serialized_file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_file)) return false;
|
||||
if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(serialized_file)) {
|
||||
@@ -406,7 +418,7 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
|
||||
sessions->RemoveLast();
|
||||
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFile(file_name.c_str(), serialized_file);
|
||||
return StoreFileWithHash(file_name.c_str(), serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteAllUsageInfoForApp(const std::string& app_id) {
|
||||
@@ -442,7 +454,7 @@ bool DeviceFiles::RetrieveUsageInfo(
|
||||
|
||||
std::string serialized_file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_file)) {
|
||||
if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) {
|
||||
std::string path;
|
||||
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
|
||||
return false;
|
||||
@@ -484,7 +496,7 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
|
||||
}
|
||||
std::string serialized_file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!RetrieveFile(file_name.c_str(), &serialized_file)) return false;
|
||||
if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(serialized_file)) {
|
||||
@@ -510,22 +522,22 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreFile(const char* name,
|
||||
const std::string& serialized_file) {
|
||||
bool DeviceFiles::StoreFileWithHash(const char* name,
|
||||
const std::string& serialized_file) {
|
||||
if (!file_.get()) {
|
||||
LOGW("DeviceFiles::StoreFile: Invalid file handle");
|
||||
LOGW("DeviceFiles::StoreFileWithHash: Invalid file handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
LOGW("DeviceFiles::StoreFile: Unspecified file name parameter");
|
||||
LOGW("DeviceFiles::StoreFileWithHash: Unspecified file name parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate SHA hash
|
||||
std::string hash;
|
||||
if (!Hash(serialized_file, &hash)) {
|
||||
LOGW("DeviceFiles::StoreFile: Hash computation failed");
|
||||
LOGW("DeviceFiles::StoreFileWithHash: Hash computation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -537,9 +549,24 @@ bool DeviceFiles::StoreFile(const char* name,
|
||||
std::string serialized_hash_file;
|
||||
hash_file.SerializeToString(&serialized_hash_file);
|
||||
|
||||
return StoreFileRaw(name, serialized_hash_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreFileRaw(const char* name,
|
||||
const std::string& serialized_file) {
|
||||
if (!file_.get()) {
|
||||
LOGW("DeviceFiles::StoreFileRaw: Invalid file handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
LOGW("DeviceFiles::StoreFileRaw: Unspecified file name parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
|
||||
LOGW("DeviceFiles::StoreFile: Unable to get base path");
|
||||
LOGW("DeviceFiles::StoreFileRaw: Unable to get base path");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -550,40 +577,40 @@ bool DeviceFiles::StoreFile(const char* name,
|
||||
path += name;
|
||||
|
||||
if (!file_->Open(path, File::kCreate | File::kTruncate | File::kBinary)) {
|
||||
LOGW("DeviceFiles::StoreFile: File open failed: %s", path.c_str());
|
||||
LOGW("DeviceFiles::StoreFileRaw: File open failed: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t bytes = file_->Write(serialized_hash_file.data(),
|
||||
serialized_hash_file.size());
|
||||
ssize_t bytes = file_->Write(serialized_file.data(),
|
||||
serialized_file.size());
|
||||
file_->Close();
|
||||
|
||||
if (bytes != static_cast<ssize_t>(serialized_hash_file.size())) {
|
||||
LOGW("DeviceFiles::StoreFile: write failed: (actual: %d, expected: %d)",
|
||||
if (bytes != static_cast<ssize_t>(serialized_file.size())) {
|
||||
LOGW("DeviceFiles::StoreFileRaw: write failed: (actual: %d, expected: %d)",
|
||||
bytes,
|
||||
serialized_hash_file.size());
|
||||
serialized_file.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("DeviceFiles::StoreFile: success: %s (%db)",
|
||||
LOGV("DeviceFiles::StoreFileRaw: success: %s (%db)",
|
||||
path.c_str(),
|
||||
serialized_hash_file.size());
|
||||
serialized_file.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveFile(const char* name, std::string* serialized_file) {
|
||||
bool DeviceFiles::RetrieveHashedFile(const char* name, std::string* serialized_file) {
|
||||
if (!file_.get()) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Invalid file handle");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Invalid file handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Unspecified file name parameter");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Unspecified file name parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!serialized_file) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Unspecified serialized_file parameter");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Unspecified serialized_file parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -596,13 +623,13 @@ bool DeviceFiles::RetrieveFile(const char* name, std::string* serialized_file) {
|
||||
path += name;
|
||||
|
||||
if (!file_->Exists(path)) {
|
||||
LOGW("DeviceFiles::RetrieveFile: %s does not exist", path.c_str());
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: %s does not exist", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t bytes = file_->FileSize(path);
|
||||
if (bytes <= 0) {
|
||||
LOGW("DeviceFiles::RetrieveFile: File size invalid: %s", path.c_str());
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: File size invalid: %s", path.c_str());
|
||||
// Remove the corrupted file so the caller will not get the same error
|
||||
// when trying to access the file repeatedly, causing the system to stall.
|
||||
file_->Remove(path);
|
||||
@@ -619,27 +646,27 @@ bool DeviceFiles::RetrieveFile(const char* name, std::string* serialized_file) {
|
||||
file_->Close();
|
||||
|
||||
if (bytes != static_cast<ssize_t>(serialized_hash_file.size())) {
|
||||
LOGW("DeviceFiles::RetrieveFile: read failed");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("DeviceFiles::RetrieveFile: success: %s (%db)", path.c_str(),
|
||||
LOGV("DeviceFiles::RetrieveHashedFile: success: %s (%db)", path.c_str(),
|
||||
serialized_hash_file.size());
|
||||
|
||||
HashedFile hash_file;
|
||||
if (!hash_file.ParseFromString(serialized_hash_file)) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Unable to parse hash file");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Unable to parse hash file");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string hash;
|
||||
if (!Hash(hash_file.file(), &hash)) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Hash computation failed");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Hash computation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hash.compare(hash_file.hash())) {
|
||||
LOGW("DeviceFiles::RetrieveFile: Hash mismatch");
|
||||
LOGW("DeviceFiles::RetrieveHashedFile: Hash mismatch");
|
||||
// Remove the corrupted file so the caller will not get the same error
|
||||
// when trying to access the file repeatedly, causing the system to stall.
|
||||
file_->Remove(path);
|
||||
@@ -733,6 +760,8 @@ std::string DeviceFiles::GetUsageInfoFileName(const std::string& app_id) {
|
||||
std::string(kUsageInfoFileNameExt);
|
||||
}
|
||||
|
||||
std::string DeviceFiles::GetBlankFileData() { return kBlankFileData; }
|
||||
|
||||
void DeviceFiles::SetTestFile(File* file) {
|
||||
file_.reset(file);
|
||||
test_file_ = true;
|
||||
|
||||
Reference in New Issue
Block a user