Remove Sub-Licenses and Sub-Sessions
(This is a merge of http://go/wvgerrit/66643) The sub-license feature has been removed from the server and packager. So that we do not have to continue maintaining the code that supports this feature that never shipped, I am removing it from the CDM as well. Bug: 113165466 Test: CE CDM Unit Tests Test: Android Unit Tests Change-Id: I5d25844b161e74aa19adf19a29c56e4881aa7304
This commit is contained in:
@@ -44,7 +44,6 @@ LOCAL_SRC_FILES := \
|
||||
$(CORE_SRC_DIR)/policy_engine.cpp \
|
||||
$(CORE_SRC_DIR)/privacy_crypto_boringssl.cpp \
|
||||
$(CORE_SRC_DIR)/service_certificate.cpp \
|
||||
$(CORE_SRC_DIR)/sublicense_key_session.cpp \
|
||||
$(CORE_SRC_DIR)/usage_table_header.cpp \
|
||||
$(SRC_DIR)/wv_content_decryption_module.cpp \
|
||||
$(METRICS_SRC_DIR)/attribute_handler.cpp \
|
||||
|
||||
@@ -19,8 +19,6 @@ class CryptoKey {
|
||||
const std::string& key_data_iv() const { return key_data_iv_; }
|
||||
const std::string& key_control() const { return key_control_; }
|
||||
const std::string& key_control_iv() const { return key_control_iv_; }
|
||||
const std::string& sub_session_key_id() const {return sub_session_key_id_;}
|
||||
const std::string& sub_session_key() const {return sub_session_key_;}
|
||||
const std::string& entitlement_key_id() const {return entitlement_key_id_;}
|
||||
const std::string& track_label() const { return track_label_; }
|
||||
CdmCipherMode cipher_mode() const { return cipher_mode_; }
|
||||
@@ -34,12 +32,6 @@ class CryptoKey {
|
||||
void set_cipher_mode(CdmCipherMode cipher_mode) {
|
||||
cipher_mode_ = cipher_mode;
|
||||
}
|
||||
void set_sub_session_key_id(const std::string& sub_session_key_id) {
|
||||
sub_session_key_id_ = sub_session_key_id;
|
||||
}
|
||||
void set_sub_session_key(const std::string& sub_session_key) {
|
||||
sub_session_key_ = sub_session_key;
|
||||
}
|
||||
void set_track_label(const std::string& track_label) {
|
||||
track_label_ = track_label;
|
||||
}
|
||||
@@ -55,9 +47,7 @@ class CryptoKey {
|
||||
std::string key_data_;
|
||||
std::string key_control_;
|
||||
std::string key_control_iv_;
|
||||
std::string sub_session_key_id_;
|
||||
std::string track_label_;
|
||||
std::string sub_session_key_;
|
||||
std::string entitlement_key_id_;
|
||||
CdmCipherMode cipher_mode_;
|
||||
};
|
||||
|
||||
@@ -199,13 +199,6 @@ class CryptoSession {
|
||||
bool* can_support_cgms_a);
|
||||
virtual metrics::CryptoMetrics* GetCryptoMetrics() { return metrics_; }
|
||||
|
||||
virtual CdmResponseType AddSubSession(const std::string& sub_session_key_id,
|
||||
const std::string& group_master_key_id);
|
||||
// TODO(jfore): exists is set based on whether a sub session exists. For now,
|
||||
// that is not assumed to be an error.
|
||||
virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id,
|
||||
bool* exists, uint32_t* nonce);
|
||||
|
||||
virtual CdmResponseType GetProvisioningMethod(
|
||||
SecurityLevel requested_security_level,
|
||||
CdmClientTokenType* token_type);
|
||||
@@ -295,9 +288,6 @@ class CryptoSession {
|
||||
std::string oem_token_; // Cached OEMCrypto Public Key
|
||||
bool update_usage_table_after_close_session_;
|
||||
CryptoSessionId oec_session_id_;
|
||||
SubLicenseSessionMap sub_license_oec_sessions_;
|
||||
// Used for sub license sessions.
|
||||
std::string wrapped_key_;
|
||||
std::unique_ptr<KeySession> key_session_;
|
||||
|
||||
OEMCryptoBufferType destination_buffer_type_;
|
||||
|
||||
@@ -31,9 +31,6 @@ class InitializationData {
|
||||
const CdmInitData& data() const { return data_; }
|
||||
std::vector<uint8_t> hls_iv() const { return hls_iv_; }
|
||||
CdmHlsMethod hls_method() const { return hls_method_; }
|
||||
// TODO(jfore): Perhaps this should be a generic structure with the ids for
|
||||
// any type of licensing?
|
||||
std::vector<video_widevine::SubLicense> ExtractSublicenseKeys() const;
|
||||
std::vector<video_widevine::WidevinePsshData_EntitledKey> ExtractWrappedKeys()
|
||||
const;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class KeySession {
|
||||
KeySession(metrics::CryptoMetrics* metrics) : metrics_(metrics) {}
|
||||
|
||||
public:
|
||||
typedef enum { kDefault, kSubLicense, kEntitlement } KeySessionType;
|
||||
typedef enum { kDefault, kEntitlement } KeySessionType;
|
||||
virtual ~KeySession() {}
|
||||
virtual KeySessionType Type() = 0;
|
||||
virtual bool GenerateDerivedKeys(const std::string& message) = 0;
|
||||
@@ -43,8 +43,6 @@ class KeySession {
|
||||
metrics::CryptoMetrics* metrics_;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, CryptoSessionId> SubLicenseSessionMap;
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_KEY_SESSION_H_
|
||||
|
||||
@@ -108,7 +108,6 @@ class CdmLicense {
|
||||
|
||||
CdmResponseType HandleNewEntitledKeys(
|
||||
const std::vector<WidevinePsshData_EntitledKey>& wrapped_keys);
|
||||
CdmResponseType HandleSubLicense(const InitializationData& init_data);
|
||||
|
||||
template <typename T>
|
||||
bool SetTypeAndId(CdmLicenseType license_type, const std::string& request_id,
|
||||
@@ -147,11 +146,6 @@ class CdmLicense {
|
||||
// entitelement keys. It is also used in updating the key status info.
|
||||
std::vector<WidevinePsshData_EntitledKey> wrapped_keys_;
|
||||
|
||||
// For sublicense key embedding. This key array will be initialized with any
|
||||
// sub session keys we may have received in a license response. These keys
|
||||
// may be used to support key rotation.
|
||||
std::vector<CryptoKey> entitlement_key_array_;
|
||||
|
||||
CdmLicenseKeyType license_key_type_;
|
||||
RepeatedPtrField<License_KeyContainer> entitlement_keys_;
|
||||
#if defined(UNIT_TEST)
|
||||
|
||||
@@ -59,11 +59,6 @@ class PolicyEngine {
|
||||
// permits playback.
|
||||
virtual void SetLicense(const video_widevine::License& license);
|
||||
|
||||
// TODO(jfore): Sublicense uses this to update the keys when they are
|
||||
// changed during key rotation. Drop this method and use SetLicenseKeys
|
||||
// instead.
|
||||
virtual void UpdateLicenseKeys(const video_widevine::License& license);
|
||||
|
||||
// Used to update the currently loaded entitled content keys.
|
||||
virtual void SetEntitledLicenseKeys(
|
||||
const std::vector<WidevinePsshData_EntitledKey>& entitled_keys);
|
||||
|
||||
@@ -106,7 +106,6 @@ class Properties {
|
||||
FRIEND_TEST(CdmSessionTest, InitFailCryptoError);
|
||||
FRIEND_TEST(CdmSessionTest, InitNeedsProvisioning);
|
||||
FRIEND_TEST(CdmLicenseTest, PrepareKeyRequestValidation);
|
||||
FRIEND_TEST(SubLicenseTest, VerifySubSessionData);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#ifndef WVCDM_CORE_SUBLICENSE_KEY_SESSION_H_
|
||||
#define WVCDM_CORE_SUBLICENSE_KEY_SESSION_H_
|
||||
|
||||
#include "crypto_key.h"
|
||||
#include "key_session.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class SubLicenseKeySession : public KeySession {
|
||||
typedef enum {
|
||||
kInitializing,
|
||||
kInitialLicenseLoaded,
|
||||
kInitialLicenseFailed,
|
||||
} SubLicenseState;
|
||||
|
||||
public:
|
||||
SubLicenseKeySession(SubLicenseSessionMap& sub_license_oec_sessions,
|
||||
metrics::CryptoMetrics* metrics,
|
||||
const std::string& wrapped_private_device_key,
|
||||
SecurityLevel requested_security_level,
|
||||
const std::string& group_id);
|
||||
|
||||
virtual ~SubLicenseKeySession();
|
||||
|
||||
KeySessionType Type() { return kSubLicense; }
|
||||
|
||||
// This version of GenerateDerivedKeys is for devices using keyboxes. It is
|
||||
// not supported using sub licenses.
|
||||
bool GenerateDerivedKeys(const std::string&) { return false; }
|
||||
|
||||
// GenerateDerivedKeys is called for each open oemcrypto session and is only
|
||||
// called once.
|
||||
bool GenerateDerivedKeys(const std::string& message,
|
||||
const std::string& session_key);
|
||||
|
||||
// Load the keys in |keys|. The initial keys are saved for key rotation.
|
||||
OEMCryptoResult LoadKeys(const std::string& message,
|
||||
const std::string& signature,
|
||||
const std::string& mac_key_iv,
|
||||
const std::string& mac_key,
|
||||
const std::vector<CryptoKey>& keys,
|
||||
const std::string& provider_session_token,
|
||||
CdmCipherMode* cipher_mode,
|
||||
const std::string& srm_requirement);
|
||||
|
||||
OEMCryptoResult LoadEntitledContentKeys(const std::vector<CryptoKey>& /*keys*/) {
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
// Each oemcrypto session contains a single key. Find the right sub session
|
||||
// and save it's id as the selected oemcrypto session.
|
||||
OEMCryptoResult SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode);
|
||||
|
||||
// Decrypt performs the decryption using the selected oemcrypto session.
|
||||
// TODO(jfore): Support DecryptInChunks.
|
||||
OEMCryptoResult Decrypt(const CdmDecryptionParameters& params,
|
||||
OEMCrypto_DestBufferDesc& buffer_descriptor,
|
||||
OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor);
|
||||
|
||||
private:
|
||||
// Destroy each open oemcrypto session and relace them with new ones.
|
||||
OEMCryptoResult ResetCryptoSessions();
|
||||
|
||||
// DoLoadKeys loads a single key into each oemcrypto session.
|
||||
OEMCryptoResult DoLoadKeys(const std::string& message,
|
||||
const std::string& signature,
|
||||
const std::string& mac_key_iv,
|
||||
const std::string& mac_key,
|
||||
const std::vector<CryptoKey>& keys,
|
||||
const std::string& provider_session_token,
|
||||
CdmCipherMode* cipher_mode,
|
||||
const std::string& srm_requirement);
|
||||
|
||||
// DoLoadKeys loads a single key into each oemcrypto session.
|
||||
OEMCryptoResult DoSubLicenseLoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
const std::string& mac_key_iv, const std::string& mac_key,
|
||||
const CryptoKey& key, const std::string& provider_session_token,
|
||||
CdmCipherMode*, const std::string& srm_requirement);
|
||||
|
||||
SubLicenseState state_;
|
||||
std::string cached_sub_session_key_id_;
|
||||
std::string wrapped_private_device_key_;
|
||||
std::string message_;
|
||||
std::string session_key_;
|
||||
std::vector<CryptoKey> keys_;
|
||||
SubLicenseSessionMap& sub_license_oec_sessions_;
|
||||
SecurityLevel requested_security_level_;
|
||||
KeyId group_id_;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_SUBLICENSE_KEY_SESSION_H_
|
||||
@@ -318,7 +318,7 @@ enum CdmResponseType {
|
||||
USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE = 274,
|
||||
REMOVE_ALL_USAGE_INFO_ERROR_6 = 275,
|
||||
REMOVE_ALL_USAGE_INFO_ERROR_7 = 276,
|
||||
LICENSE_REQUEST_INVALID_SUBLICENSE = 277,
|
||||
/* previously LICENSE_REQUEST_INVALID_SUBLICENSE = 277, */
|
||||
CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE = 278,
|
||||
LOAD_SYSTEM_ID_ERROR = 279,
|
||||
INSUFFICIENT_CRYPTO_RESOURCES_4 = 280,
|
||||
|
||||
@@ -418,18 +418,6 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
|
||||
return KEY_REQUEST_ERROR_1;
|
||||
}
|
||||
|
||||
std::vector<video_widevine::SubLicense> embedded_key_data =
|
||||
init_data.ExtractSublicenseKeys();
|
||||
for (size_t i = 0; i < embedded_key_data.size(); ++i) {
|
||||
CdmResponseType sts = crypto_session_->AddSubSession(
|
||||
embedded_key_data[i].sub_session_key_id(),
|
||||
embedded_key_data[i].group_id());
|
||||
if (NO_ERROR != sts) {
|
||||
LOGE("CdmSession::GenerateKeyRequest: Unable to generate sub session");
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
app_parameters_ = app_parameters;
|
||||
CdmResponseType status = license_parser_->PrepareKeyRequest(
|
||||
init_data, license_type, app_parameters, &key_request->message,
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "properties.h"
|
||||
#include "pst_report.h"
|
||||
#include "string_conversions.h"
|
||||
#include "sublicense_key_session.h"
|
||||
#include "usage_table_header.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
@@ -772,7 +771,6 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
metrics_->oemcrypto_usage_table_support_.SetError(result);
|
||||
}
|
||||
|
||||
// TODO(gmorgan, jfore): resolve handling of usage records in sublicenses
|
||||
key_session_.reset(new ContentKeySession(oec_session_id_, metrics_));
|
||||
|
||||
return NO_ERROR;
|
||||
@@ -944,7 +942,6 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
|
||||
LOGE("LoadCertificatePrivateKey: OEMCrypto_LoadDeviceRSAKey error=%d", sts);
|
||||
return false;
|
||||
}
|
||||
wrapped_key_ = wrapped_key;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2316,73 +2313,6 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output,
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::AddSubSession(
|
||||
const std::string& sub_session_key_id,
|
||||
const std::string& group_master_key_id) {
|
||||
size_t exists = sub_license_oec_sessions_.count(sub_session_key_id);
|
||||
if (exists > 0) {
|
||||
// TODO(jfore): Should this be an error if the key exists? If so add a new
|
||||
// error. If not, perhaps this should just print info message.
|
||||
LOGE("AddSubSession: SubSession already exists for id: %s",
|
||||
sub_session_key_id.c_str());
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
CryptoSessionId sid;
|
||||
OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level_);
|
||||
if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) {
|
||||
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
|
||||
session_count_, (int)initialized_);
|
||||
return INSUFFICIENT_CRYPTO_RESOURCES;
|
||||
} else if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
|
||||
session_count_, (int)initialized_);
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
M_TIME(sts = OEMCrypto_LoadDeviceRSAKey(
|
||||
sid, reinterpret_cast<const uint8_t*>(wrapped_key_.data()),
|
||||
wrapped_key_.size()),
|
||||
metrics_, oemcrypto_load_device_rsa_key_, sts);
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("LoadDeviceRSAKey failed: %d", sts);
|
||||
return NEED_PROVISIONING;
|
||||
}
|
||||
|
||||
sub_license_oec_sessions_[sub_session_key_id] = sid;
|
||||
if (key_session_->Type() != KeySession::kSubLicense) {
|
||||
key_session_.reset(new SubLicenseKeySession(
|
||||
sub_license_oec_sessions_, metrics_, wrapped_key_,
|
||||
requested_security_level_, group_master_key_id));
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool CryptoSession::GenerateSubSessionNonce(
|
||||
const std::string& sub_session_key_id, bool* exists, uint32_t* nonce) {
|
||||
if (!exists || !nonce) {
|
||||
LOGE("input parameter is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("CryptoSession::GenerateSubSessionNonce: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
|
||||
SubLicenseSessionMap::iterator it =
|
||||
sub_license_oec_sessions_.find(sub_session_key_id);
|
||||
if (it == sub_license_oec_sessions_.end()) {
|
||||
// A subsession does not exist. Indicate that and return success.
|
||||
*exists = false;
|
||||
return false;
|
||||
}
|
||||
*exists = true;
|
||||
|
||||
OEMCryptoResult result;
|
||||
result = OEMCrypto_GenerateNonce(it->second, nonce);
|
||||
return OEMCrypto_SUCCESS == result;
|
||||
}
|
||||
|
||||
OEMCrypto_Algorithm CryptoSession::GenericSigningAlgorithm(
|
||||
CdmSigningAlgorithm algorithm) {
|
||||
if (kSigningAlgorithmHmacSha256 == algorithm) {
|
||||
|
||||
@@ -85,15 +85,6 @@ InitializationData::InitializationData(const std::string& type,
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the pssh data and return the embedded key data if it exists.
|
||||
std::vector<video_widevine::SubLicense>
|
||||
InitializationData::ExtractSublicenseKeys() const {
|
||||
std::vector<video_widevine::SubLicense> keys;
|
||||
// TODO(jfore): The pssh has changed in ways that are not compatible with
|
||||
//sublicenses. Restructure or remove sublicense support including this method.
|
||||
return keys;
|
||||
}
|
||||
|
||||
std::vector<video_widevine::WidevinePsshData_EntitledKey>
|
||||
InitializationData::ExtractWrappedKeys() const {
|
||||
std::vector<video_widevine::WidevinePsshData_EntitledKey> keys;
|
||||
|
||||
@@ -53,7 +53,6 @@ using video_widevine::SignedMessage;
|
||||
static std::vector<CryptoKey> ExtractEntitlementKeys(const License& license) {
|
||||
std::vector<CryptoKey> key_array;
|
||||
|
||||
// Extract sub session key(s)
|
||||
for (int i = 0; i < license.key_size(); ++i) {
|
||||
CryptoKey key;
|
||||
size_t length = 0;
|
||||
@@ -326,29 +325,6 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||
license_request.set_key_control_nonce(nonce);
|
||||
LOGD("PrepareKeyRequest: nonce=%u", nonce);
|
||||
|
||||
// Prepare the request for any embedded keys that may exist in the
|
||||
// initialization data.
|
||||
std::vector<video_widevine::SubLicense> embedded_key_data =
|
||||
init_data.ExtractSublicenseKeys();
|
||||
for (size_t i = 0; i < embedded_key_data.size(); ++i) {
|
||||
bool exists = false;
|
||||
if (!crypto_session_->GenerateSubSessionNonce(
|
||||
embedded_key_data[i].sub_session_key_id(), &exists, &nonce)) {
|
||||
if (exists) {
|
||||
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
|
||||
}
|
||||
}
|
||||
SignedMessage signed_sub_license;
|
||||
License_KeyContainer keyc;
|
||||
|
||||
// Parse the sub license for this track to extract the label.
|
||||
if (!signed_sub_license.ParseFromString(embedded_key_data[i].key_msg()) ||
|
||||
!keyc.ParseFromString(signed_sub_license.msg()) ||
|
||||
keyc.track_label().empty()) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
}
|
||||
|
||||
license_request.set_protocol_version(video_widevine::VERSION_2_1);
|
||||
|
||||
// License request is complete. Serialize it.
|
||||
@@ -626,7 +602,6 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
|
||||
CdmResponseType resp = NO_CONTENT_KEY;
|
||||
if (kLicenseKeyTypeEntitlement == key_type) {
|
||||
entitlement_key_array_ = key_array;
|
||||
resp = HandleEntitlementKeyResponse(signed_response.msg(),
|
||||
signed_response.signature(), mac_key_iv,
|
||||
mac_keys, key_array, license);
|
||||
@@ -722,9 +697,7 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
|
||||
|
||||
CdmResponseType CdmLicense::HandleEmbeddedKeyData(
|
||||
const InitializationData& init_data) {
|
||||
return (license_key_type_ == kLicenseKeyTypeEntitlement
|
||||
? HandleNewEntitledKeys(init_data.ExtractWrappedKeys())
|
||||
: HandleSubLicense(init_data));
|
||||
return HandleNewEntitledKeys(init_data.ExtractWrappedKeys());
|
||||
}
|
||||
|
||||
bool CdmLicense::RestoreOfflineLicense(
|
||||
@@ -1127,57 +1100,6 @@ CdmResponseType CdmLicense::HandleNewEntitledKeys(
|
||||
return resp;
|
||||
}
|
||||
|
||||
CdmResponseType CdmLicense::HandleSubLicense(
|
||||
const InitializationData& init_data) {
|
||||
std::vector<video_widevine::SubLicense> subkeys =
|
||||
init_data.ExtractSublicenseKeys();
|
||||
std::set<KeyId> loaded_keys;
|
||||
// Build a license with the rotated keys.
|
||||
License license;
|
||||
for (size_t i = 0; i < subkeys.size(); ++i) {
|
||||
SignedMessage sm;
|
||||
if (!sm.ParseFromString(subkeys[i].key_msg())) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
License_KeyContainer keyc;
|
||||
if (!keyc.ParseFromString(sm.msg())) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
size_t length;
|
||||
std::vector<CryptoKey> keys;
|
||||
keys.resize(1);
|
||||
keys[0].set_key_id(keyc.id());
|
||||
|
||||
// Strip PKCS#5 padding from sublicense content keys.
|
||||
// TODO(jfore): Refactor this to use ExtractContentKeys.
|
||||
if (keyc.key().size() > CONTENT_KEY_SIZE) {
|
||||
length = keyc.key().size() - CONTENT_KEY_SIZE;
|
||||
} else {
|
||||
length = 0;
|
||||
}
|
||||
keys[0].set_key_data(keyc.key().substr(0, length));
|
||||
keys[0].set_key_data_iv(keyc.iv());
|
||||
keys[0].set_key_control(keyc.key_control().key_control_block());
|
||||
keys[0].set_key_control_iv(keyc.key_control().iv());
|
||||
keys[0].set_track_label(keyc.track_label());
|
||||
// TODO: passing empty cipher_mode and srm_req params - OK?
|
||||
CdmResponseType result = crypto_session_->LoadKeys(
|
||||
sm.msg(), sm.signature(), std::string(), std::string(), keys,
|
||||
std::string(), std::string(), kLicenseKeyTypeContent);
|
||||
if (result != KEY_ADDED) {
|
||||
LOGE("CdmLicense::HandleSubLicense: LoadKeys() call failed, result=%d",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
loaded_keys.insert(keyc.id());
|
||||
*license.add_key() = keyc;
|
||||
}
|
||||
loaded_keys_.swap(loaded_keys);
|
||||
policy_engine_->UpdateLicenseKeys(license);
|
||||
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool CdmLicense::SetTypeAndId(CdmLicenseType license_type,
|
||||
const std::string& request_id, T* content_id) {
|
||||
|
||||
@@ -170,14 +170,6 @@ void PolicyEngine::SetLicense(const License& license) {
|
||||
UpdateLicense(license);
|
||||
}
|
||||
|
||||
void PolicyEngine::UpdateLicenseKeys(const video_widevine::License& license) {
|
||||
// Use the current policy and set the new keys.
|
||||
video_widevine::License loadable = license;
|
||||
loadable.mutable_policy()->CopyFrom(policy_);
|
||||
license_keys_->SetFromLicense(loadable);
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
}
|
||||
|
||||
void PolicyEngine::SetEntitledLicenseKeys(
|
||||
const std::vector<WidevinePsshData_EntitledKey>& entitled_keys) {
|
||||
license_keys_->SetEntitledKeys(entitled_keys);
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
#include "sublicense_key_session.h"
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "log.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
SubLicenseKeySession::SubLicenseKeySession(
|
||||
SubLicenseSessionMap& sub_license_oec_sessions,
|
||||
metrics::CryptoMetrics* metrics,
|
||||
const std::string& wrapped_private_device_key,
|
||||
SecurityLevel requested_security_level,
|
||||
const std::string& group_id)
|
||||
: KeySession(metrics),
|
||||
state_(kInitializing),
|
||||
wrapped_private_device_key_(wrapped_private_device_key),
|
||||
sub_license_oec_sessions_(sub_license_oec_sessions),
|
||||
requested_security_level_(requested_security_level),
|
||||
group_id_(group_id) {}
|
||||
|
||||
SubLicenseKeySession::~SubLicenseKeySession() {
|
||||
for (SubLicenseSessionMap::iterator oec_session =
|
||||
sub_license_oec_sessions_.begin();
|
||||
oec_session != sub_license_oec_sessions_.end(); oec_session++) {
|
||||
metrics_->oemcrypto_close_session_.Increment(
|
||||
OEMCrypto_CloseSession(oec_session->second));
|
||||
}
|
||||
sub_license_oec_sessions_.clear();
|
||||
}
|
||||
|
||||
// GenerateDerivedKeys is called for each open oemcrypto session and is only
|
||||
// called once.
|
||||
bool SubLicenseKeySession::GenerateDerivedKeys(const std::string& message,
|
||||
const std::string& session_key) {
|
||||
std::string mac_deriv_message;
|
||||
std::string enc_deriv_message;
|
||||
GenerateMacContext(message, &mac_deriv_message);
|
||||
GenerateEncryptContext(message, &enc_deriv_message);
|
||||
|
||||
for (SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.begin();
|
||||
it != sub_license_oec_sessions_.end(); it++) {
|
||||
LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)it->second);
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(sts = OEMCrypto_DeriveKeysFromSessionKey(
|
||||
it->second, reinterpret_cast<const uint8_t*>(session_key.data()),
|
||||
session_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(mac_deriv_message.data()),
|
||||
mac_deriv_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(enc_deriv_message.data()),
|
||||
enc_deriv_message.size()),
|
||||
metrics_, oemcrypto_derive_keys_from_session_key_, sts);
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d",
|
||||
sts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::LoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
const std::string& mac_key_iv, const std::string& mac_key,
|
||||
const std::vector<CryptoKey>& keys,
|
||||
const std::string& provider_session_token, CdmCipherMode* cipher_mode,
|
||||
const std::string& srm_requirement) {
|
||||
if (state_ == kInitializing) {
|
||||
state_ = kInitialLicenseLoaded;
|
||||
keys_ = keys;
|
||||
OEMCryptoResult sts =
|
||||
DoLoadKeys(message, signature, mac_key_iv, mac_key, keys,
|
||||
provider_session_token, cipher_mode, srm_requirement);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
state_ = kInitialLicenseFailed;
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
return DoSubLicenseLoadKeys(message, signature, mac_key_iv, mac_key, keys[0],
|
||||
provider_session_token, cipher_mode,
|
||||
srm_requirement);
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode) {
|
||||
for (size_t i = 0; i < keys_.size(); ++i) {
|
||||
if (keys_[i].key_id() == key_id) {
|
||||
cached_sub_session_key_id_ = keys_[i].sub_session_key_id();
|
||||
if (keys_[i].cipher_mode() != cipher_mode) {
|
||||
SubLicenseSessionMap::iterator it =
|
||||
sub_license_oec_sessions_.find(cached_sub_session_key_id_);
|
||||
if (it == sub_license_oec_sessions_.end()) {
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
|
||||
OEMCryptoResult status = OEMCrypto_SUCCESS;
|
||||
M_TIME(status = OEMCrypto_SelectKey(
|
||||
it->second,
|
||||
reinterpret_cast<const uint8_t*>(keys_[i].key_id().data()),
|
||||
keys_[i].key_id().size(),
|
||||
ToOEMCryptoCipherMode(cipher_mode)),
|
||||
metrics_, oemcrypto_select_key_, status);
|
||||
if (OEMCrypto_SUCCESS != status) {
|
||||
return status;
|
||||
}
|
||||
keys_[i].set_cipher_mode(cipher_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::Decrypt(
|
||||
const CdmDecryptionParameters& params,
|
||||
OEMCrypto_DestBufferDesc& buffer_descriptor,
|
||||
OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor) {
|
||||
SubLicenseSessionMap::iterator it =
|
||||
sub_license_oec_sessions_.find(cached_sub_session_key_id_);
|
||||
if (it == sub_license_oec_sessions_.end()) {
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(sts = OEMCrypto_DecryptCENC(
|
||||
it->second, params.encrypt_buffer, params.encrypt_length,
|
||||
params.is_encrypted, &(*params.iv).front(), params.block_offset,
|
||||
&buffer_descriptor, &pattern_descriptor, params.subsample_flags),
|
||||
metrics_, oemcrypto_decrypt_cenc_, sts,
|
||||
metrics::Pow2Bucket(params.encrypt_length));
|
||||
return sts;
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::ResetCryptoSessions() {
|
||||
for (SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.begin();
|
||||
it != sub_license_oec_sessions_.end(); it++) {
|
||||
OEMCryptoResult sts = OEMCrypto_CloseSession(it->second);
|
||||
metrics_->oemcrypto_close_session_.Increment(sts);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return sts;
|
||||
}
|
||||
sts = OEMCrypto_OpenSession(&it->second, requested_security_level_);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return sts;
|
||||
}
|
||||
M_TIME(sts = OEMCrypto_LoadDeviceRSAKey(
|
||||
it->second,
|
||||
reinterpret_cast<const uint8_t*>(
|
||||
wrapped_private_device_key_.data()),
|
||||
wrapped_private_device_key_.size()),
|
||||
metrics_, oemcrypto_load_device_rsa_key_, sts);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
const std::string& mac_key_iv, const std::string& mac_key,
|
||||
const std::vector<CryptoKey>& keys,
|
||||
const std::string& provider_session_token, CdmCipherMode* cipher_mode,
|
||||
const std::string& srm_requirement) {
|
||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||
bool valid_mac_keys =
|
||||
mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE;
|
||||
OEMCrypto_Substring enc_mac_key =
|
||||
GetSubstring(message, mac_key, !valid_mac_keys);
|
||||
OEMCrypto_Substring enc_mac_key_iv =
|
||||
GetSubstring(message, mac_key_iv, !valid_mac_keys);
|
||||
if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
||||
|
||||
OEMCrypto_Substring pst = GetSubstring(message, provider_session_token);
|
||||
OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement);
|
||||
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
OEMCrypto_KeyObject key_object;
|
||||
const CryptoKey& key_data = keys[i];
|
||||
key_object.key_id = GetSubstring(message, key_data.key_id());
|
||||
key_object.key_data_iv = GetSubstring(message, key_data.key_data_iv());
|
||||
key_object.key_data = GetSubstring(message, key_data.key_data());
|
||||
bool has_key_control = key_data.HasKeyControl();
|
||||
key_object.key_control_iv =
|
||||
GetSubstring(message, key_data.key_control_iv(), !has_key_control);
|
||||
key_object.key_control =
|
||||
GetSubstring(message, key_data.key_control(), !has_key_control);
|
||||
if (!has_key_control) {
|
||||
LOGE("For key %s: XXX key has no control block. size=%d",
|
||||
key_data.key_id().c_str(), key_data.key_control().size());
|
||||
}
|
||||
OEMCryptoCipherMode oem_cipher_mode =
|
||||
ToOEMCryptoCipherMode(key_data.cipher_mode());
|
||||
|
||||
// TODO(jfore): Does returning the cipher mode serve any purpose?
|
||||
// If not drop.
|
||||
*cipher_mode = key_data.cipher_mode();
|
||||
|
||||
SubLicenseSessionMap::iterator oec_session_id =
|
||||
sub_license_oec_sessions_.find(key_data.sub_session_key_id());
|
||||
if (oec_session_id == sub_license_oec_sessions_.end()) {
|
||||
LOGE("CryptoSession::LoadKeys: Unrecognized sub session %s",
|
||||
key_data.sub_session_key_id().c_str());
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat(
|
||||
oec_session_id->second, msg, message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object,
|
||||
pst, srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode),
|
||||
metrics_, oemcrypto_load_keys_, sts);
|
||||
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
M_TIME(sts = OEMCrypto_SelectKey(
|
||||
oec_session_id->second,
|
||||
reinterpret_cast<const uint8_t*>(key_data.key_id().data()),
|
||||
key_data.key_id().size(),
|
||||
ToOEMCryptoCipherMode(key_data.cipher_mode())),
|
||||
metrics_, oemcrypto_select_key_, sts);
|
||||
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
keys_ = keys;
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
const std::string& mac_key_iv, const std::string& mac_key,
|
||||
const CryptoKey& key, const std::string& provider_session_token,
|
||||
CdmCipherMode*, const std::string& srm_requirement) {
|
||||
SubLicenseSessionMap::iterator it = sub_license_oec_sessions_.end();
|
||||
size_t key_index = 0;
|
||||
for (; key_index < keys_.size(); key_index++) {
|
||||
if (keys_[key_index].track_label() == key.track_label()) {
|
||||
it =
|
||||
sub_license_oec_sessions_.find(keys_[key_index].sub_session_key_id());
|
||||
CryptoKey tmp = key;
|
||||
tmp.set_sub_session_key_id(keys_[key_index].sub_session_key_id());
|
||||
tmp.set_sub_session_key(keys_[key_index].sub_session_key());
|
||||
keys_[key_index] = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it == sub_license_oec_sessions_.end()) {
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
LOGV("GenerateDerivedKeys: id=%ld", (uint32_t)it->second);
|
||||
|
||||
std::string mac_deriv_message;
|
||||
std::string enc_deriv_message;
|
||||
GenerateMacContext(group_id_ + message.c_str(), &mac_deriv_message);
|
||||
GenerateEncryptContext(group_id_ + message.c_str(), &enc_deriv_message);
|
||||
|
||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||
bool valid_mac_keys =
|
||||
mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE;
|
||||
OEMCrypto_Substring enc_mac_key =
|
||||
GetSubstring(message, mac_key, !valid_mac_keys);
|
||||
OEMCrypto_Substring enc_mac_key_iv =
|
||||
GetSubstring(message, mac_key_iv, !valid_mac_keys);
|
||||
if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
||||
|
||||
OEMCrypto_Substring pst = GetSubstring(message, provider_session_token);
|
||||
OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement);
|
||||
|
||||
OEMCryptoResult sts;
|
||||
const std::string& sub_session_key = keys_[key_index].sub_session_key();
|
||||
LOGV("ssksize = %d", sub_session_key.size());
|
||||
|
||||
M_TIME(
|
||||
sts = OEMCrypto_DeriveKeysFromSessionKey(
|
||||
it->second, reinterpret_cast<const uint8_t*>(sub_session_key.data()),
|
||||
sub_session_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(mac_deriv_message.data()),
|
||||
mac_deriv_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(enc_deriv_message.data()),
|
||||
enc_deriv_message.size()),
|
||||
metrics_, oemcrypto_derive_keys_from_session_key_, sts);
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
OEMCrypto_KeyObject key_object;
|
||||
key_object.key_id = GetSubstring(message, keys_[key_index].key_id());
|
||||
key_object.key_data_iv =
|
||||
GetSubstring(message, keys_[key_index].key_data_iv());
|
||||
key_object.key_data = GetSubstring(message, keys_[key_index].key_data());
|
||||
bool has_key_control = key.HasKeyControl();
|
||||
key_object.key_control_iv = GetSubstring(
|
||||
message, keys_[key_index].key_control_iv(), !has_key_control);
|
||||
key_object.key_control =
|
||||
GetSubstring(message, keys_[key_index].key_control(), !has_key_control);
|
||||
OEMCryptoCipherMode oem_cipher_mode =
|
||||
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode());
|
||||
|
||||
M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat(
|
||||
it->second, msg, message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
|
||||
srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode),
|
||||
metrics_, oemcrypto_load_keys_, sts);
|
||||
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
return sts;
|
||||
}
|
||||
|
||||
M_TIME(sts = OEMCrypto_SelectKey(
|
||||
it->second,
|
||||
reinterpret_cast<const uint8_t*>(keys_[key_index].key_id().data()),
|
||||
keys_[key_index].key_id().size(),
|
||||
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode())),
|
||||
metrics_, oemcrypto_select_key_, sts);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
@@ -170,19 +170,6 @@ const std::string kZeroSizedPsshBox = a2bs_hex(
|
||||
// data:
|
||||
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
|
||||
|
||||
const std::string kSubLicensePsshBox = a2bs_hex(
|
||||
// Widevine PSSH box
|
||||
"0000009f" // atom size
|
||||
"70737368" // atom type="pssh"
|
||||
"00000000" // v0, flags=0
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
|
||||
"0000007f" // data size
|
||||
// data:
|
||||
"0801120d746573745f6b65795f69645f30120d746573745f6b65795f69645f31220f"
|
||||
"746573745f636f6e74656e745f69645a250a147375625f73657373696f6e5f6b6579"
|
||||
"5f69645f30120d7375625f6c6963656e73655f305a250a147375625f73657373696f"
|
||||
"6e5f6b65795f69645f31120d7375625f6c6963656e73655f31");
|
||||
|
||||
const std::string kMultipleWidevinePsshBox = a2bs_hex(
|
||||
// first PSSH box, Widevine with single keys
|
||||
"00000042" // atom size
|
||||
@@ -515,7 +502,7 @@ class HlsTest : public ::testing::Test {};
|
||||
} // namespace
|
||||
|
||||
TEST_F(InitializationDataTest, BadType) {
|
||||
InitializationData init_data("bad", kSubLicensePsshBox);
|
||||
InitializationData init_data("bad", kWidevinePssh);
|
||||
EXPECT_TRUE(init_data.IsEmpty());
|
||||
}
|
||||
|
||||
@@ -529,8 +516,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(kWidevinePssh, kWidevinePsshFirst,
|
||||
kWidevinePsshAfterV0Pssh, kWidevinePsshAfterNonZeroFlags,
|
||||
kWidevinePsshAfterV1Pssh, kWidevineV1Pssh, kOtherBoxFirst,
|
||||
kZeroSizedPsshBox, kSubLicensePsshBox,
|
||||
kMultipleWidevinePsshBox));
|
||||
kZeroSizedPsshBox, kMultipleWidevinePsshBox));
|
||||
|
||||
TEST_F(InitializationDataTest, HandlesMultipleWidevinePsshs) {
|
||||
InitializationData single_init_data(ISO_BMFF_VIDEO_MIME_TYPE,
|
||||
@@ -546,28 +532,6 @@ TEST_F(InitializationDataTest, HandlesMultipleWidevinePsshs) {
|
||||
EXPECT_EQ(kEntitledKeysWidevinePsshBoxData, entitled_init_data.data());
|
||||
}
|
||||
|
||||
// TODO(jfore): The pssh has changed in ways that are not compatible with
|
||||
//sublicenses. Restructure or remove sublicense support including this test.
|
||||
TEST_F(InitializationDataTest, DISABLED_ExtractSubLicense) {
|
||||
InitializationData init_data(ISO_BMFF_VIDEO_MIME_TYPE, kSubLicensePsshBox);
|
||||
ASSERT_FALSE(init_data.IsEmpty());
|
||||
std::vector<video_widevine::SubLicense> keys =
|
||||
init_data.ExtractSublicenseKeys();
|
||||
ASSERT_EQ(keys.size(), 2UL);
|
||||
EXPECT_EQ(keys[0].sub_session_key_id(), "sub_session_key_id_0");
|
||||
EXPECT_EQ(keys[1].sub_session_key_id(), "sub_session_key_id_1");
|
||||
EXPECT_EQ(keys[0].key_msg(), "sub_license_0");
|
||||
EXPECT_EQ(keys[1].key_msg(), "sub_license_1");
|
||||
}
|
||||
|
||||
TEST_F(InitializationDataTest, ExtractEmptySubLicense) {
|
||||
InitializationData init_data(ISO_BMFF_VIDEO_MIME_TYPE, kWidevinePssh);
|
||||
ASSERT_FALSE(init_data.IsEmpty());
|
||||
std::vector<video_widevine::SubLicense> keys =
|
||||
init_data.ExtractSublicenseKeys();
|
||||
ASSERT_TRUE(keys.empty());
|
||||
}
|
||||
|
||||
TEST_P(HlsKeyFormatVersionsExtractionTest, ExtractKeyFormatVersions) {
|
||||
std::vector<std::string> versions = GetParam();
|
||||
std::string key_format_versions;
|
||||
|
||||
@@ -113,32 +113,6 @@ const std::string kLicenseRequestSignature = a2bs_hex(
|
||||
"9AE18B91516E0CDD0B581590DDDEA2A2527E2C9ABA273629B586A9D22D451A827E332CFC3E"
|
||||
"9BEDB6CF3D8713F9E11675DF1F5DB9038DBBECAB9D1683F8722CAF6E18EC8C04AEE5");
|
||||
|
||||
const std::string kSubLicensePssh = a2bs_hex(
|
||||
"000002317073736800000000edef8ba979d64acea3c827dcd51d21ed000002010801120d54"
|
||||
"6573744b6579415544494f30120a546573744b6579534430120a546573744b65794844301a"
|
||||
"0048e3dc959b0650025a9b010a101f10e4700b1a5b731c545fe2405cea1b12860112620a0d"
|
||||
"546573744b6579415544494f3012102f4b661d1064b5ea82efcd3ef850f45b1a10a02c5cea"
|
||||
"5182383c064c06abbc79bfa8200242240a1023acc9a0ef2bca66af2a1307cc9edeb21210e1"
|
||||
"f1d352b4c6b1aad1fd78423db256946205415544494f1a20aaf4537f09332c502a88f43a18"
|
||||
"a3e21ec28bbde675c5d87054fbca06f98e98015a95010a10c034cf6ae181b8d07f2e79142d"
|
||||
"792bb3128001125c0a0a546573744b657953443012106d37a0a201afdef8a494f89a4b0772"
|
||||
"4a1a10457db86b73bf87177a5cc61c0d04b690200242240a1001fe432d2a8afb7054ae76a3"
|
||||
"9c2727e612108761b7e0ba354ee4132117a9de12abd3620253441a20e3f37529cb795b35a0"
|
||||
"d186e4ce7187f08dda5f1df136ddb92eb0a65a899635005a95010a1021cdec9b2105c6b643"
|
||||
"e71f68e5302c85128001125c0a0a546573744b6579484430121012a3e3afe1e23be2c3fc55"
|
||||
"fddad877451a108f31ff0865f4d4fb41d96414297f7728200242240a1061e3cbca755b36c8"
|
||||
"e7d6dda03af20e4f1210a2fa2fc5d10c9c84ddc5511446ce77e9620248441a20a945699aef"
|
||||
"49355b0214b636edb7670bbe350c58b69cd52f207953b380a52df2");
|
||||
|
||||
const std::string kSubSessionKeyID1 =
|
||||
a2bs_hex("1f10e4700b1a5b731c545fe2405cea1b");
|
||||
|
||||
const std::string kSubSessionKeyID2 =
|
||||
a2bs_hex("c034cf6ae181b8d07f2e79142d792bb3");
|
||||
|
||||
const std::string kSubSessionKeyID3 =
|
||||
a2bs_hex("21cdec9b2105c6b643e71f68e5302c85");
|
||||
|
||||
const CryptoSession::SupportedCertificateTypes kDefaultSupportedCertTypes = {
|
||||
true,
|
||||
true,
|
||||
@@ -171,9 +145,6 @@ class MockCryptoSession : public TestCryptoSession {
|
||||
MOCK_METHOD1(GetApiVersion, bool(uint32_t*));
|
||||
MOCK_METHOD1(GenerateNonce, bool(uint32_t*));
|
||||
MOCK_METHOD3(PrepareRequest, bool(const std::string&, bool, std::string*));
|
||||
MOCK_METHOD3(GenerateSubSessionNonce,
|
||||
bool(const std::string& sub_session_key_id, bool* exists,
|
||||
uint32_t* nonce));
|
||||
MOCK_METHOD1(LoadEntitledContentKeys,
|
||||
CdmResponseType(const std::vector<CryptoKey>& key_array));
|
||||
};
|
||||
@@ -270,11 +241,6 @@ class CdmLicenseTest : public WvCdmTestBase {
|
||||
std::string pssh_;
|
||||
};
|
||||
|
||||
class SubLicenseTest : public CdmLicenseTest {
|
||||
protected:
|
||||
SubLicenseTest() : CdmLicenseTest(kSubLicensePssh) {}
|
||||
};
|
||||
|
||||
TEST_F(CdmLicenseTest, InitSuccess) {
|
||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||
|
||||
|
||||
@@ -566,9 +566,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
case USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE:
|
||||
*os << "USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE";
|
||||
break;
|
||||
case LICENSE_REQUEST_INVALID_SUBLICENSE:
|
||||
*os << "LICENSE_REQUEST_INVALID_SUBLICENSE";
|
||||
break;
|
||||
case CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE:
|
||||
*os << "CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE";
|
||||
break;
|
||||
|
||||
@@ -257,7 +257,6 @@ enum {
|
||||
kUsageStoreEntryRetrieveInvalidStorageType = ERROR_DRM_VENDOR_MIN + 266,
|
||||
kRemoveAllUsageInfoError6 = ERROR_DRM_VENDOR_MIN + 267,
|
||||
kRemoveAllUsageInfoError7 = ERROR_DRM_VENDOR_MIN + 268,
|
||||
kLicenseRequestInvalidSublicense = ERROR_DRM_VENDOR_MIN + 269,
|
||||
kCertProvisioningEmptyServiceCertificate = ERROR_DRM_VENDOR_MIN + 270,
|
||||
kLoadSystemIdError = ERROR_DRM_VENDOR_MIN + 271,
|
||||
kInsufficientCryptoResources4 = ERROR_DRM_VENDOR_MIN + 272,
|
||||
|
||||
@@ -500,8 +500,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
|
||||
return kRemoveAllUsageInfoError6;
|
||||
case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_7:
|
||||
return kRemoveAllUsageInfoError7;
|
||||
case wvcdm::LICENSE_REQUEST_INVALID_SUBLICENSE:
|
||||
return kLicenseRequestInvalidSublicense;
|
||||
case wvcdm::CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE:
|
||||
return kCertProvisioningEmptyServiceCertificate;
|
||||
case wvcdm::LOAD_SYSTEM_ID_ERROR:
|
||||
|
||||
@@ -195,7 +195,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
|
||||
case wvcdm::WEBM_INIT_DATA_UNAVAILABLE:
|
||||
case wvcdm::PREPARE_WEBM_CONTENT_ID_FAILED:
|
||||
case wvcdm::UNSUPPORTED_INIT_DATA_FORMAT:
|
||||
case wvcdm::LICENSE_REQUEST_INVALID_SUBLICENSE:
|
||||
case wvcdm::LICENSE_REQUEST_NONCE_GENERATION_ERROR:
|
||||
case wvcdm::LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR:
|
||||
case wvcdm::LICENSE_REQUEST_SIGNING_ERROR:
|
||||
|
||||
Reference in New Issue
Block a user