Secure stop API related changes
[ Merge of http://go/wvgerrit/44921 ] * Added the ability to remove a single usage information record. * Added a method to retrieve all secure stop Ids. Bug: 69674645 Test: WV unit, integration tests Change-Id: I04ac8224b4bdda69541e61ff1103af3836138228
This commit is contained in:
@@ -188,11 +188,13 @@ class CdmEngine {
|
||||
virtual CdmResponseType ListStoredLicenses(
|
||||
CdmSecurityLevel security_level, std::vector<std::string>* key_set_ids);
|
||||
|
||||
// Return the list of key_set_ids stored as usage records on the
|
||||
// current (origin-specific) file system.
|
||||
virtual CdmResponseType ListUsageRecords(
|
||||
// Return the list of IDs associated with usage records for the
|
||||
// current (origin-specific) file system. At least one parameter
|
||||
// |ksids| or |provider_session_tokens| needs to be supplied.
|
||||
virtual CdmResponseType ListUsageIds(
|
||||
const std::string& app_id, CdmSecurityLevel security_level,
|
||||
std::vector<std::string>* ksids);
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens);
|
||||
|
||||
// Delete the usage record for the given key_set_id. This removes the
|
||||
// usage record in the file system and the OEMCrypto usage record.
|
||||
@@ -220,6 +222,10 @@ class CdmEngine {
|
||||
// security levels.
|
||||
virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id);
|
||||
|
||||
virtual CdmResponseType RemoveUsageInfo(
|
||||
const std::string& app_id,
|
||||
const CdmSecureStopId& secure_stop_id);
|
||||
|
||||
virtual CdmResponseType ReleaseUsageInfo(
|
||||
const CdmUsageInfoReleaseMessage& message);
|
||||
virtual CdmResponseType LoadUsageSession(const CdmKeySetId& key_set_id,
|
||||
|
||||
@@ -105,9 +105,13 @@ class DeviceFiles {
|
||||
const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number);
|
||||
|
||||
// Extract KSIDs from usage information on the file system.
|
||||
virtual bool ListUsageRecords(const std::string& app_id,
|
||||
std::vector<std::string>* ksids);
|
||||
// Retrieve usage identifying information stored on the file system.
|
||||
// The caller needs to specify at least one of |ksids| or
|
||||
// |provider_session_tokens|
|
||||
virtual bool ListUsageIds(
|
||||
const std::string& app_id,
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens);
|
||||
|
||||
// Get the provider session token for the given key_set_id.
|
||||
virtual bool GetProviderSessionToken(const std::string& app_id,
|
||||
|
||||
@@ -929,20 +929,22 @@ CdmResponseType CdmEngine::ListStoredLicenses(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::ListUsageRecords(const std::string& app_id,
|
||||
CdmSecurityLevel security_level,
|
||||
std::vector<std::string>* ksids) {
|
||||
CdmResponseType CdmEngine::ListUsageIds(
|
||||
const std::string& app_id,
|
||||
CdmSecurityLevel security_level,
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens) {
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!ksids) {
|
||||
LOGE("CdmEngine::ListUsageRecords: no response destination");
|
||||
if (!ksids && !provider_session_tokens) {
|
||||
LOGE("CdmEngine::ListUsageIds: no response destination");
|
||||
return INVALID_PARAMETERS_ENG_23;
|
||||
}
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("CdmEngine::ListUsageRecords: unable to initialize device files");
|
||||
LOGE("CdmEngine::ListUsageIds: unable to initialize device files");
|
||||
return LIST_USAGE_ERROR_1;
|
||||
}
|
||||
if (!handle.ListUsageRecords(app_id, ksids)) {
|
||||
LOGE("CdmEngine::ListUsageRecords: ListUsageRecords call failed");
|
||||
if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) {
|
||||
LOGE("CdmEngine::ListUsageIds: ListUsageIds call failed");
|
||||
return LIST_USAGE_ERROR_2;
|
||||
}
|
||||
return NO_ERROR;
|
||||
@@ -1272,6 +1274,85 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) {
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::RemoveUsageInfo(
|
||||
const std::string& app_id,
|
||||
const CdmSecureStopId& provider_session_token) {
|
||||
if (NULL == usage_property_set_.get()) {
|
||||
usage_property_set_.reset(new UsagePropertySet());
|
||||
}
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
|
||||
CdmResponseType status = NO_ERROR;
|
||||
for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) {
|
||||
DeviceFiles handle(file_system_);
|
||||
if (handle.Init(static_cast<CdmSecurityLevel>(j))) {
|
||||
SecurityLevel security_level =
|
||||
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3
|
||||
? kLevel3
|
||||
: kLevelDefault;
|
||||
usage_property_set_->set_security_level(security_level);
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
|
||||
usage_session_->Init(usage_property_set_.get());
|
||||
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
CdmKeyMessage license_request;
|
||||
CdmKeyResponse license_response;
|
||||
CdmUsageEntry usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
|
||||
if (!handle.RetrieveUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token,
|
||||
&license_request, &license_response, &usage_entry,
|
||||
&usage_entry_number)) {
|
||||
// Try other security level
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (usage_session_->get_usage_support_type()) {
|
||||
case kUsageEntrySupport: {
|
||||
status = usage_session_->DeleteUsageEntry(
|
||||
usage_data[0].usage_entry_number);
|
||||
|
||||
if (!handle.DeleteUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
provider_session_token)) {
|
||||
status = REMOVE_USAGE_INFO_ERROR_1;
|
||||
}
|
||||
usage_session_.reset(NULL);
|
||||
return status;
|
||||
}
|
||||
case kUsageTableSupport: {
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
handle.DeleteUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
provider_session_token);
|
||||
scoped_ptr<CryptoSession> crypto_session(
|
||||
new CryptoSession(metrics_.GetCryptoMetrics()));
|
||||
status = crypto_session->Open(
|
||||
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3
|
||||
? kLevel3 : kLevelDefault);
|
||||
if (status == NO_ERROR) {
|
||||
crypto_session->UpdateUsageInformation();
|
||||
status =
|
||||
crypto_session->DeleteUsageInformation(provider_session_token);
|
||||
crypto_session->UpdateUsageInformation();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LOGE("CdmEngine::RemoveUsageInfo: failed to initialize L%d devicefiles",
|
||||
j);
|
||||
status = REMOVE_USAGE_INFO_ERROR_2;
|
||||
}
|
||||
}
|
||||
usage_session_.reset(NULL);
|
||||
return REMOVE_USAGE_INFO_ERROR_3;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::ReleaseUsageInfo(
|
||||
const CdmUsageInfoReleaseMessage& message) {
|
||||
if (NULL == usage_session_.get()) {
|
||||
|
||||
@@ -868,10 +868,22 @@ void CdmSession::GetApplicationId(std::string* app_id) {
|
||||
|
||||
CdmResponseType CdmSession::DeleteMultipleUsageInformation(
|
||||
const std::vector<std::string>& provider_session_tokens) {
|
||||
CdmResponseType sts = crypto_session_->DeleteMultipleUsageInformation(
|
||||
provider_session_tokens);
|
||||
crypto_metrics_->crypto_session_delete_multiple_usage_information_
|
||||
.Increment(sts);
|
||||
CdmUsageSupportType usage_support_type;
|
||||
CdmResponseType sts =
|
||||
crypto_session_->GetUsageSupportType(&usage_support_type);
|
||||
if (sts == NO_ERROR && usage_support_type == kUsageTableSupport) {
|
||||
for (size_t i = 0; i < provider_session_tokens.size(); ++i) {
|
||||
crypto_session_->DeactivateUsageInformation(provider_session_tokens[i]);
|
||||
UpdateUsageTableInformation();
|
||||
}
|
||||
}
|
||||
|
||||
if (sts == NO_ERROR) {
|
||||
sts = crypto_session_->DeleteMultipleUsageInformation(
|
||||
provider_session_tokens);
|
||||
crypto_metrics_->crypto_session_delete_multiple_usage_information_
|
||||
.Increment(sts);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
@@ -464,22 +464,25 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
return StoreFileWithHash(usage_info_file_name, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::ListUsageRecords(const std::string& app_id,
|
||||
std::vector<std::string>* ksids) {
|
||||
bool DeviceFiles::ListUsageIds(
|
||||
const std::string& app_id,
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::ListUsageRecords: not initialized");
|
||||
LOGW("DeviceFiles::ListUsageIds: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ksids == NULL) {
|
||||
LOGW("DeviceFiles::ListUsageRecords: return parameter not provided");
|
||||
if (ksids == NULL && provider_session_tokens == NULL) {
|
||||
LOGW("DeviceFiles::ListUsageIds: ksids or pst parameter not provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty or non-existent file == no usage records.
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!FileExists(file_name) || GetFileSize(file_name) == 0) {
|
||||
ksids->clear();
|
||||
if (ksids != NULL) ksids->clear();
|
||||
if (provider_session_tokens != NULL) provider_session_tokens->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -489,13 +492,19 @@ bool DeviceFiles::ListUsageRecords(const std::string& app_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
ksids->clear();
|
||||
if (ksids != NULL) ksids->clear();
|
||||
if (provider_session_tokens != NULL) provider_session_tokens->clear();
|
||||
|
||||
size_t num_records = file.usage_info().sessions_size();
|
||||
for (size_t i = 0; i < num_records; ++i) {
|
||||
if (!file.usage_info().sessions(i).key_set_id().empty()) {
|
||||
if ((ksids != NULL) &&
|
||||
!file.usage_info().sessions(i).key_set_id().empty()) {
|
||||
ksids->push_back(file.usage_info().sessions(i).key_set_id());
|
||||
}
|
||||
if ((provider_session_tokens != NULL) &&
|
||||
!file.usage_info().sessions(i).token().empty()) {
|
||||
provider_session_tokens->push_back(file.usage_info().sessions(i).token());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2629,6 +2629,73 @@ TEST_F(DeviceFilesUsageInfoTest, ListNullParam) {
|
||||
EXPECT_FALSE(device_files.ListUsageInfoFiles(NULL));
|
||||
}
|
||||
|
||||
TEST_F(DeviceFilesUsageInfoTest, ListIdsNull) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
|
||||
std::string app_id = kUsageInfoTestData[0].app_id;
|
||||
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
EXPECT_FALSE(device_files.ListUsageIds(app_id, NULL, NULL));
|
||||
}
|
||||
|
||||
TEST_F(DeviceFilesUsageInfoTest, ListUsageIds) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
|
||||
int index = 8;
|
||||
std::string app_id = kUsageInfoTestData[index].app_id;
|
||||
|
||||
std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id);
|
||||
std::string path = device_base_path_ + file_name;
|
||||
std::string file_data = (index < 0) ? kEmptyUsageInfoFileData
|
||||
: kUsageInfoTestData[index].file_data;
|
||||
if (index >= 0) {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(file_system, FileSize(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size()));
|
||||
EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file));
|
||||
EXPECT_CALL(file,
|
||||
Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size())))
|
||||
.WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()),
|
||||
Return(file_data.size())));
|
||||
EXPECT_CALL(file, Close());
|
||||
}
|
||||
else {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.WillOnce(Return(false));
|
||||
}
|
||||
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<std::string> key_set_ids;
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
EXPECT_TRUE(device_files.ListUsageIds(
|
||||
app_id, &key_set_ids, &provider_session_tokens));
|
||||
|
||||
EXPECT_EQ(key_set_ids.size(), provider_session_tokens.size());
|
||||
if (index >= 0) {
|
||||
for (size_t i = 0; i < provider_session_tokens.size(); ++i) {
|
||||
bool found = false;
|
||||
for (int j = 0; !found && j <= index; ++j) {
|
||||
if (app_id == kUsageInfoTestData[j].app_id &&
|
||||
kUsageInfoTestData[j].usage_data.provider_session_token ==
|
||||
provider_session_tokens[i] &&
|
||||
kUsageInfoTestData[j].usage_data.key_set_id ==
|
||||
key_set_ids[i]) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DeviceFilesUsageInfoListTest, UsageInfoList) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
@@ -2767,6 +2834,113 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DeviceFilesUsageInfoTest, ListKeySetIds) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
|
||||
int index = GetParam();
|
||||
|
||||
std::string app_id;
|
||||
if (index >= 0) app_id = kUsageInfoTestData[index].app_id;
|
||||
|
||||
std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id);
|
||||
std::string path = device_base_path_ + file_name;
|
||||
std::string file_data = (index < 0) ? kEmptyUsageInfoFileData
|
||||
: kUsageInfoTestData[index].file_data;
|
||||
if (index >= 0) {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(file_system, FileSize(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size()));
|
||||
EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file));
|
||||
EXPECT_CALL(file,
|
||||
Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size())))
|
||||
.WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()),
|
||||
Return(file_data.size())));
|
||||
EXPECT_CALL(file, Close());
|
||||
}
|
||||
else {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.WillOnce(Return(false));
|
||||
}
|
||||
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<std::string> key_set_ids;
|
||||
EXPECT_TRUE(device_files.ListUsageIds(app_id, &key_set_ids, NULL));
|
||||
|
||||
if (index >= 0) {
|
||||
for (size_t i = 0; i < key_set_ids.size(); ++i) {
|
||||
bool found = false;
|
||||
for (int j = 0; !found && j <= index; ++j) {
|
||||
if (app_id == kUsageInfoTestData[j].app_id &&
|
||||
kUsageInfoTestData[j].usage_data.key_set_id ==
|
||||
key_set_ids[i]) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DeviceFilesUsageInfoTest, ListProviderSessionTokenIds) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
|
||||
int index = GetParam();
|
||||
|
||||
std::string app_id;
|
||||
if (index >= 0) app_id = kUsageInfoTestData[index].app_id;
|
||||
|
||||
std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id);
|
||||
std::string path = device_base_path_ + file_name;
|
||||
std::string file_data = (index < 0) ? kEmptyUsageInfoFileData
|
||||
: kUsageInfoTestData[index].file_data;
|
||||
if (index >= 0) {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(file_system, FileSize(StrEq(path)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size()));
|
||||
EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file));
|
||||
EXPECT_CALL(file,
|
||||
Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size())))
|
||||
.WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()),
|
||||
Return(file_data.size())));
|
||||
EXPECT_CALL(file, Close());
|
||||
}
|
||||
else {
|
||||
EXPECT_CALL(file_system, Exists(StrEq(path)))
|
||||
.WillOnce(Return(false));
|
||||
}
|
||||
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
EXPECT_TRUE(
|
||||
device_files.ListUsageIds(app_id, NULL, &provider_session_tokens));
|
||||
|
||||
if (index >= 0) {
|
||||
for (size_t i = 0; i < provider_session_tokens.size(); ++i) {
|
||||
bool found = false;
|
||||
for (int j = 0; !found && j <= index; ++j) {
|
||||
if (app_id == kUsageInfoTestData[j].app_id &&
|
||||
kUsageInfoTestData[j].usage_data.provider_session_token ==
|
||||
provider_session_tokens[i]) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) {
|
||||
MockFileSystem file_system;
|
||||
MockFile file;
|
||||
|
||||
Reference in New Issue
Block a user