Allows sharing of keys between sessions
This change allows the app to specify that keys may be shared by sessions. The app enables this by setting the session sharing properties in DRM Plugin. Keys are shared only amoungst the specified group of sessions. Merged from widevine CDM repo * https://widevine-internal-review.googlesource.com/#/c/8019/ * https://widevine-internal-review.googlesource.com/#/c/8021/ Bug: 11013707 Change-Id: I52db41a53138b4fc563ebc6d38a623f23f7cdfb5
This commit is contained in:
@@ -16,6 +16,9 @@ class CdmClientPropertySet {
|
||||
virtual std::string security_level() const = 0;
|
||||
virtual bool use_privacy_mode() const = 0;
|
||||
virtual std::vector<uint8_t> service_certificate() const = 0;
|
||||
virtual bool is_session_sharing_enabled() const = 0;
|
||||
virtual uint32_t session_sharing_id() const = 0;
|
||||
virtual void set_session_sharing_id(uint32_t id) = 0;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -93,6 +93,7 @@ class CdmEngine : public TimerHandler {
|
||||
|
||||
// Is the key known to any session?
|
||||
virtual bool IsKeyValid(const KeyId& key_id);
|
||||
virtual bool FindSessionForKey(const KeyId& key_id, CdmSessionId* sessionId);
|
||||
|
||||
// Event listener related methods
|
||||
virtual bool AttachEventListener(const CdmSessionId& session_id,
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#ifndef CDM_BASE_LICENSE_H_
|
||||
#define CDM_BASE_LICENSE_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace video_widevine_server {
|
||||
@@ -41,6 +43,7 @@ class CdmLicense {
|
||||
CdmKeyResponse& license_response,
|
||||
CdmKeyResponse& license_renewal_response);
|
||||
bool HasInitData() { return !init_data_.empty(); }
|
||||
bool IsKeyLoaded(const KeyId& key_id);
|
||||
|
||||
private:
|
||||
bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
|
||||
@@ -58,6 +61,7 @@ class CdmLicense {
|
||||
std::string service_certificate_;
|
||||
std::string init_data_;
|
||||
bool initialized_;
|
||||
std::set<KeyId> loaded_keys_;
|
||||
|
||||
// Used for certificate based licensing
|
||||
CdmKeyMessage key_request_;
|
||||
|
||||
@@ -66,6 +66,7 @@ class Properties {
|
||||
static const std::vector<uint8_t> GetServiceCertificate(
|
||||
const CdmSessionId& session_id);
|
||||
static bool UsePrivacyMode(const CdmSessionId& session_id);
|
||||
static uint32_t GetSessionSharingId(const CdmSessionId& session_id);
|
||||
|
||||
static bool AddSessionPropertySet(
|
||||
const CdmSessionId& session_id,
|
||||
|
||||
@@ -525,6 +525,29 @@ bool CdmEngine::IsKeyValid(const KeyId& key_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CdmEngine::FindSessionForKey(
|
||||
const KeyId& key_id,
|
||||
CdmSessionId* session_id) {
|
||||
if (NULL == session_id) {
|
||||
LOGE("CdmEngine::FindSessionForKey: session id not provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t session_sharing_id = Properties::GetSessionSharingId(*session_id);
|
||||
|
||||
for (CdmSessionMap::iterator iter = sessions_.begin();
|
||||
iter != sessions_.end(); ++iter) {
|
||||
CdmSessionId id = iter->second->session_id();
|
||||
if (Properties::GetSessionSharingId(id) == session_sharing_id) {
|
||||
if (iter->second->IsKeyValid(key_id)) {
|
||||
*session_id = id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CdmEngine::AttachEventListener(
|
||||
const CdmSessionId& session_id,
|
||||
WvCdmEventListener* listener) {
|
||||
|
||||
@@ -335,22 +335,7 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
|
||||
}
|
||||
|
||||
bool CdmSession::IsKeyValid(const KeyId& key_id) {
|
||||
if (crypto_session_.get() == NULL || !crypto_session_->IsOpen())
|
||||
return false;
|
||||
|
||||
if (key_id_ != key_id) {
|
||||
// OEMCrypto does not provide a way to query the existence/validity of a
|
||||
// key. SelectKey can be used to check whether a key is valid, but there
|
||||
// is also a side effect - the key is selected for decryption, which might
|
||||
// be undesirable and it posts restriction on the use of IsKeyValid API.
|
||||
// TODO(kqyang, gmorgan): consider adding a function in OEMCrypto to check
|
||||
// if a key is valid.
|
||||
if (!crypto_session_->SelectKey(key_id)) {
|
||||
return false;
|
||||
}
|
||||
key_id_ = key_id;
|
||||
}
|
||||
return true;
|
||||
return license_parser_.IsKeyLoaded(key_id);
|
||||
}
|
||||
|
||||
CdmSessionId CdmSession::GenerateSessionId() {
|
||||
|
||||
@@ -539,9 +539,22 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
// merge from Eureka)
|
||||
policy_engine_->SetLicense(license);
|
||||
|
||||
return session_->LoadKeys(signed_response.msg(), signed_response.signature(),
|
||||
mac_key_iv, mac_key, key_array.size(),
|
||||
&key_array[0]);
|
||||
CdmResponseType resp = session_->LoadKeys(signed_response.msg(),
|
||||
signed_response.signature(),
|
||||
mac_key_iv,
|
||||
mac_key,
|
||||
key_array.size(),
|
||||
&key_array[0]);
|
||||
|
||||
if (KEY_ADDED == resp) {
|
||||
loaded_keys_.clear();
|
||||
for (std::vector<CryptoKey>::iterator it = key_array.begin();
|
||||
it != key_array.end();
|
||||
++it) {
|
||||
loaded_keys_.insert(it->key_id());
|
||||
}
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
CdmResponseType CdmLicense::HandleKeyUpdateResponse(
|
||||
@@ -753,4 +766,8 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse(
|
||||
}
|
||||
}
|
||||
|
||||
bool CdmLicense::IsKeyLoaded(const KeyId& key_id) {
|
||||
return loaded_keys_.find(key_id) != loaded_keys_.end();
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -100,6 +100,17 @@ bool Properties::UsePrivacyMode(const CdmSessionId& session_id) {
|
||||
return property_set->use_privacy_mode();
|
||||
}
|
||||
|
||||
uint32_t Properties::GetSessionSharingId(const CdmSessionId& session_id) {
|
||||
const CdmClientPropertySet* property_set =
|
||||
GetCdmClientPropertySet(session_id);
|
||||
if (NULL == property_set) {
|
||||
LOGE("Properties::GetSessionSharingId: cannot find property set for %s",
|
||||
session_id.c_str());
|
||||
return 0;
|
||||
}
|
||||
return property_set->session_sharing_id();
|
||||
}
|
||||
|
||||
bool Properties::GetSecurityLevelDirectories(std::vector<std::string>* dirs) {
|
||||
dirs->resize(sizeof(kSecurityLevelDirs)/sizeof(const char*));
|
||||
for (size_t i = 0; i < dirs->size(); ++i) {
|
||||
|
||||
Reference in New Issue
Block a user