|
|
|
|
@@ -81,9 +81,7 @@ CdmSession::CdmSession(wvutil::FileSystem* file_system,
|
|
|
|
|
security_level_(kSecurityLevelUninitialized),
|
|
|
|
|
requested_security_level_(kLevelDefault),
|
|
|
|
|
is_initial_usage_update_(true),
|
|
|
|
|
is_usage_update_needed_(false),
|
|
|
|
|
mock_license_parser_in_use_(false),
|
|
|
|
|
mock_policy_engine_in_use_(false) {
|
|
|
|
|
is_usage_update_needed_(false) {
|
|
|
|
|
assert(metrics_); // metrics_ must not be null.
|
|
|
|
|
crypto_metrics_ = metrics_->GetCryptoMetrics();
|
|
|
|
|
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
|
|
|
|
|
@@ -866,18 +864,10 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_index) {
|
|
|
|
|
// The usage entry cannot be deleted if it has a crypto session handling
|
|
|
|
|
// it, so close and reopen session.
|
|
|
|
|
UpdateUsageEntryInformation();
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
crypto_session_->Close();
|
|
|
|
|
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
|
|
|
|
|
M_TIME(sts = crypto_session_->Open(requested_security_level_),
|
|
|
|
|
crypto_metrics_, crypto_session_open_, sts, requested_security_level_);
|
|
|
|
|
if (sts != NO_ERROR) return sts;
|
|
|
|
|
|
|
|
|
|
usage_table_ = nullptr;
|
|
|
|
|
bool has_support = false;
|
|
|
|
|
if (crypto_session_->HasUsageTableSupport(&has_support) && has_support) {
|
|
|
|
|
usage_table_ = crypto_session_->GetUsageTable();
|
|
|
|
|
}
|
|
|
|
|
crypto_session_->Close();
|
|
|
|
|
CdmResponseType sts = ResetCryptoSession();
|
|
|
|
|
if (sts != NO_ERROR) return sts;
|
|
|
|
|
|
|
|
|
|
if (usage_table_ == nullptr) {
|
|
|
|
|
LOGE("Usage table header unavailable");
|
|
|
|
|
@@ -1012,14 +1002,8 @@ bool CdmSession::StoreLicense(CdmOfflineLicenseState state, int* error_detail) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType CdmSession::RemoveKeys() {
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
|
|
|
|
|
// Ignore errors
|
|
|
|
|
M_TIME(sts = crypto_session_->Open(requested_security_level_),
|
|
|
|
|
crypto_metrics_, crypto_session_open_, sts, requested_security_level_);
|
|
|
|
|
policy_engine_.reset(
|
|
|
|
|
new PolicyEngine(session_id_, nullptr, crypto_session_.get()));
|
|
|
|
|
return CdmResponseType(NO_ERROR);
|
|
|
|
|
crypto_session_->Close();
|
|
|
|
|
return ResetCryptoSession();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType CdmSession::RemoveLicense() {
|
|
|
|
|
@@ -1249,7 +1233,7 @@ CdmResponseType CdmSession::LoadPrivateKey(
|
|
|
|
|
DrmKeyTypeToMetricValue(private_key.type()));
|
|
|
|
|
|
|
|
|
|
drm_certificate_ = drm_certificate;
|
|
|
|
|
wrapped_private_key_ = std::move(private_key);
|
|
|
|
|
wrapped_private_key_ = private_key;
|
|
|
|
|
return CdmResponseType(NO_ERROR);
|
|
|
|
|
case SESSION_LOST_STATE_ERROR:
|
|
|
|
|
case SYSTEM_INVALIDATED_ERROR:
|
|
|
|
|
@@ -1313,6 +1297,77 @@ CdmResponseType CdmSession::GenerateRsaSignature(const std::string& message,
|
|
|
|
|
return crypto_session_->GenerateRsaSignature(message, signature, scheme);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType CdmSession::ResetCryptoSession() {
|
|
|
|
|
LOGD("Resetting crypto session: session_id = %s, ksid = %s",
|
|
|
|
|
IdToString(session_id_), IdToString(key_set_id_));
|
|
|
|
|
if (mock_crypto_session_in_use_) {
|
|
|
|
|
// If the crypto session is not reset, then there is nothing to do.
|
|
|
|
|
return CdmResponseType(NO_ERROR);
|
|
|
|
|
}
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
|
|
|
|
|
usage_table_ = nullptr;
|
|
|
|
|
M_TIME(sts = crypto_session_->Open(requested_security_level_),
|
|
|
|
|
crypto_metrics_, crypto_session_open_, sts, requested_security_level_);
|
|
|
|
|
|
|
|
|
|
CdmResponseType final_sts(NO_ERROR);
|
|
|
|
|
if (sts != NO_ERROR) {
|
|
|
|
|
// Challenging case, still need to reset other components.
|
|
|
|
|
LOGE("Failed to open crypto session: sts = %s", sts.ToString().c_str());
|
|
|
|
|
final_sts = sts;
|
|
|
|
|
} else {
|
|
|
|
|
// Reset all component dependent on the crypto session.
|
|
|
|
|
security_level_ = crypto_session_->GetSecurityLevel();
|
|
|
|
|
crypto_metrics_->crypto_session_security_level_.Record(security_level_);
|
|
|
|
|
|
|
|
|
|
if (!file_handle_->Init(security_level_)) {
|
|
|
|
|
LOGE("Unable to initialize file handle");
|
|
|
|
|
final_sts = CdmResponseType(SESSION_FILE_HANDLE_INIT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!file_handle_->HasCertificate(atsc_mode_enabled_)) {
|
|
|
|
|
LOGE("Missing certificate: atsc_mode_enabled = %s",
|
|
|
|
|
BoolToString(atsc_mode_enabled_));
|
|
|
|
|
final_sts = CdmResponseType(NEED_PROVISIONING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool has_support = false;
|
|
|
|
|
if (crypto_session_->HasUsageTableSupport(&has_support) && has_support) {
|
|
|
|
|
usage_table_ = crypto_session_->GetUsageTable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Even if the session is not open, other members need new session pointer.
|
|
|
|
|
if (mock_policy_engine_in_use_) {
|
|
|
|
|
// Simply pass the new pointer.
|
|
|
|
|
policy_engine_->set_crypto_session(crypto_session_.get());
|
|
|
|
|
} else {
|
|
|
|
|
// Attempt to maintain event listener.
|
|
|
|
|
WvCdmEventListener* event_listener =
|
|
|
|
|
policy_engine_ ? policy_engine_->event_listener() : nullptr;
|
|
|
|
|
policy_engine_.reset(
|
|
|
|
|
new PolicyEngine(session_id_, event_listener, crypto_session_.get()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mock_license_parser_in_use_) {
|
|
|
|
|
license_parser_->set_crypto_session(crypto_session_.get());
|
|
|
|
|
license_parser_->set_policy_engine(policy_engine_.get());
|
|
|
|
|
} else {
|
|
|
|
|
license_parser_.reset(new CdmLicense(session_id_));
|
|
|
|
|
std::string service_certificate;
|
|
|
|
|
if (!Properties::GetServiceCertificate(session_id_, &service_certificate))
|
|
|
|
|
service_certificate.clear();
|
|
|
|
|
if (!license_parser_->Init(Properties::UsePrivacyMode(session_id_),
|
|
|
|
|
service_certificate, crypto_session_.get(),
|
|
|
|
|
policy_engine_.get())) {
|
|
|
|
|
LOGE("Failed to initialize license parser");
|
|
|
|
|
final_sts = CdmResponseType(LICENSE_PARSER_INIT_ERROR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return final_sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For testing only - takes ownership of pointers
|
|
|
|
|
|
|
|
|
|
void CdmSession::set_license_parser(CdmLicense* license_parser) {
|
|
|
|
|
@@ -1322,6 +1377,7 @@ void CdmSession::set_license_parser(CdmLicense* license_parser) {
|
|
|
|
|
|
|
|
|
|
void CdmSession::set_crypto_session(CryptoSession* crypto_session) {
|
|
|
|
|
crypto_session_.reset(crypto_session);
|
|
|
|
|
mock_crypto_session_in_use_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CdmSession::set_policy_engine(PolicyEngine* policy_engine) {
|
|
|
|
|
|