Source release v2.2.0-0-903 + third_party libs
Change-Id: I03f670eaeb052bc741abb347be06f8ddc58418e7
This commit is contained in:
@@ -3,11 +3,11 @@
|
||||
#include "device_files.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
# define SHA256 CC_SHA256
|
||||
# define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#define SHA256 CC_SHA256
|
||||
#define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
|
||||
#else
|
||||
# include <openssl/sha.h>
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
@@ -39,13 +39,15 @@ 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;
|
||||
hash->resize(SHA256_DIGEST_LENGTH);
|
||||
|
||||
const unsigned char* input =
|
||||
reinterpret_cast<const unsigned char*>(data.data());
|
||||
reinterpret_cast<const unsigned char*>(data.data());
|
||||
unsigned char* output = reinterpret_cast<unsigned char*>(&(*hash)[0]);
|
||||
SHA256(input, data.size(), output);
|
||||
return true;
|
||||
@@ -56,9 +58,10 @@ bool Hash(const std::string& data, std::string* hash) {
|
||||
namespace wvcdm {
|
||||
|
||||
DeviceFiles::DeviceFiles()
|
||||
: file_(NULL), security_level_(kSecurityLevelUninitialized),
|
||||
initialized_(false), test_file_(false) {
|
||||
}
|
||||
: file_(NULL),
|
||||
security_level_(kSecurityLevelUninitialized),
|
||||
initialized_(false),
|
||||
test_file_(false) {}
|
||||
|
||||
DeviceFiles::~DeviceFiles() {
|
||||
if (test_file_) file_.release();
|
||||
@@ -100,7 +103,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,
|
||||
@@ -115,8 +118,7 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
|
||||
}
|
||||
|
||||
std::string serialized_file;
|
||||
if (!RetrieveFile(kCertificateFileName, &serialized_file))
|
||||
return false;
|
||||
if (!RetrieveHashedFile(kCertificateFileName, &serialized_file)) return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(serialized_file)) {
|
||||
@@ -189,7 +191,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,
|
||||
@@ -206,7 +208,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)) {
|
||||
@@ -310,7 +312,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);
|
||||
@@ -319,6 +321,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) {
|
||||
@@ -329,7 +341,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
|
||||
std::string serialized_file;
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveFile(kUsageInfoFileName, &serialized_file)) {
|
||||
if (!RetrieveHashedFile(kUsageInfoFileName, &serialized_file)) {
|
||||
file.set_type(video_widevine_client::sdk::File::USAGE_INFO);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
} else {
|
||||
@@ -344,13 +356,11 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
|
||||
provider_session->set_token(provider_session_token.data(),
|
||||
provider_session_token.size());
|
||||
provider_session->set_license_request(key_request.data(),
|
||||
key_request.size());
|
||||
provider_session->set_license(key_response.data(),
|
||||
key_response.size());
|
||||
provider_session->set_license_request(key_request.data(), key_request.size());
|
||||
provider_session->set_license(key_response.data(), key_response.size());
|
||||
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFile(kUsageInfoFileName, serialized_file);
|
||||
return StoreFileWithHash(kUsageInfoFileName, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteUsageInfo(const std::string& provider_session_token) {
|
||||
@@ -360,7 +370,7 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& provider_session_token) {
|
||||
}
|
||||
|
||||
std::string serialized_file;
|
||||
if (!RetrieveFile(kUsageInfoFileName, &serialized_file)) return false;
|
||||
if (!RetrieveHashedFile(kUsageInfoFileName, &serialized_file)) return false;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!file.ParseFromString(serialized_file)) {
|
||||
@@ -372,15 +382,18 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& provider_session_token) {
|
||||
int index = 0;
|
||||
bool found = false;
|
||||
for (; index < usage_info->sessions_size(); ++index) {
|
||||
if (usage_info->sessions(index).token().compare(provider_session_token) == 0) {
|
||||
if (usage_info->sessions(index).token().compare(provider_session_token) ==
|
||||
0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
LOGW("DeviceFiles::DeleteUsageInfo: Unable to find provider session "
|
||||
"token: %s", b2a_hex(provider_session_token).c_str());
|
||||
LOGW(
|
||||
"DeviceFiles::DeleteUsageInfo: Unable to find provider session "
|
||||
"token: %s",
|
||||
b2a_hex(provider_session_token).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -392,7 +405,7 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& provider_session_token) {
|
||||
sessions->RemoveLast();
|
||||
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFile(kUsageInfoFileName, serialized_file);
|
||||
return StoreFileWithHash(kUsageInfoFileName, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteUsageInfo() {
|
||||
@@ -411,21 +424,22 @@ bool DeviceFiles::DeleteUsageInfo() {
|
||||
return file_->Remove(path);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveUsageInfo(std::vector<
|
||||
std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info) {
|
||||
bool DeviceFiles::RetrieveUsageInfo(
|
||||
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == usage_info) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: license destination not "
|
||||
LOGW(
|
||||
"DeviceFiles::RetrieveUsageInfo: license destination not "
|
||||
"provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string serialized_file;
|
||||
if (!RetrieveFile(kUsageInfoFileName, &serialized_file)) {
|
||||
if (!RetrieveHashedFile(kUsageInfoFileName, &serialized_file)) {
|
||||
std::string path;
|
||||
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
|
||||
return false;
|
||||
@@ -457,22 +471,22 @@ bool DeviceFiles::RetrieveUsageInfo(std::vector<
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -484,9 +498,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;
|
||||
}
|
||||
|
||||
@@ -497,59 +526,62 @@ 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)",
|
||||
bytes,
|
||||
serialized_hash_file.size());
|
||||
if (bytes != static_cast<ssize_t>(serialized_file.size())) {
|
||||
LOGW(
|
||||
"DeviceFiles::StoreFileRaw: write failed: (actual: %d, "
|
||||
"expected: %d)",
|
||||
bytes, serialized_file.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("DeviceFiles::StoreFile: success: %s (%db)",
|
||||
path.c_str(),
|
||||
serialized_hash_file.size());
|
||||
LOGV("DeviceFiles::StoreFileRaw: success: %s (%db)", path.c_str(),
|
||||
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;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
|
||||
LOGW("DeviceFiles::StoreFile: Unable to get base path");
|
||||
LOGW("DeviceFiles::StoreFileWithHash: Unable to get base path");
|
||||
return false;
|
||||
}
|
||||
|
||||
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());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -563,27 +595,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");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -663,9 +695,9 @@ std::string DeviceFiles::GetLicenseFileNameExtension() {
|
||||
return kLicenseFileNameExt;
|
||||
}
|
||||
|
||||
std::string DeviceFiles::GetUsageInfoFileName() {
|
||||
return kUsageInfoFileName;
|
||||
}
|
||||
std::string DeviceFiles::GetUsageInfoFileName() { return kUsageInfoFileName; }
|
||||
|
||||
std::string DeviceFiles::GetBlankFileData() { return kBlankFileData; }
|
||||
|
||||
void DeviceFiles::SetTestFile(File* file) {
|
||||
file_.reset(file);
|
||||
|
||||
Reference in New Issue
Block a user