Merge "Disallow the ability to load offline licenses more than once" into sc-dev

This commit is contained in:
Rahul Frias
2021-05-07 22:21:03 +00:00
committed by Android (Google) Code Review
7 changed files with 1 additions and 99 deletions

View File

@@ -253,12 +253,6 @@ class CdmSession {
// true otherwise. // true otherwise.
bool VerifyOfflineUsageEntry(); bool VerifyOfflineUsageEntry();
// On android, we previously permitted a license to be loaded and restored
// in the same session. This method releases resources so that
// CdmSession::Init can safely be invoked before a new license is restored.
// TODO(b/161865160): Investigate whether we can dispense with this scenario.
virtual CdmResponseType ReleaseOfflineResources();
// These setters are for testing only. Takes ownership of the pointers. // These setters are for testing only. Takes ownership of the pointers.
void set_license_parser(CdmLicense* license_parser); void set_license_parser(CdmLicense* license_parser);
void set_crypto_session(CryptoSession* crypto_session); void set_crypto_session(CryptoSession* crypto_session);
@@ -318,21 +312,6 @@ class CdmSession {
// license type release and offline related information // license type release and offline related information
CdmKeySetId key_set_id_; CdmKeySetId key_set_id_;
// TODO(b/161865160): Use these variables to cache Init parameters. Remove
// when b/ has been addressed.
// |cdm_client_property_set_| and |event_listener_| point to a data
// member of WVDrmPlugin or WVDrmPlugin itself. It is safe for CdmSession
// to make use of these objects without taking ownership since WVDrmPlugin
// lifetime exceeds CdmSession (WVDrmPlugin indirectly owns CdmSession
// objects). These pointers if set, should be valid till CdmSession
// destruction.
CdmClientPropertySet* cdm_client_property_set_ = nullptr;
CdmSessionId* forced_session_id_ = nullptr;
CdmSessionId forced_session_id_value_;
WvCdmEventListener* event_listener_ = nullptr;
bool has_license_been_loaded_ = false;
bool has_license_been_restored_ = false;
bool mock_license_parser_in_use_; bool mock_license_parser_in_use_;
bool mock_policy_engine_in_use_; bool mock_policy_engine_in_use_;

View File

@@ -414,7 +414,7 @@ enum CdmResponseType : int32_t {
SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE = 359, SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE = 359,
LICENSE_USAGE_ENTRY_MISSING = 360, LICENSE_USAGE_ENTRY_MISSING = 360,
LOAD_USAGE_ENTRY_INVALID_SESSION = 361, LOAD_USAGE_ENTRY_INVALID_SESSION = 361,
RESTORE_OFFLINE_LICENSE_ERROR_3 = 362, // previously RESTORE_OFFLINE_LICENSE_ERROR_3 = 362,
NO_SRM_VERSION = 363, NO_SRM_VERSION = 363,
SESSION_NOT_FOUND_23 = 364, SESSION_NOT_FOUND_23 = 364,
CERT_PROVISIONING_RESPONSE_ERROR_9 = 365, CERT_PROVISIONING_RESPONSE_ERROR_9 = 365,

View File

@@ -122,18 +122,6 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
return REINIT_ERROR; return REINIT_ERROR;
} }
// Save parameters in case Init needs to be called again (load and restore
// offline license)
if (cdm_client_property_set)
cdm_client_property_set_ = cdm_client_property_set;
if (forced_session_id) {
forced_session_id_value_ = *forced_session_id;
forced_session_id_ = &forced_session_id_value_;
}
if (event_listener) event_listener_ = event_listener;
if (cdm_client_property_set && cdm_client_property_set->security_level() == if (cdm_client_property_set && cdm_client_property_set->security_level() ==
QUERY_VALUE_SECURITY_LEVEL_L3) { QUERY_VALUE_SECURITY_LEVEL_L3) {
requested_security_level_ = kLevel3; requested_security_level_ = kLevel3;
@@ -217,22 +205,6 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
return NO_ERROR; return NO_ERROR;
} }
CdmResponseType CdmSession::ReleaseOfflineResources() {
// |license_parser_| and |policy_engine_| are reset in Init. No need to
// deallocate here.
if (has_provider_session_token() && supports_usage_info() && !is_release_) {
UpdateUsageEntryInformation();
}
if (!key_set_id_.empty()) {
// Unreserve the license ID.
file_handle_->UnreserveLicenseId(key_set_id_);
}
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
initialized_ = false;
return NO_ERROR;
}
CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
CdmLicenseType license_type, CdmLicenseType license_type,
int* error_detail) { int* error_detail) {
@@ -244,30 +216,6 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
file_handle_->UnreserveLicenseId(key_set_id_); file_handle_->UnreserveLicenseId(key_set_id_);
} }
// On android, we previously permitted an offline license to be loaded and
// restored in the same session. OEMCrypto v16+ disallows it so we need to
// release and initialize an OEMCrypto session. We will still prohibit
// multiple restore attempts on the same session.
// TODO(b/161865160): reevalute this scenario. Should we also
// (a) only allow a restore for the same key set ID that was loaded
// (b) if (a) is true, indicate success and do nothing else rather than
// release resources and reinitialize.
// We need to investigate the conditions that caused an app failure and
// led us to add a test to support this use case as there were multiple
// related issues.
if (!has_license_been_loaded_ && has_license_been_restored_) {
LOGE("Disallow multiple offline license restores");
return RESTORE_OFFLINE_LICENSE_ERROR_3;
}
if (has_license_been_loaded_) {
CdmResponseType status = ReleaseOfflineResources();
if (status != NO_ERROR) return status;
status =
Init(cdm_client_property_set_, forced_session_id_, event_listener_);
if (status != NO_ERROR) return status;
}
has_license_been_restored_ = true;
key_set_id_ = key_set_id; key_set_id_ = key_set_id;
DeviceFiles::CdmLicenseData license_data; DeviceFiles::CdmLicenseData license_data;
@@ -633,7 +581,6 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
sts = StoreLicense(); sts = StoreLicense();
if (sts != NO_ERROR) return sts; if (sts != NO_ERROR) return sts;
} }
has_license_been_loaded_ = true;
return KEY_ADDED; return KEY_ADDED;
} }

View File

@@ -734,9 +734,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
case RESTORE_OFFLINE_LICENSE_ERROR_2: case RESTORE_OFFLINE_LICENSE_ERROR_2:
*os << "RESTORE_OFFLINE_LICENSE_ERROR_2"; *os << "RESTORE_OFFLINE_LICENSE_ERROR_2";
break; break;
case RESTORE_OFFLINE_LICENSE_ERROR_3:
*os << "RESTORE_OFFLINE_LICENSE_ERROR_3";
break;
case REWRAP_DEVICE_RSA_KEY_ERROR: case REWRAP_DEVICE_RSA_KEY_ERROR:
*os << "REWRAP_DEVICE_RSA_KEY_ERROR"; *os << "REWRAP_DEVICE_RSA_KEY_ERROR";
break; break;

View File

@@ -2939,23 +2939,6 @@ TEST_F(WvCdmRequestLicenseTest, DisallowMultipleRestoreOfflineKeyTest) {
decryptor_->CloseSession(session_id_); decryptor_->CloseSession(session_id_);
} }
TEST_F(WvCdmRequestLicenseTest, AllowLoadAndRestoreOfflineKeyTest) {
Unprovision();
Provision();
std::string key_id;
std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth);
decryptor_->OpenSession(config_.key_system(), nullptr, kDefaultCdmIdentifier,
nullptr, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(config_.license_server(), client_auth);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_->RestoreKey(session_id_, key_set_id_));
decryptor_->CloseSession(session_id_);
}
TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) {
Unprovision(); Unprovision();
Provision(); Provision();

View File

@@ -477,8 +477,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kRenewKeyError2; return kRenewKeyError2;
case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_2: case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_2:
return kRestoreOfflineLicenseError2; return kRestoreOfflineLicenseError2;
case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_3:
return kRestoreOfflineLicenseError3;
case wvcdm::SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH: case wvcdm::SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH:
return kSampleAndSubsampleSizeMismatch; return kSampleAndSubsampleSizeMismatch;
case wvcdm::SESSION_FILE_HANDLE_INIT_ERROR: case wvcdm::SESSION_FILE_HANDLE_INIT_ERROR:

View File

@@ -167,7 +167,6 @@ static Status mapCdmResponseType_1_0(wvcdm::CdmResponseType res) {
case wvcdm::RENEW_KEY_ERROR_1: case wvcdm::RENEW_KEY_ERROR_1:
case wvcdm::RENEW_KEY_ERROR_2: case wvcdm::RENEW_KEY_ERROR_2:
case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_2: case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_2:
case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_3:
case wvcdm::NOT_INITIALIZED_ERROR: case wvcdm::NOT_INITIALIZED_ERROR:
case wvcdm::REINIT_ERROR: case wvcdm::REINIT_ERROR:
case wvcdm::SESSION_KEYS_NOT_FOUND: case wvcdm::SESSION_KEYS_NOT_FOUND:
@@ -616,7 +615,6 @@ static S mapCdmResponseType(wvcdm::CdmResponseType res) {
err = ::drm::V1_4::Status::LICENSE_RESTORE_ERROR; err = ::drm::V1_4::Status::LICENSE_RESTORE_ERROR;
break; break;
case wvcdm::GET_RELEASED_LICENSE_ERROR: case wvcdm::GET_RELEASED_LICENSE_ERROR:
case wvcdm::RESTORE_OFFLINE_LICENSE_ERROR_3:
err = ::drm::V1_4::Status::LICENSE_STATE_ERROR; err = ::drm::V1_4::Status::LICENSE_STATE_ERROR;
break; break;
case wvcdm::DEVICE_CERTIFICATE_ERROR_2: case wvcdm::DEVICE_CERTIFICATE_ERROR_2: