Run clang-format on Core

This copies over formatting changes from the Widevine CDM repository
that resulted from running clang-format with Google style on the
shared core/ directory. It also copies over some rewordings of log
messages that were made at the same time.

Aside from the changed log messages, this should not affect behavior
or functionality.

Change-Id: I69c57c188f7a79f30fa3517afeed17365929b6b6
This commit is contained in:
John "Juce" Bruce
2015-03-05 14:14:22 -08:00
parent dff91b48c1
commit a3b0d83d19
39 changed files with 652 additions and 803 deletions

View File

@@ -24,13 +24,13 @@ namespace wvcdm {
class BufferReader { class BufferReader {
public: public:
BufferReader(const uint8_t* buf, size_t size) BufferReader(const uint8_t* buf, size_t size)
: buf_(buf), size_(size), pos_(0) {} : buf_(buf), size_(size), pos_(0) {}
bool HasBytes(int count) { return (pos() + count <= size()); } bool HasBytes(int count) { return (pos() + count <= size()); }
// Read a value from the stream, performing endian correction, // Read a value from the stream, performing endian correction,
// and advance the stream pointer. // and advance the stream pointer.
bool Read1(uint8_t* v) WARN_UNUSED_RESULT; bool Read1(uint8_t* v) WARN_UNUSED_RESULT;
bool Read2(uint16_t* v) WARN_UNUSED_RESULT; bool Read2(uint16_t* v) WARN_UNUSED_RESULT;
bool Read2s(int16_t* v) WARN_UNUSED_RESULT; bool Read2s(int16_t* v) WARN_UNUSED_RESULT;
bool Read4(uint32_t* v) WARN_UNUSED_RESULT; bool Read4(uint32_t* v) WARN_UNUSED_RESULT;
@@ -58,7 +58,8 @@ class BufferReader {
size_t size_; size_t size_;
size_t pos_; size_t pos_;
template<typename T> bool Read(T* t) WARN_UNUSED_RESULT; template <typename T>
bool Read(T* t) WARN_UNUSED_RESULT;
CORE_DISALLOW_COPY_AND_ASSIGN(BufferReader); CORE_DISALLOW_COPY_AND_ASSIGN(BufferReader);
}; };

View File

@@ -36,8 +36,7 @@ class CdmEngine {
virtual CdmResponseType CloseSession(const CdmSessionId& session_id); virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
virtual CdmResponseType OpenKeySetSession( virtual CdmResponseType OpenKeySetSession(
const CdmKeySetId& key_set_id, const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set);
const CdmClientPropertySet* property_set);
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id); virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
// License related methods // License related methods

View File

@@ -118,7 +118,6 @@ class CdmSession {
CdmResponseType StoreLicense(); CdmResponseType StoreLicense();
bool StoreLicense(DeviceFiles::LicenseState state); bool StoreLicense(DeviceFiles::LicenseState state);
// instance variables // instance variables
bool initialized_; bool initialized_;
CdmSessionId session_id_; CdmSessionId session_id_;

View File

@@ -31,8 +31,7 @@ class CertificateProvisioning {
CdmProvisioningRequest* request); CdmProvisioningRequest* request);
bool ParseJsonResponse(const CdmProvisioningResponse& json_str, bool ParseJsonResponse(const CdmProvisioningResponse& json_str,
const std::string& start_substr, const std::string& start_substr,
const std::string& end_substr, const std::string& end_substr, std::string* result);
std::string* result);
CryptoSession crypto_session_; CryptoSession crypto_session_;
CdmCertificateType cert_type_; CdmCertificateType cert_type_;

View File

@@ -11,7 +11,6 @@ namespace wvcdm {
// Provides time related information. The implementation is platform dependent. // Provides time related information. The implementation is platform dependent.
class Clock { class Clock {
public: public:
Clock() {} Clock() {}
virtual ~Clock() {} virtual ~Clock() {}

View File

@@ -8,7 +8,7 @@
namespace wvcdm { namespace wvcdm {
class CryptoKey { class CryptoKey {
public: public:
CryptoKey() {}; CryptoKey() {};
~CryptoKey() {}; ~CryptoKey() {};
@@ -27,7 +27,7 @@ public:
bool HasKeyControl() const { return key_control_.size() >= 16; } bool HasKeyControl() const { return key_control_.size() >= 16; }
private: private:
std::string key_id_; std::string key_id_;
std::string key_data_iv_; std::string key_data_iv_;
std::string key_data_; std::string key_data_;
@@ -35,6 +35,6 @@ private:
std::string key_control_iv_; std::string key_control_iv_;
}; };
}; // namespace wvcdm }; // namespace wvcdm
#endif // WVCDM_CORE_CRYPTO_KEY_H_ #endif // WVCDM_CORE_CRYPTO_KEY_H_

View File

@@ -27,7 +27,7 @@ class DeviceFiles {
virtual bool Init(CdmSecurityLevel security_level); virtual bool Init(CdmSecurityLevel security_level);
virtual bool Reset(CdmSecurityLevel security_level) { virtual bool Reset(CdmSecurityLevel security_level) {
return Init(security_level); return Init(security_level);
} }
virtual bool StoreCertificate(const std::string& certificate, virtual bool StoreCertificate(const std::string& certificate,
@@ -45,16 +45,12 @@ class DeviceFiles {
const std::string& release_server_url, const std::string& release_server_url,
int64_t playback_start_time, int64_t playback_start_time,
int64_t last_playback_time); int64_t last_playback_time);
virtual bool RetrieveLicense(const std::string& key_set_id, virtual bool RetrieveLicense(
LicenseState* state, const std::string& key_set_id, LicenseState* state,
CdmInitData* pssh_data, CdmInitData* pssh_data, CdmKeyMessage* key_request,
CdmKeyMessage* key_request, CdmKeyResponse* key_response, CdmKeyMessage* key_renewal_request,
CdmKeyResponse* key_response, CdmKeyResponse* key_renewal_response, std::string* release_server_url,
CdmKeyMessage* key_renewal_request, int64_t* playback_start_time, int64_t* last_playback_time);
CdmKeyResponse* key_renewal_response,
std::string* release_server_url,
int64_t* playback_start_time,
int64_t* last_playback_time);
virtual bool DeleteLicense(const std::string& key_set_id); virtual bool DeleteLicense(const std::string& key_set_id);
virtual bool DeleteAllFiles(); virtual bool DeleteAllFiles();
virtual bool DeleteAllLicenses(); virtual bool DeleteAllLicenses();

View File

@@ -44,7 +44,7 @@ class File {
virtual ssize_t FileSize(const std::string& file_path); virtual ssize_t FileSize(const std::string& file_path);
private: private:
Impl *impl_; Impl* impl_;
CORE_DISALLOW_COPY_AND_ASSIGN(File); CORE_DISALLOW_COPY_AND_ASSIGN(File);
}; };

View File

@@ -23,36 +23,39 @@ class PolicyEngine;
class CdmLicense { class CdmLicense {
public: public:
CdmLicense(); CdmLicense();
virtual ~CdmLicense(); virtual ~CdmLicense();
virtual bool Init(const std::string& token, CryptoSession* session, virtual bool Init(const std::string& token, CryptoSession* session,
PolicyEngine* policy_engine); PolicyEngine* policy_engine);
virtual bool PrepareKeyRequest(const InitializationData& init_data, virtual bool PrepareKeyRequest(const InitializationData& init_data,
const CdmLicenseType license_type, const CdmLicenseType license_type,
const CdmAppParameterMap& app_parameters, const CdmAppParameterMap& app_parameters,
const CdmSessionId& session_id, const CdmSessionId& session_id,
CdmKeyMessage* signed_request, CdmKeyMessage* signed_request,
std::string* server_url); std::string* server_url);
virtual CdmResponseType PrepareKeyUpdateRequest( virtual CdmResponseType PrepareKeyUpdateRequest(bool is_renewal,
bool is_renewal, CdmKeyMessage* signed_request, std::string* server_url); CdmKeyMessage* signed_request,
virtual CdmResponseType HandleKeyResponse(const CdmKeyResponse& license_response); std::string* server_url);
virtual CdmResponseType HandleKeyResponse(
const CdmKeyResponse& license_response);
virtual CdmResponseType HandleKeyUpdateResponse( virtual CdmResponseType HandleKeyUpdateResponse(
bool is_renewal, const CdmKeyResponse& license_response); bool is_renewal, const CdmKeyResponse& license_response);
virtual bool RestoreOfflineLicense(const CdmKeyMessage& license_request, virtual bool RestoreOfflineLicense(
const CdmKeyResponse& license_response, const CdmKeyMessage& license_request,
const CdmKeyResponse& license_renewal_response, const CdmKeyResponse& license_response,
int64_t playback_start_time, const CdmKeyResponse& license_renewal_response,
int64_t last_playback_time); int64_t playback_start_time, int64_t last_playback_time);
virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request, virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response); const CdmKeyResponse& license_response);
virtual bool HasInitData() { return !stored_init_data_.empty(); } virtual bool HasInitData() { return !stored_init_data_.empty(); }
virtual bool IsKeyLoaded(const KeyId& key_id); virtual bool IsKeyLoaded(const KeyId& key_id);
virtual std::string provider_session_token() { return provider_session_token_; } virtual std::string provider_session_token() {
return provider_session_token_;
}
private: private:
bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request, bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
@@ -63,9 +66,9 @@ class CdmLicense {
CdmResponseType HandleKeyErrorResponse( CdmResponseType HandleKeyErrorResponse(
const video_widevine_server::sdk::SignedMessage& signed_message); const video_widevine_server::sdk::SignedMessage& signed_message);
template<typename T> bool PrepareContentId(const CdmLicenseType license_type, template <typename T>
const std::string& request_id, bool PrepareContentId(const CdmLicenseType license_type,
T* content_id); const std::string& request_id, T* content_id);
CryptoSession* session_; CryptoSession* session_;
PolicyEngine* policy_engine_; PolicyEngine* policy_engine_;

View File

@@ -29,7 +29,7 @@ class Lock {
private: private:
class Impl; class Impl;
Impl *impl_; Impl* impl_;
CORE_DISALLOW_COPY_AND_ASSIGN(Lock); CORE_DISALLOW_COPY_AND_ASSIGN(Lock);
}; };
@@ -38,20 +38,14 @@ class Lock {
// is constructed and release when AutoLock goes out of scope. // is constructed and release when AutoLock goes out of scope.
class AutoLock { class AutoLock {
public: public:
explicit AutoLock(Lock& lock) : lock_(&lock) { explicit AutoLock(Lock& lock) : lock_(&lock) { lock_->Acquire(); }
lock_->Acquire();
}
explicit AutoLock(Lock* lock) : lock_(lock) { explicit AutoLock(Lock* lock) : lock_(lock) { lock_->Acquire(); }
lock_->Acquire();
}
~AutoLock() { ~AutoLock() { lock_->Release(); }
lock_->Release();
}
private: private:
Lock *lock_; Lock* lock_;
CORE_DISALLOW_COPY_AND_ASSIGN(AutoLock); CORE_DISALLOW_COPY_AND_ASSIGN(AutoLock);
}; };

View File

@@ -7,10 +7,7 @@
namespace wvcdm { namespace wvcdm {
enum SecurityLevel { enum SecurityLevel { kLevelDefault, kLevel3 };
kLevelDefault,
kLevel3
};
/* This attempts to open a session at the desired security level. /* This attempts to open a session at the desired security level.
If one level is not available, the other will be used instead. */ If one level is not available, the other will be used instead. */

View File

@@ -52,8 +52,7 @@ class RsaPublicKey {
// Encrypt a message using RSA-OAEP. Caller retains ownership of all // Encrypt a message using RSA-OAEP. Caller retains ownership of all
// parameters. Returns true if successful, false otherwise. // parameters. Returns true if successful, false otherwise.
bool Encrypt(const std::string& plaintext, bool Encrypt(const std::string& plaintext, std::string* ciphertext);
std::string* ciphertext);
// Verify RSASSA-PSS signature. Caller retains ownership of all parameters. // Verify RSASSA-PSS signature. Caller retains ownership of all parameters.
// Returns true if validation succeeds, false otherwise. // Returns true if validation succeeds, false otherwise.

View File

@@ -53,6 +53,7 @@ class scoped_ptr {
ptr_ = p; ptr_ = p;
} }
} }
private: private:
T* ptr_; T* ptr_;

View File

@@ -17,7 +17,8 @@ bool BufferReader::Read1(uint8_t* v) {
} }
// Internal implementation of multi-byte reads // Internal implementation of multi-byte reads
template<typename T> bool BufferReader::Read(T* v) { template <typename T>
bool BufferReader::Read(T* v) {
if (!HasBytes(sizeof(T))) { if (!HasBytes(sizeof(T))) {
LOGW("BufferReader::Read<T> : Failure during parse: Not enough bytes (%u)", LOGW("BufferReader::Read<T> : Failure during parse: Not enough bytes (%u)",
sizeof(T)); sizeof(T));

View File

@@ -19,8 +19,8 @@
#include "wv_cdm_event_listener.h" #include "wv_cdm_event_listener.h"
namespace { namespace {
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
const size_t kUsageReportsPerRequest = 1; const size_t kUsageReportsPerRequest = 1;
} // unnamed namespace } // unnamed namespace
namespace wvcdm { namespace wvcdm {
@@ -77,10 +77,9 @@ CdmEngine::~CdmEngine() {
sessions_.clear(); sessions_.clear();
} }
CdmResponseType CdmEngine::OpenSession( CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
const CdmKeySystem& key_system, const CdmClientPropertySet* property_set,
const CdmClientPropertySet* property_set, CdmSessionId* session_id) {
CdmSessionId* session_id) {
LOGI("CdmEngine::OpenSession"); LOGI("CdmEngine::OpenSession");
if (!ValidateKeySystem(key_system)) { if (!ValidateKeySystem(key_system)) {
@@ -116,8 +115,7 @@ CdmResponseType CdmEngine::OpenSession(
} }
CdmResponseType CdmEngine::OpenKeySetSession( CdmResponseType CdmEngine::OpenKeySetSession(
const CdmKeySetId& key_set_id, const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set) {
const CdmClientPropertySet* property_set) {
LOGI("CdmEngine::OpenKeySetSession"); LOGI("CdmEngine::OpenKeySetSession");
if (key_set_id.empty()) { if (key_set_id.empty()) {
@@ -128,8 +126,7 @@ CdmResponseType CdmEngine::OpenKeySetSession(
CdmSessionId session_id; CdmSessionId session_id;
CdmResponseType sts = OpenSession(KEY_SYSTEM, property_set, &session_id); CdmResponseType sts = OpenSession(KEY_SYSTEM, property_set, &session_id);
if (sts != NO_ERROR) if (sts != NO_ERROR) return sts;
return sts;
release_key_sets_[key_set_id] = session_id; release_key_sets_[key_set_id] = session_id;
return NO_ERROR; return NO_ERROR;
@@ -147,8 +144,11 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
CdmSession* session = iter->second; CdmSession* session = iter->second;
sessions_.erase(session_id); sessions_.erase(session_id);
// If the event timer is active, it will delete this session when it's done. // If the event timer is active, it will delete this session when it's done.
if (timer_event_active_) dead_sessions_.push_back(session); if (timer_event_active_) {
else delete session; dead_sessions_.push_back(session);
} else {
delete session;
}
return NO_ERROR; return NO_ERROR;
} }
@@ -158,7 +158,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
if (iter == release_key_sets_.end()) { if (iter == release_key_sets_.end()) {
LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s", LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s",
key_set_id.c_str()); key_set_id.c_str());
return KEY_ERROR; return KEY_ERROR;
} }
@@ -168,14 +168,10 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
} }
CdmResponseType CdmEngine::GenerateKeyRequest( CdmResponseType CdmEngine::GenerateKeyRequest(
const CdmSessionId& session_id, const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
const CdmKeySetId& key_set_id, const InitializationData& init_data, const CdmLicenseType license_type,
const InitializationData& init_data, CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
const CdmLicenseType license_type, std::string* server_url, CdmKeySetId* key_set_id_out) {
CdmAppParameterMap& app_parameters,
CdmKeyMessage* key_request,
std::string* server_url,
CdmKeySetId* key_set_id_out) {
LOGI("CdmEngine::GenerateKeyRequest"); LOGI("CdmEngine::GenerateKeyRequest");
CdmSessionId id = session_id; CdmSessionId id = session_id;
@@ -189,14 +185,14 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
if (!session_id.empty()) { if (!session_id.empty()) {
LOGE("CdmEngine::GenerateKeyRequest: invalid session ID = %s", LOGE("CdmEngine::GenerateKeyRequest: invalid session ID = %s",
session_id.c_str()); session_id.c_str());
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
if (iter == release_key_sets_.end()) { if (iter == release_key_sets_.end()) {
LOGE("CdmEngine::GenerateKeyRequest: key set ID not found = %s", LOGE("CdmEngine::GenerateKeyRequest: key set ID not found = %s",
key_set_id.c_str()); key_set_id.c_str());
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -206,7 +202,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
CdmSessionMap::iterator iter = sessions_.find(id); CdmSessionMap::iterator iter = sessions_.find(id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
LOGE("CdmEngine::GenerateKeyRequest: session_id not found = %s", LOGE("CdmEngine::GenerateKeyRequest: session_id not found = %s",
id.c_str()); id.c_str());
return KEY_ERROR; return KEY_ERROR;
} }
@@ -220,22 +216,24 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
if (license_type == kLicenseTypeRelease) { if (license_type == kLicenseTypeRelease) {
sts = iter->second->RestoreOfflineSession(key_set_id, kLicenseTypeRelease); sts = iter->second->RestoreOfflineSession(key_set_id, kLicenseTypeRelease);
if (sts != KEY_ADDED) { if (sts != KEY_ADDED) {
LOGE("CdmEngine::GenerateKeyRequest: key release restoration failed," LOGE(
"CdmEngine::GenerateKeyRequest: key release restoration failed,"
"sts = %d", sts); "sts = %d", sts);
return sts; return sts;
} }
} }
sts = iter->second->GenerateKeyRequest(init_data, license_type, sts =
app_parameters, key_request, iter->second->GenerateKeyRequest(init_data, license_type, app_parameters,
server_url, key_set_id_out); key_request, server_url, key_set_id_out);
if (KEY_MESSAGE != sts) { if (KEY_MESSAGE != sts) {
if (sts == NEED_PROVISIONING) { if (sts == NEED_PROVISIONING) {
cert_provisioning_requested_security_level_ = cert_provisioning_requested_security_level_ =
iter->second->GetRequestedSecurityLevel(); iter->second->GetRequestedSecurityLevel();
} }
LOGE("CdmEngine::GenerateKeyRequest: key request generation failed, " LOGE(
"CdmEngine::GenerateKeyRequest: key request generation failed, "
"sts = %d", sts); "sts = %d", sts);
return sts; return sts;
} }
@@ -247,10 +245,9 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
return KEY_MESSAGE; return KEY_MESSAGE;
} }
CdmResponseType CdmEngine::AddKey( CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
const CdmSessionId& session_id, const CdmKeyResponse& key_data,
const CdmKeyResponse& key_data, CdmKeySetId* key_set_id) {
CdmKeySetId* key_set_id) {
LOGI("CdmEngine::AddKey"); LOGI("CdmEngine::AddKey");
CdmSessionId id = session_id; CdmSessionId id = session_id;
@@ -298,9 +295,8 @@ CdmResponseType CdmEngine::AddKey(
return KEY_ADDED; return KEY_ADDED;
} }
CdmResponseType CdmEngine::RestoreKey( CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id,
const CdmSessionId& session_id, const CdmKeySetId& key_set_id) {
const CdmKeySetId& key_set_id) {
LOGI("CdmEngine::RestoreKey"); LOGI("CdmEngine::RestoreKey");
if (key_set_id.empty()) { if (key_set_id.empty()) {
@@ -311,7 +307,7 @@ CdmResponseType CdmEngine::RestoreKey(
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
LOGE("CdmEngine::RestoreKey: session_id not found = %s ", LOGE("CdmEngine::RestoreKey: session_id not found = %s ",
session_id.c_str()); session_id.c_str());
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -322,7 +318,7 @@ CdmResponseType CdmEngine::RestoreKey(
iter->second->GetRequestedSecurityLevel(); iter->second->GetRequestedSecurityLevel();
} }
if (KEY_ADDED != sts) { if (KEY_ADDED != sts) {
LOGE("CdmEngine::RestoreKey: restore offline session error = %d", sts); LOGE("CdmEngine::RestoreKey: restore offline session failed = %d", sts);
} }
return sts; return sts;
} }
@@ -342,8 +338,7 @@ CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) {
} }
CdmResponseType CdmEngine::GenerateRenewalRequest( CdmResponseType CdmEngine::GenerateRenewalRequest(
const CdmSessionId& session_id, const CdmSessionId& session_id, CdmKeyMessage* key_request,
CdmKeyMessage* key_request,
std::string* server_url) { std::string* server_url) {
LOGI("CdmEngine::GenerateRenewalRequest"); LOGI("CdmEngine::GenerateRenewalRequest");
@@ -361,8 +356,8 @@ CdmResponseType CdmEngine::GenerateRenewalRequest(
key_request->clear(); key_request->clear();
CdmResponseType sts = iter->second->GenerateRenewalRequest(key_request, CdmResponseType sts =
server_url); iter->second->GenerateRenewalRequest(key_request, server_url);
if (KEY_MESSAGE != sts) { if (KEY_MESSAGE != sts) {
LOGE("CdmEngine::GenerateRenewalRequest: key request gen. failed, sts=%d", LOGE("CdmEngine::GenerateRenewalRequest: key request gen. failed, sts=%d",
@@ -373,9 +368,8 @@ CdmResponseType CdmEngine::GenerateRenewalRequest(
return KEY_MESSAGE; return KEY_MESSAGE;
} }
CdmResponseType CdmEngine::RenewKey( CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id,
const CdmSessionId& session_id, const CdmKeyResponse& key_data) {
const CdmKeyResponse& key_data) {
LOGI("CdmEngine::RenewKey"); LOGI("CdmEngine::RenewKey");
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
@@ -470,9 +464,8 @@ CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id,
return iter->second->QueryStatus(key_info); return iter->second->QueryStatus(key_info);
} }
CdmResponseType CdmEngine::QueryKeyStatus( CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id,
const CdmSessionId& session_id, CdmQueryMap* key_info) {
CdmQueryMap* key_info) {
LOGI("CdmEngine::QueryKeyStatus"); LOGI("CdmEngine::QueryKeyStatus");
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
@@ -483,9 +476,8 @@ CdmResponseType CdmEngine::QueryKeyStatus(
return iter->second->QueryKeyStatus(key_info); return iter->second->QueryKeyStatus(key_info);
} }
CdmResponseType CdmEngine::QueryKeyControlInfo( CdmResponseType CdmEngine::QueryKeyControlInfo(const CdmSessionId& session_id,
const CdmSessionId& session_id, CdmQueryMap* key_info) {
CdmQueryMap* key_info) {
LOGI("CdmEngine::QueryKeyControlInfo"); LOGI("CdmEngine::QueryKeyControlInfo");
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
@@ -504,10 +496,8 @@ CdmResponseType CdmEngine::QueryKeyControlInfo(
* Returns NO_ERROR for success and UNKNOWN_ERROR if fails. * Returns NO_ERROR for success and UNKNOWN_ERROR if fails.
*/ */
CdmResponseType CdmEngine::GetProvisioningRequest( CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, CdmCertificateType cert_type, const std::string& cert_authority,
const std::string& cert_authority, CdmProvisioningRequest* request, std::string* default_url) {
CdmProvisioningRequest* request,
std::string* default_url) {
if (!request || !default_url) { if (!request || !default_url) {
LOGE("CdmEngine::GetProvisioningRequest: invalid input parameters"); LOGE("CdmEngine::GetProvisioningRequest: invalid input parameters");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -516,11 +506,8 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
cert_provisioning_.reset(new CertificateProvisioning()); cert_provisioning_.reset(new CertificateProvisioning());
} }
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest( CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
cert_provisioning_requested_security_level_, cert_provisioning_requested_security_level_, cert_type, cert_authority,
cert_type, request, default_url);
cert_authority,
request,
default_url);
if (ret != NO_ERROR) { if (ret != NO_ERROR) {
cert_provisioning_.reset(NULL); // Release resources. cert_provisioning_.reset(NULL); // Release resources.
} }
@@ -535,8 +522,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
* Returns NO_ERROR for success and UNKNOWN_ERROR if fails. * Returns NO_ERROR for success and UNKNOWN_ERROR if fails.
*/ */
CdmResponseType CdmEngine::HandleProvisioningResponse( CdmResponseType CdmEngine::HandleProvisioningResponse(
CdmProvisioningResponse& response, CdmProvisioningResponse& response, std::string* cert,
std::string* cert,
std::string* wrapped_key) { std::string* wrapped_key) {
if (response.empty()) { if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response."); LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
@@ -544,8 +530,9 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
if (NULL == cert) { if (NULL == cert) {
LOGE("CdmEngine::HandleProvisioningResponse: invalid certificate " LOGE(
"destination"); "CdmEngine::HandleProvisioningResponse: invalid certificate "
"destination");
cert_provisioning_.reset(NULL); cert_provisioning_.reset(NULL);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -559,9 +546,8 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
LOGE("CdmEngine::HandleProvisioningResponse: provisioning object missing."); LOGE("CdmEngine::HandleProvisioningResponse: provisioning object missing.");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
CdmResponseType ret = CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse(
cert_provisioning_->HandleProvisioningResponse(response, cert, response, cert, wrapped_key);
wrapped_key);
cert_provisioning_.reset(NULL); // Release resources. cert_provisioning_.reset(NULL); // Release resources.
return ret; return ret;
} }
@@ -664,11 +650,9 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
do { do {
status = GetUsageInfo(app_id, security_level, usage_info); status = GetUsageInfo(app_id, security_level, usage_info);
if (KEY_MESSAGE == status && !usage_info->empty()) if (KEY_MESSAGE == status && !usage_info->empty()) return status;
return status;
} while (KEY_CANCELED == status); } while (KEY_CANCELED == status);
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3; security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
do { do {
status = GetUsageInfo(app_id, security_level, usage_info); status = GetUsageInfo(app_id, security_level, usage_info);
@@ -720,13 +704,14 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
status = usage_session_->RestoreUsageSession(license_info[index].first, status = usage_session_->RestoreUsageSession(license_info[index].first,
license_info[index].second); license_info[index].second);
if (KEY_ADDED != status) { if (KEY_ADDED != status) {
LOGE("CdmEngine::GetUsageInfo: restore usage session (%u) error %d", LOGE("CdmEngine::GetUsageInfo: restore usage session (%d) error %ld", index,
index, status); status);
usage_info->clear(); usage_info->clear();
return status; return status;
} }
status = usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url); status =
usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
switch (status) { switch (status) {
case KEY_MESSAGE: case KEY_MESSAGE:
@@ -750,11 +735,13 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
for (int i = 0, j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++i, ++j) { for (int i = 0, j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++i, ++j) {
if (handle[i].Init(static_cast<CdmSecurityLevel>(j))) { if (handle[i].Init(static_cast<CdmSecurityLevel>(j))) {
if (!handle[i].DeleteAllUsageInfoForApp(app_id)) { if (!handle[i].DeleteAllUsageInfoForApp(app_id)) {
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure stops", j); LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure"
"stops", j);
status = UNKNOWN_ERROR; status = UNKNOWN_ERROR;
} }
} else { } else {
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device files", j); LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device"
"files", j);
status = UNKNOWN_ERROR; status = UNKNOWN_ERROR;
} }
} }
@@ -776,9 +763,8 @@ CdmResponseType CdmEngine::ReleaseUsageInfo(
return status; return status;
} }
CdmResponseType CdmEngine::Decrypt( CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id,
const CdmSessionId& session_id, const CdmDecryptionParameters& parameters) {
const CdmDecryptionParameters& parameters) {
if (parameters.key_id == NULL) { if (parameters.key_id == NULL) {
LOGE("CdmEngine::Decrypt: no key_id"); LOGE("CdmEngine::Decrypt: no key_id");
return KEY_ERROR; return KEY_ERROR;
@@ -799,7 +785,8 @@ CdmResponseType CdmEngine::Decrypt(
!Properties::Properties::oem_crypto_use_fifo()) { !Properties::Properties::oem_crypto_use_fifo()) {
LOGE("CdmEngine::Decrypt: no dest decrypt buffer"); LOGE("CdmEngine::Decrypt: no dest decrypt buffer");
return KEY_ERROR; return KEY_ERROR;
} // else we must be level 1 direct and we don't need to return a buffer. }
// else we must be level 1 direct and we don't need to return a buffer.
} }
CdmSessionMap::iterator iter; CdmSessionMap::iterator iter;
@@ -815,8 +802,7 @@ CdmResponseType CdmEngine::Decrypt(
} }
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
LOGE("CdmEngine::Decrypt: session not found: id=%s, id size=%d", LOGE("CdmEngine::Decrypt: session not found: id=%s, id size=%d",
session_id.c_str(), session_id.c_str(), session_id.size());
session_id.size());
return KEY_ERROR; return KEY_ERROR;
} }
@@ -833,9 +819,8 @@ bool CdmEngine::IsKeyLoaded(const KeyId& key_id) {
return false; return false;
} }
bool CdmEngine::FindSessionForKey( bool CdmEngine::FindSessionForKey(const KeyId& key_id,
const KeyId& key_id, CdmSessionId* session_id) {
CdmSessionId* session_id) {
if (NULL == session_id) { if (NULL == session_id) {
LOGE("CdmEngine::FindSessionForKey: session id not provided"); LOGE("CdmEngine::FindSessionForKey: session id not provided");
return false; return false;
@@ -863,9 +848,8 @@ bool CdmEngine::FindSessionForKey(
return false; return false;
} }
bool CdmEngine::AttachEventListener( bool CdmEngine::AttachEventListener(const CdmSessionId& session_id,
const CdmSessionId& session_id, WvCdmEventListener* listener) {
WvCdmEventListener* listener) {
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
return false; return false;
@@ -874,9 +858,8 @@ bool CdmEngine::AttachEventListener(
return iter->second->AttachEventListener(listener); return iter->second->AttachEventListener(listener);
} }
bool CdmEngine::DetachEventListener( bool CdmEngine::DetachEventListener(const CdmSessionId& session_id,
const CdmSessionId& session_id, WvCdmEventListener* listener) {
WvCdmEventListener* listener) {
CdmSessionMap::iterator iter = sessions_.find(session_id); CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
return false; return false;
@@ -964,7 +947,6 @@ void CdmEngine::OnTimerEvent() {
} }
void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) { void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
for (CdmSessionMap::iterator iter = sessions_.begin(); for (CdmSessionMap::iterator iter = sessions_.begin();
iter != sessions_.end(); ++iter) { iter != sessions_.end(); ++iter) {
iter->second->OnKeyReleaseEvent(key_set_id); iter->second->OnKeyReleaseEvent(key_set_id);

View File

@@ -31,22 +31,18 @@ CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set) {
new DeviceFiles(), cdm_client_property_set); new DeviceFiles(), cdm_client_property_set);
} }
CdmSession::CdmSession( CdmSession::CdmSession(CdmLicense* license_parser,
CdmLicense* license_parser, CryptoSession* crypto_session,
CryptoSession* crypto_session, PolicyEngine* policy_engine, DeviceFiles* file_handle,
PolicyEngine* policy_engine, const CdmClientPropertySet* cdm_client_property_set) {
DeviceFiles* file_handle,
const CdmClientPropertySet* cdm_client_property_set) {
Create(license_parser, crypto_session, policy_engine, file_handle, Create(license_parser, crypto_session, policy_engine, file_handle,
cdm_client_property_set); cdm_client_property_set);
} }
void CdmSession::Create( void CdmSession::Create(CdmLicense* license_parser,
CdmLicense* license_parser, CryptoSession* crypto_session,
CryptoSession* crypto_session, PolicyEngine* policy_engine, DeviceFiles* file_handle,
PolicyEngine* policy_engine, const CdmClientPropertySet* cdm_client_property_set) {
DeviceFiles* file_handle,
const CdmClientPropertySet* cdm_client_property_set) {
// Just return on failures. Failures will be signaled in Init. // Just return on failures. Failures will be signaled in Init.
if (NULL == license_parser) { if (NULL == license_parser) {
LOGE("CdmSession::Create: License parser not provided"); LOGE("CdmSession::Create: License parser not provided");
@@ -80,8 +76,8 @@ void CdmSession::Create(
if (cdm_client_property_set) { if (cdm_client_property_set) {
Properties::AddSessionPropertySet(session_id_, cdm_client_property_set); Properties::AddSessionPropertySet(session_id_, cdm_client_property_set);
} }
security_level_ = GetRequestedSecurityLevel() == kLevel3 security_level_ = GetRequestedSecurityLevel() == kLevel3 ? kSecurityLevelL3
? kSecurityLevelL3 : GetSecurityLevel(); : GetSecurityLevel();
app_id_.clear(); app_id_.clear();
} }
@@ -126,21 +122,17 @@ CdmResponseType CdmSession::RestoreOfflineSession(
key_set_id_ = key_set_id; key_set_id_ = key_set_id;
// Retrieve license information from persistent store // Retrieve license information from persistent store
if (!file_handle_->Reset(security_level_)) if (!file_handle_->Reset(security_level_)) return UNKNOWN_ERROR;
return UNKNOWN_ERROR;
DeviceFiles::LicenseState license_state; DeviceFiles::LicenseState license_state;
int64_t playback_start_time; int64_t playback_start_time;
int64_t last_playback_time; int64_t last_playback_time;
if (!file_handle_->RetrieveLicense(key_set_id, &license_state, if (!file_handle_->RetrieveLicense(
&offline_init_data_, key_set_id, &license_state, &offline_init_data_, &key_request_,
&key_request_, &key_response_, &key_response_, &offline_key_renewal_request_,
&offline_key_renewal_request_, &offline_key_renewal_response_, &offline_release_server_url_,
&offline_key_renewal_response_, &playback_start_time, &last_playback_time)) {
&offline_release_server_url_,
&playback_start_time,
&last_playback_time)) {
LOGE("CdmSession::Init failed to retrieve license. key set id = %s", LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
key_set_id.c_str()); key_set_id.c_str());
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -148,10 +140,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(
// Do not restore a released offline license, unless a release retry // Do not restore a released offline license, unless a release retry
if (!(license_type == kLicenseTypeRelease || if (!(license_type == kLicenseTypeRelease ||
license_state == DeviceFiles::kLicenseStateActive)) { license_state == DeviceFiles::kLicenseStateActive)) {
LOGE("CdmSession::Init invalid offline license state = %d, type = %d", LOGE("CdmSession::Init invalid offline license state = %d, type = %d",
license_state, license_state, license_type);
license_type);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -161,10 +152,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
} else { } else {
if (!license_parser_->RestoreOfflineLicense(key_request_, key_response_, if (!license_parser_->RestoreOfflineLicense(
offline_key_renewal_response_, key_request_, key_response_, offline_key_renewal_response_,
playback_start_time, playback_start_time, last_playback_time)) {
last_playback_time)) {
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
} }
@@ -176,8 +166,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(
} }
CdmResponseType CdmSession::RestoreUsageSession( CdmResponseType CdmSession::RestoreUsageSession(
const CdmKeyMessage& key_request, const CdmKeyMessage& key_request, const CdmKeyResponse& key_response) {
const CdmKeyResponse& key_response) {
key_request_ = key_request; key_request_ = key_request;
key_response_ = key_response; key_response_ = key_response;
@@ -206,9 +195,15 @@ CdmResponseType CdmSession::GenerateKeyRequest(
} }
switch (license_type) { switch (license_type) {
case kLicenseTypeStreaming: is_offline_ = false; break; case kLicenseTypeStreaming:
case kLicenseTypeOffline: is_offline_ = true; break; is_offline_ = false;
case kLicenseTypeRelease: is_release_ = true; break; break;
case kLicenseTypeOffline:
is_offline_ = true;
break;
case kLicenseTypeRelease:
is_release_ = true;
break;
default: default:
LOGE("CdmSession::GenerateKeyRequest: unrecognized license type: %ld", LOGE("CdmSession::GenerateKeyRequest: unrecognized license type: %ld",
license_type); license_type);
@@ -352,7 +347,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
CdmResponseType status = crypto_session_->Decrypt(params); CdmResponseType status = crypto_session_->Decrypt(params);
switch (status) { switch (status) {
case NO_ERROR: case NO_ERROR: {
if (is_initial_decryption_) { if (is_initial_decryption_) {
policy_engine_->BeginDecryption(); policy_engine_->BeginDecryption();
is_initial_decryption_ = false; is_initial_decryption_ = false;
@@ -360,9 +355,10 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
has_decrypted_recently_ = true; has_decrypted_recently_ = true;
if (!is_usage_update_needed_) { if (!is_usage_update_needed_) {
is_usage_update_needed_ = is_usage_update_needed_ =
!license_parser_->provider_session_token().empty(); !license_parser_->provider_session_token().empty();
} }
break; break;
}
case UNKNOWN_ERROR: { case UNKNOWN_ERROR: {
Clock clock; Clock clock;
int64_t current_time = clock.GetCurrentTime(); int64_t current_time = clock.GetCurrentTime();
@@ -372,8 +368,9 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
} }
break; break;
} }
default: //Ignore default: { //Ignore
break; break;
}
} }
return status; return status;
@@ -387,8 +384,7 @@ CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyMessage* key_request,
CdmResponseType status = CdmResponseType status =
license_parser_->PrepareKeyUpdateRequest(true, key_request, server_url); license_parser_->PrepareKeyUpdateRequest(true, key_request, server_url);
if (KEY_MESSAGE != status) if (KEY_MESSAGE != status) return status;
return status;
if (is_offline_) { if (is_offline_) {
offline_key_renewal_request_ = *key_request; offline_key_renewal_request_ = *key_request;
@@ -415,8 +411,7 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyMessage* key_request,
CdmResponseType status = CdmResponseType status =
license_parser_->PrepareKeyUpdateRequest(false, key_request, server_url); license_parser_->PrepareKeyUpdateRequest(false, key_request, server_url);
if (KEY_MESSAGE != status) if (KEY_MESSAGE != status) return status;
return status;
if (is_offline_) { // Mark license as being released if (is_offline_) { // Mark license as being released
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing)) if (!StoreLicense(DeviceFiles::kLicenseStateReleasing))
@@ -427,10 +422,9 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyMessage* key_request,
// ReleaseKey() - Accept release response and release license. // ReleaseKey() - Accept release response and release license.
CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) { CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
CdmResponseType sts = license_parser_->HandleKeyUpdateResponse(false, CdmResponseType sts =
key_response); license_parser_->HandleKeyUpdateResponse(false, key_response);
if (KEY_ADDED != sts) if (KEY_ADDED != sts) return sts;
return sts;
if (is_offline_ || !license_parser_->provider_session_token().empty()) { if (is_offline_ || !license_parser_->provider_session_token().empty()) {
DeleteLicense(); DeleteLicense();
@@ -456,8 +450,7 @@ bool CdmSession::GenerateKeySetId(CdmKeySetId* key_set_id) {
std::vector<uint8_t> random_data( std::vector<uint8_t> random_data(
(kKeySetIdLength - sizeof(KEY_SET_ID_PREFIX)) / 2, 0); (kKeySetIdLength - sizeof(KEY_SET_ID_PREFIX)) / 2, 0);
if (!file_handle_->Reset(security_level_)) if (!file_handle_->Reset(security_level_)) return false;
return false;
while (key_set_id->empty()) { while (key_set_id->empty()) {
if (!crypto_session_->GetRandom(random_data.size(), &random_data[0])) if (!crypto_session_->GetRandom(random_data.size(), &random_data[0]))
@@ -519,14 +512,12 @@ CdmResponseType CdmSession::StoreLicense() {
} }
bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) { bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
if (!file_handle_->Reset(security_level_)) if (!file_handle_->Reset(security_level_)) return false;
return false;
return file_handle_->StoreLicense( return file_handle_->StoreLicense(
key_set_id_, state, offline_init_data_, key_request_, key_set_id_, state, offline_init_data_, key_request_, key_response_,
key_response_, offline_key_renewal_request_, offline_key_renewal_request_, offline_key_renewal_response_,
offline_key_renewal_response_, offline_release_server_url_, offline_release_server_url_, policy_engine_->GetPlaybackStartTime(),
policy_engine_->GetPlaybackStartTime(),
policy_engine_->GetLastPlaybackTime()); policy_engine_->GetLastPlaybackTime());
} }

View File

@@ -14,9 +14,9 @@ namespace {
// The provisioning server supplies the certificate that is needed // The provisioning server supplies the certificate that is needed
// to communicate with the License Server. // to communicate with the License Server.
const std::string kProvisioningServerUrl = const std::string kProvisioningServerUrl =
"https://www.googleapis.com/" "https://www.googleapis.com/"
"certificateprovisioning/v1/devicecertificates/create" "certificateprovisioning/v1/devicecertificates/create"
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
} }
namespace wvcdm { namespace wvcdm {
@@ -41,9 +41,7 @@ using video_widevine_server::sdk::SignedProvisioningMessage;
* base64 encoded message * base64 encoded message
*/ */
void CertificateProvisioning::ComposeJsonRequestAsQueryString( void CertificateProvisioning::ComposeJsonRequestAsQueryString(
const std::string& message, const std::string& message, CdmProvisioningRequest* request) {
CdmProvisioningRequest* request) {
// Performs base64 encoding for message // Performs base64 encoding for message
std::vector<uint8_t> message_vector(message.begin(), message.end()); std::vector<uint8_t> message_vector(message.begin(), message.end());
std::string message_b64 = Base64SafeEncodeNoPad(message_vector); std::string message_b64 = Base64SafeEncodeNoPad(message_vector);
@@ -58,10 +56,8 @@ void CertificateProvisioning::ComposeJsonRequestAsQueryString(
* Returns NO_ERROR for success and UNKNOWN_ERROR if fails. * Returns NO_ERROR for success and UNKNOWN_ERROR if fails.
*/ */
CdmResponseType CertificateProvisioning::GetProvisioningRequest( CdmResponseType CertificateProvisioning::GetProvisioningRequest(
SecurityLevel requested_security_level, SecurityLevel requested_security_level, CdmCertificateType cert_type,
CdmCertificateType cert_type, const std::string& cert_authority, CdmProvisioningRequest* request,
const std::string& cert_authority,
CdmProvisioningRequest* request,
std::string* default_url) { std::string* default_url) {
if (!default_url) { if (!default_url) {
LOGE("GetProvisioningRequest: pointer for returning URL is NULL"); LOGE("GetProvisioningRequest: pointer for returning URL is NULL");
@@ -123,7 +119,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
// Derives signing and encryption keys and constructs signature. // Derives signing and encryption keys and constructs signature.
std::string request_signature; std::string request_signature;
if (!crypto_session_.PrepareRequest(serialized_message, true, if (!crypto_session_.PrepareRequest(serialized_message, true,
&request_signature)) { &request_signature)) {
LOGE("GetProvisioningRequest: fails to prepare request"); LOGE("GetProvisioningRequest: fails to prepare request");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -152,10 +148,8 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
* Returns true for success and false if fails. * Returns true for success and false if fails.
*/ */
bool CertificateProvisioning::ParseJsonResponse( bool CertificateProvisioning::ParseJsonResponse(
const CdmProvisioningResponse& json_str, const CdmProvisioningResponse& json_str, const std::string& start_substr,
const std::string& start_substr, const std::string& end_substr, std::string* result) {
const std::string& end_substr,
std::string* result) {
std::string b64_string; std::string b64_string;
size_t start = json_str.find(start_substr); size_t start = json_str.find(start_substr);
if (start == json_str.npos) { if (start == json_str.npos) {
@@ -186,10 +180,8 @@ bool CertificateProvisioning::ParseJsonResponse(
* Returns NO_ERROR for success and UNKNOWN_ERROR if fails. * Returns NO_ERROR for success and UNKNOWN_ERROR if fails.
*/ */
CdmResponseType CertificateProvisioning::HandleProvisioningResponse( CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
CdmProvisioningResponse& response, CdmProvisioningResponse& response, std::string* cert,
std::string* cert,
std::string* wrapped_key) { std::string* wrapped_key) {
// Extracts signed response from JSON string, decodes base64 signed response // Extracts signed response from JSON string, decodes base64 signed response
const std::string kMessageStart = "\"signedResponse\": \""; const std::string kMessageStart = "\"signedResponse\": \"";
const std::string kMessageEnd = "\""; const std::string kMessageEnd = "\"";
@@ -220,8 +212,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
error = true; error = true;
} }
if (error) if (error) return UNKNOWN_ERROR;
return UNKNOWN_ERROR;
const std::string& signed_message = signed_response.message(); const std::string& signed_message = signed_response.message();
ProvisioningResponse provisioning_response; ProvisioningResponse provisioning_response;
@@ -241,12 +232,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv(); const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv();
const std::string& signature = signed_response.signature(); const std::string& signature = signed_response.signature();
std::string wrapped_rsa_key; std::string wrapped_rsa_key;
if (!crypto_session_.RewrapDeviceRSAKey(signed_message, if (!crypto_session_.RewrapDeviceRSAKey(signed_message, signature, nonce,
signature, enc_rsa_key, rsa_key_iv,
nonce, &wrapped_rsa_key)) {
enc_rsa_key,
rsa_key_iv,
&wrapped_rsa_key)){
LOGE("HandleProvisioningResponse: RewrapDeviceRSAKey fails"); LOGE("HandleProvisioningResponse: RewrapDeviceRSAKey fails");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }

View File

@@ -245,16 +245,16 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level); OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level);
if (OEMCrypto_SUCCESS == sts) { if (OEMCrypto_SUCCESS == sts) {
oec_session_id_ = static_cast<CryptoSessionId>(sid); oec_session_id_ = static_cast<CryptoSessionId>(sid);
LOGV("OpenSession: id= %d", (uint32_t)oec_session_id_); LOGV("OpenSession: id= %ld", (uint32_t)oec_session_id_);
open_ = true; open_ = true;
} else if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) { } else if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
sts, session_count_, (int)initialized_); session_count_, (int)initialized_);
return INSUFFICIENT_CRYPTO_RESOURCES; return INSUFFICIENT_CRYPTO_RESOURCES;
} }
if (!open_) { if (!open_) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
sts, session_count_, (int)initialized_); session_count_, (int)initialized_);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -432,7 +432,7 @@ CdmResponseType CryptoSession::LoadKeys(
sts = OEMCrypto_UpdateUsageTable(); sts = OEMCrypto_UpdateUsageTable();
if (sts != OEMCrypto_SUCCESS) { if (sts != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld", LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld",
sts); sts);
} }
} }
return KEY_ADDED; return KEY_ADDED;
@@ -604,8 +604,8 @@ bool CryptoSession::GenerateRsaSignature(const std::string& message,
OEMCryptoResult sts = OEMCrypto_GenerateRSASignature( OEMCryptoResult sts = OEMCrypto_GenerateRSASignature(
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()), oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
message.size(), message.size(),
reinterpret_cast<uint8_t*>(const_cast<char*>(signature->data())), reinterpret_cast<uint8_t*>(const_cast<char*>(signature->data())), &length,
&length, kSign_RSASSA_PSS); kSign_RSASSA_PSS);
if (OEMCrypto_SUCCESS != sts) { if (OEMCrypto_SUCCESS != sts) {
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) { if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
@@ -723,18 +723,15 @@ CdmResponseType CryptoSession::DeactivateUsageInformation(
OEMCryptoResult status = OEMCryptoResult status =
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length()); OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
switch(status) { switch (status) {
case OEMCrypto_SUCCESS: case OEMCrypto_SUCCESS:
return NO_ERROR; return NO_ERROR;
case OEMCrypto_ERROR_INVALID_CONTEXT: case OEMCrypto_ERROR_INVALID_CONTEXT:
LOGE("CryptoSession::DeactivateUsageInformation: Deactivate Usage Entry " LOGE("CryptoSession::DeactivateUsageInformation: invalid context error");
" invalid context error");
return KEY_CANCELED; return KEY_CANCELED;
default: default:
LOGE("CryptoSession::DeactivateUsageInformation: Deactivate Usage Entry " LOGE("CryptoSession::DeactivateUsageInformation: error=%ld", status);
" error=%ld", return UNKNOWN_ERROR;
status);
return UNKNOWN_ERROR;
} }
} }
@@ -754,15 +751,14 @@ CdmResponseType CryptoSession::GenerateUsageReport(
const_cast<char*>(provider_session_token.data())); const_cast<char*>(provider_session_token.data()));
size_t usage_length = 0; size_t usage_length = 0;
OEMCryptoResult status = OEMCryptoResult status = OEMCrypto_ReportUsage(
OEMCrypto_ReportUsage(oec_session_id_, pst, oec_session_id_, pst, provider_session_token.length(), NULL,
provider_session_token.length(), NULL, &usage_length);
&usage_length);
if (OEMCrypto_SUCCESS != status) { if (OEMCrypto_SUCCESS != status) {
if (OEMCrypto_ERROR_SHORT_BUFFER != status) { if (OEMCrypto_ERROR_SHORT_BUFFER != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld",
status); status);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
} }
@@ -787,7 +783,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
*usage_duration_status = kUsageDurationsInvalid; *usage_duration_status = kUsageDurationsInvalid;
if (usage_length < sizeof(pst_report)) { if (usage_length < sizeof(pst_report)) {
LOGE("CryptoSession::GenerateUsageReport: usage report too small=%ld", LOGE("CryptoSession::GenerateUsageReport: usage report too small=%ld",
usage_length); usage_length);
return NO_ERROR; // usage report available but no duration information return NO_ERROR; // usage report available but no duration information
} }
@@ -798,15 +794,15 @@ CdmResponseType CryptoSession::GenerateUsageReport(
} }
LOGV("OEMCrypto_PST_Report.status: %d\n", pst_report.status); LOGV("OEMCrypto_PST_Report.status: %d\n", pst_report.status);
LOGV("OEMCrypto_PST_Report.clock_security_level: %d\n", LOGV("OEMCrypto_PST_Report.clock_security_level: %d\n",
pst_report.clock_security_level); pst_report.clock_security_level);
LOGV("OEMCrypto_PST_Report.pst_length: %d\n", pst_report.pst_length); LOGV("OEMCrypto_PST_Report.pst_length: %d\n", pst_report.pst_length);
LOGV("OEMCrypto_PST_Report.padding: %d\n", pst_report.padding); LOGV("OEMCrypto_PST_Report.padding: %d\n", pst_report.padding);
LOGV("OEMCrypto_PST_Report.seconds_since_license_received: %lld\n", LOGV("OEMCrypto_PST_Report.seconds_since_license_received: %lld\n",
ntohll64(pst_report.seconds_since_license_received)); ntohll64(pst_report.seconds_since_license_received));
LOGV("OEMCrypto_PST_Report.seconds_since_first_decrypt: %lld\n", LOGV("OEMCrypto_PST_Report.seconds_since_first_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_first_decrypt)); ntohll64(pst_report.seconds_since_first_decrypt));
LOGV("OEMCrypto_PST_Report.seconds_since_last_decrypt: %lld\n", LOGV("OEMCrypto_PST_Report.seconds_since_last_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_last_decrypt)); ntohll64(pst_report.seconds_since_last_decrypt));
LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str()); LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str());
// When usage report state is inactive, we have to deduce whether the // When usage report state is inactive, we have to deduce whether the
@@ -845,9 +841,8 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
} }
status = OEMCrypto_UpdateUsageTable(); status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) { if (status != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::ReleaseUsageInformation: OEMCrypto_UpdateUsageTable: " LOGW("CryptoSession::ReleaseUsageInformation: update table error=%ld",
"error=%ld", status);
status);
} }
return NO_ERROR; return NO_ERROR;
@@ -864,9 +859,8 @@ CdmResponseType CryptoSession::DeleteAllUsageReports() {
status = OEMCrypto_UpdateUsageTable(); status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) { if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::ReleaseUsageInformation: OEMCrypto_UpdateUsageTable: " LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld",
"error=%ld", status);
status);
} }
return NO_ERROR; return NO_ERROR;
@@ -954,9 +948,8 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
return true; return true;
} }
bool CryptoSession::GetHdcpCapabilities( bool CryptoSession::GetHdcpCapabilities(OemCryptoHdcpVersion* current_version,
OemCryptoHdcpVersion* current_version, OemCryptoHdcpVersion* max_version) {
OemCryptoHdcpVersion* max_version) {
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_); LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);
if (!initialized_) return UNKNOWN_ERROR; if (!initialized_) return UNKNOWN_ERROR;
OEMCrypto_HDCP_Capability current, max; OEMCrypto_HDCP_Capability current, max;

View File

@@ -3,11 +3,11 @@
#include "device_files.h" #include "device_files.h"
#if defined(__APPLE__) #if defined(__APPLE__)
# include <CommonCrypto/CommonDigest.h> #include <CommonCrypto/CommonDigest.h>
# define SHA256 CC_SHA256 #define SHA256 CC_SHA256
# define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH #define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
#else #else
# include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#endif #endif
@@ -49,7 +49,7 @@ bool Hash(const std::string& data, std::string* hash) {
hash->resize(SHA256_DIGEST_LENGTH); hash->resize(SHA256_DIGEST_LENGTH);
const unsigned char* input = const unsigned char* input =
reinterpret_cast<const unsigned char*>(data.data()); reinterpret_cast<const unsigned char*>(data.data());
unsigned char* output = reinterpret_cast<unsigned char*>(&(*hash)[0]); unsigned char* output = reinterpret_cast<unsigned char*>(&(*hash)[0]);
SHA256(input, data.size(), output); SHA256(input, data.size(), output);
return true; return true;
@@ -60,9 +60,10 @@ bool Hash(const std::string& data, std::string* hash) {
namespace wvcdm { namespace wvcdm {
DeviceFiles::DeviceFiles() DeviceFiles::DeviceFiles()
: file_(NULL), security_level_(kSecurityLevelUninitialized), : file_(NULL),
initialized_(false), test_file_(false) { security_level_(kSecurityLevelUninitialized),
} initialized_(false),
test_file_(false) {}
DeviceFiles::~DeviceFiles() { DeviceFiles::~DeviceFiles() {
if (test_file_) file_.release(); if (test_file_) file_.release();
@@ -119,8 +120,7 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
} }
std::string serialized_file; std::string serialized_file;
if (!RetrieveHashedFile(kCertificateFileName, &serialized_file)) if (!RetrieveHashedFile(kCertificateFileName, &serialized_file)) return false;
return false;
video_widevine_client::sdk::File file; video_widevine_client::sdk::File file;
if (!file.ParseFromString(serialized_file)) { if (!file.ParseFromString(serialized_file)) {
@@ -200,15 +200,12 @@ bool DeviceFiles::StoreLicense(const std::string& key_set_id,
return StoreFileWithHash(file_name.c_str(), serialized_file); return StoreFileWithHash(file_name.c_str(), serialized_file);
} }
bool DeviceFiles::RetrieveLicense(const std::string& key_set_id, bool DeviceFiles::RetrieveLicense(
LicenseState* state, CdmInitData* pssh_data, const std::string& key_set_id, LicenseState* state, CdmInitData* pssh_data,
CdmKeyMessage* license_request, CdmKeyMessage* license_request, CdmKeyResponse* license_message,
CdmKeyResponse* license_message, CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal,
CdmKeyMessage* license_renewal_request, std::string* release_server_url, int64_t* playback_start_time,
CdmKeyResponse* license_renewal, int64_t* last_playback_time) {
std::string* release_server_url,
int64_t* playback_start_time,
int64_t* last_playback_time) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::RetrieveLicense: not initialized"); LOGW("DeviceFiles::RetrieveLicense: not initialized");
return false; return false;
@@ -368,10 +365,8 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
provider_session->set_token(provider_session_token.data(), provider_session->set_token(provider_session_token.data(),
provider_session_token.size()); provider_session_token.size());
provider_session->set_license_request(key_request.data(), provider_session->set_license_request(key_request.data(), key_request.size());
key_request.size()); provider_session->set_license(key_response.data(), key_response.size());
provider_session->set_license(key_response.data(),
key_response.size());
file.SerializeToString(&serialized_file); file.SerializeToString(&serialized_file);
return StoreFileWithHash(file_name.c_str(), serialized_file); return StoreFileWithHash(file_name.c_str(), serialized_file);
@@ -398,15 +393,18 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
int index = 0; int index = 0;
bool found = false; bool found = false;
for (; index < usage_info->sessions_size(); ++index) { for (; index < usage_info->sessions_size(); ++index) {
if (usage_info->sessions(index).token().compare(provider_session_token) == 0) { if (usage_info->sessions(index).token().compare(provider_session_token) ==
0) {
found = true; found = true;
break; break;
} }
} }
if (!found) { if (!found) {
LOGW("DeviceFiles::DeleteUsageInfo: Unable to find provider session " LOGW(
"token: %s", b2a_hex(provider_session_token).c_str()); "DeviceFiles::DeleteUsageInfo: Unable to find provider session "
"token: %s",
b2a_hex(provider_session_token).c_str());
return false; return false;
} }
@@ -439,7 +437,7 @@ bool DeviceFiles::DeleteAllUsageInfoForApp(const std::string& app_id) {
} }
bool DeviceFiles::RetrieveUsageInfo( bool DeviceFiles::RetrieveUsageInfo(
const std::string &app_id, const std::string& app_id,
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info) { std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
@@ -447,7 +445,8 @@ bool DeviceFiles::RetrieveUsageInfo(
} }
if (NULL == usage_info) { if (NULL == usage_info) {
LOGW("DeviceFiles::RetrieveUsageInfo: license destination not " LOGW(
"DeviceFiles::RetrieveUsageInfo: license destination not "
"provided"); "provided");
return false; return false;
} }
@@ -581,24 +580,24 @@ bool DeviceFiles::StoreFileRaw(const char* name,
return false; return false;
} }
ssize_t bytes = file_->Write(serialized_file.data(), ssize_t bytes = file_->Write(serialized_file.data(), serialized_file.size());
serialized_file.size());
file_->Close(); file_->Close();
if (bytes != static_cast<ssize_t>(serialized_file.size())) { if (bytes != static_cast<ssize_t>(serialized_file.size())) {
LOGW("DeviceFiles::StoreFileRaw: write failed: (actual: %d, expected: %d)", LOGW(
bytes, "DeviceFiles::StoreFileRaw: write failed: (actual: %d, "
serialized_file.size()); "expected: %d)",
bytes, serialized_file.size());
return false; return false;
} }
LOGV("DeviceFiles::StoreFileRaw: success: %s (%db)", LOGV("DeviceFiles::StoreFileRaw: success: %s (%db)", path.c_str(),
path.c_str(), serialized_file.size());
serialized_file.size());
return true; return true;
} }
bool DeviceFiles::RetrieveHashedFile(const char* name, std::string* serialized_file) { bool DeviceFiles::RetrieveHashedFile(const char* name,
std::string* serialized_file) {
if (!file_.get()) { if (!file_.get()) {
LOGW("DeviceFiles::RetrieveHashedFile: Invalid file handle"); LOGW("DeviceFiles::RetrieveHashedFile: Invalid file handle");
return false; return false;
@@ -610,13 +609,15 @@ bool DeviceFiles::RetrieveHashedFile(const char* name, std::string* serialized_f
} }
if (!serialized_file) { if (!serialized_file) {
LOGW("DeviceFiles::RetrieveHashedFile: Unspecified serialized_file parameter"); LOGW(
"DeviceFiles::RetrieveHashedFile: Unspecified serialized_file "
"parameter");
return false; return false;
} }
std::string path; std::string path;
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) { if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
LOGW("DeviceFiles::StoreFile: Unable to get base path"); LOGW("DeviceFiles::StoreFileWithHash: Unable to get base path");
return false; return false;
} }
@@ -629,7 +630,8 @@ bool DeviceFiles::RetrieveHashedFile(const char* name, std::string* serialized_f
ssize_t bytes = file_->FileSize(path); ssize_t bytes = file_->FileSize(path);
if (bytes <= 0) { if (bytes <= 0) {
LOGW("DeviceFiles::RetrieveHashedFile: File size invalid: %s", path.c_str()); LOGW("DeviceFiles::RetrieveHashedFile: File size invalid: %s",
path.c_str());
// Remove the corrupted file so the caller will not get the same error // Remove the corrupted file so the caller will not get the same error
// when trying to access the file repeatedly, causing the system to stall. // when trying to access the file repeatedly, causing the system to stall.
file_->Remove(path); file_->Remove(path);
@@ -750,8 +752,10 @@ std::string DeviceFiles::GetLicenseFileNameExtension() {
} }
std::string DeviceFiles::GetUsageInfoFileName(const std::string& app_id) { std::string DeviceFiles::GetUsageInfoFileName(const std::string& app_id) {
if (app_id == "") return std::string(kUsageInfoFileNamePrefix) if (app_id == "") {
+ std::string(kUsageInfoFileNameExt); return std::string(kUsageInfoFileNamePrefix) +
std::string(kUsageInfoFileNameExt);
}
std::vector<uint8_t> hash(MD5_DIGEST_LENGTH); std::vector<uint8_t> hash(MD5_DIGEST_LENGTH);
const unsigned char* input = const unsigned char* input =
reinterpret_cast<const unsigned char*>(app_id.data()); reinterpret_cast<const unsigned char*>(app_id.data());

View File

@@ -27,56 +27,40 @@ std::string kBuildInfoKey = "build_info";
std::string kDeviceIdKey = "device_id"; std::string kDeviceIdKey = "device_id";
std::string kOsVersionKey = "os_version"; std::string kOsVersionKey = "os_version";
const unsigned char kServiceCertificateCAPublicKey[] = { const unsigned char kServiceCertificateCAPublicKey[] = {
0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xb4, 0xfe, 0x39,
0x00, 0xb4, 0xfe, 0x39, 0xc3, 0x65, 0x90, 0x03, 0xc3, 0x65, 0x90, 0x03, 0xdb, 0x3c, 0x11, 0x97, 0x09, 0xe8, 0x68, 0xcd,
0xdb, 0x3c, 0x11, 0x97, 0x09, 0xe8, 0x68, 0xcd, 0xf2, 0xc3, 0x5e, 0x9b, 0xf2, 0xe7, 0x4d, 0x23, 0xb1, 0x10, 0xdb, 0x87,
0xf2, 0xc3, 0x5e, 0x9b, 0xf2, 0xe7, 0x4d, 0x23, 0x65, 0xdf, 0xdc, 0xfb, 0x9f, 0x35, 0xa0, 0x57, 0x03, 0x53, 0x4c, 0xf6,
0xb1, 0x10, 0xdb, 0x87, 0x65, 0xdf, 0xdc, 0xfb, 0x6d, 0x35, 0x7d, 0xa6, 0x78, 0xdb, 0xb3, 0x36, 0xd2, 0x3f, 0x9c, 0x40,
0x9f, 0x35, 0xa0, 0x57, 0x03, 0x53, 0x4c, 0xf6, 0xa9, 0x95, 0x26, 0x72, 0x7f, 0xb8, 0xbe, 0x66, 0xdf, 0xc5, 0x21, 0x98,
0x6d, 0x35, 0x7d, 0xa6, 0x78, 0xdb, 0xb3, 0x36, 0x78, 0x15, 0x16, 0x68, 0x5d, 0x2f, 0x46, 0x0e, 0x43, 0xcb, 0x8a, 0x84,
0xd2, 0x3f, 0x9c, 0x40, 0xa9, 0x95, 0x26, 0x72, 0x39, 0xab, 0xfb, 0xb0, 0x35, 0x80, 0x22, 0xbe, 0x34, 0x23, 0x8b, 0xab,
0x7f, 0xb8, 0xbe, 0x66, 0xdf, 0xc5, 0x21, 0x98, 0x53, 0x5b, 0x72, 0xec, 0x4b, 0xb5, 0x48, 0x69, 0x53, 0x3e, 0x47, 0x5f,
0x78, 0x15, 0x16, 0x68, 0x5d, 0x2f, 0x46, 0x0e, 0xfd, 0x09, 0xfd, 0xa7, 0x76, 0x13, 0x8f, 0x0f, 0x92, 0xd6, 0x4c, 0xdf,
0x43, 0xcb, 0x8a, 0x84, 0x39, 0xab, 0xfb, 0xb0, 0xae, 0x76, 0xa9, 0xba, 0xd9, 0x22, 0x10, 0xa9, 0x9d, 0x71, 0x45, 0xd6,
0x35, 0x80, 0x22, 0xbe, 0x34, 0x23, 0x8b, 0xab, 0xd7, 0xe1, 0x19, 0x25, 0x85, 0x9c, 0x53, 0x9a, 0x97, 0xeb, 0x84, 0xd7,
0x53, 0x5b, 0x72, 0xec, 0x4b, 0xb5, 0x48, 0x69, 0xcc, 0xa8, 0x88, 0x82, 0x20, 0x70, 0x26, 0x20, 0xfd, 0x7e, 0x40, 0x50,
0x53, 0x3e, 0x47, 0x5f, 0xfd, 0x09, 0xfd, 0xa7, 0x27, 0xe2, 0x25, 0x93, 0x6f, 0xbc, 0x3e, 0x72, 0xa0, 0xfa, 0xc1, 0xbd,
0x76, 0x13, 0x8f, 0x0f, 0x92, 0xd6, 0x4c, 0xdf, 0x29, 0xb4, 0x4d, 0x82, 0x5c, 0xc1, 0xb4, 0xcb, 0x9c, 0x72, 0x7e, 0xb0,
0xae, 0x76, 0xa9, 0xba, 0xd9, 0x22, 0x10, 0xa9, 0xe9, 0x8a, 0x17, 0x3e, 0x19, 0x63, 0xfc, 0xfd, 0x82, 0x48, 0x2b, 0xb7,
0x9d, 0x71, 0x45, 0xd6, 0xd7, 0xe1, 0x19, 0x25, 0xb2, 0x33, 0xb9, 0x7d, 0xec, 0x4b, 0xba, 0x89, 0x1f, 0x27, 0xb8, 0x9b,
0x85, 0x9c, 0x53, 0x9a, 0x97, 0xeb, 0x84, 0xd7, 0x88, 0x48, 0x84, 0xaa, 0x18, 0x92, 0x0e, 0x65, 0xf5, 0xc8, 0x6c, 0x11,
0xcc, 0xa8, 0x88, 0x82, 0x20, 0x70, 0x26, 0x20, 0xff, 0x6b, 0x36, 0xe4, 0x74, 0x34, 0xca, 0x8c, 0x33, 0xb1, 0xf9, 0xb8,
0xfd, 0x7e, 0x40, 0x50, 0x27, 0xe2, 0x25, 0x93, 0x8e, 0xb4, 0xe6, 0x12, 0xe0, 0x02, 0x98, 0x79, 0x52, 0x5e, 0x45, 0x33,
0x6f, 0xbc, 0x3e, 0x72, 0xa0, 0xfa, 0xc1, 0xbd, 0xff, 0x11, 0xdc, 0xeb, 0xc3, 0x53, 0xba, 0x7c, 0x60, 0x1a, 0x11, 0x3d,
0x29, 0xb4, 0x4d, 0x82, 0x5c, 0xc1, 0xb4, 0xcb, 0x00, 0xfb, 0xd2, 0xb7, 0xaa, 0x30, 0xfa, 0x4f, 0x5e, 0x48, 0x77, 0x5b,
0x9c, 0x72, 0x7e, 0xb0, 0xe9, 0x8a, 0x17, 0x3e, 0x17, 0xdc, 0x75, 0xef, 0x6f, 0xd2, 0x19, 0x6d, 0xdc, 0xbe, 0x7f, 0xb0,
0x19, 0x63, 0xfc, 0xfd, 0x82, 0x48, 0x2b, 0xb7, 0x78, 0x8f, 0xdc, 0x82, 0x60, 0x4c, 0xbf, 0xe4, 0x29, 0x06, 0x5e, 0x69,
0xb2, 0x33, 0xb9, 0x7d, 0xec, 0x4b, 0xba, 0x89, 0x8c, 0x39, 0x13, 0xad, 0x14, 0x25, 0xed, 0x19, 0xb2, 0xf2, 0x9f, 0x01,
0x1f, 0x27, 0xb8, 0x9b, 0x88, 0x48, 0x84, 0xaa, 0x82, 0x0d, 0x56, 0x44, 0x88, 0xc8, 0x35, 0xec, 0x1f, 0x11, 0xb3, 0x24,
0x18, 0x92, 0x0e, 0x65, 0xf5, 0xc8, 0x6c, 0x11, 0xe0, 0x59, 0x0d, 0x37, 0xe4, 0x47, 0x3c, 0xea, 0x4b, 0x7f, 0x97, 0x31,
0xff, 0x6b, 0x36, 0xe4, 0x74, 0x34, 0xca, 0x8c, 0x1c, 0x81, 0x7c, 0x94, 0x8a, 0x4c, 0x7d, 0x68, 0x15, 0x84, 0xff, 0xa5,
0x33, 0xb1, 0xf9, 0xb8, 0x8e, 0xb4, 0xe6, 0x12, 0x08, 0xfd, 0x18, 0xe7, 0xe7, 0x2b, 0xe4, 0x47, 0x27, 0x12, 0x11, 0xb8,
0xe0, 0x02, 0x98, 0x79, 0x52, 0x5e, 0x45, 0x33, 0x23, 0xec, 0x58, 0x93, 0x3c, 0xac, 0x12, 0xd2, 0x88, 0x6d, 0x41, 0x3d,
0xff, 0x11, 0xdc, 0xeb, 0xc3, 0x53, 0xba, 0x7c, 0xc5, 0xfe, 0x1c, 0xdc, 0xb9, 0xf8, 0xd4, 0x51, 0x3e, 0x07, 0xe5, 0x03,
0x60, 0x1a, 0x11, 0x3d, 0x00, 0xfb, 0xd2, 0xb7, 0x6f, 0xa7, 0x12, 0xe8, 0x12, 0xf7, 0xb5, 0xce, 0xa6, 0x96, 0x55, 0x3f,
0xaa, 0x30, 0xfa, 0x4f, 0x5e, 0x48, 0x77, 0x5b, 0x78, 0xb4, 0x64, 0x82, 0x50, 0xd2, 0x33, 0x5f, 0x91, 0x02, 0x03, 0x01,
0x17, 0xdc, 0x75, 0xef, 0x6f, 0xd2, 0x19, 0x6d, 0x00, 0x01};
0xdc, 0xbe, 0x7f, 0xb0, 0x78, 0x8f, 0xdc, 0x82,
0x60, 0x4c, 0xbf, 0xe4, 0x29, 0x06, 0x5e, 0x69,
0x8c, 0x39, 0x13, 0xad, 0x14, 0x25, 0xed, 0x19,
0xb2, 0xf2, 0x9f, 0x01, 0x82, 0x0d, 0x56, 0x44,
0x88, 0xc8, 0x35, 0xec, 0x1f, 0x11, 0xb3, 0x24,
0xe0, 0x59, 0x0d, 0x37, 0xe4, 0x47, 0x3c, 0xea,
0x4b, 0x7f, 0x97, 0x31, 0x1c, 0x81, 0x7c, 0x94,
0x8a, 0x4c, 0x7d, 0x68, 0x15, 0x84, 0xff, 0xa5,
0x08, 0xfd, 0x18, 0xe7, 0xe7, 0x2b, 0xe4, 0x47,
0x27, 0x12, 0x11, 0xb8, 0x23, 0xec, 0x58, 0x93,
0x3c, 0xac, 0x12, 0xd2, 0x88, 0x6d, 0x41, 0x3d,
0xc5, 0xfe, 0x1c, 0xdc, 0xb9, 0xf8, 0xd4, 0x51,
0x3e, 0x07, 0xe5, 0x03, 0x6f, 0xa7, 0x12, 0xe8,
0x12, 0xf7, 0xb5, 0xce, 0xa6, 0x96, 0x55, 0x3f,
0x78, 0xb4, 0x64, 0x82, 0x50, 0xd2, 0x33, 0x5f,
0x91, 0x02, 0x03, 0x01, 0x00, 0x01};
} }
namespace wvcdm { namespace wvcdm {
@@ -145,14 +129,9 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
} }
CdmLicense::CdmLicense() CdmLicense::CdmLicense()
: session_(NULL), : session_(NULL), initialized_(false), clock_(new Clock()) {}
initialized_(false),
clock_(new Clock()) {
}
CdmLicense::CdmLicense(Clock* clock) CdmLicense::CdmLicense(Clock* clock) : session_(NULL), initialized_(false) {
: session_(NULL),
initialized_(false) {
if (NULL == clock) { if (NULL == clock) {
LOGE("CdmLicense::CdmLicense: clock parameter not provided"); LOGE("CdmLicense::CdmLicense: clock parameter not provided");
return; return;
@@ -481,9 +460,7 @@ bool CdmLicense::PrepareKeyRequest(const InitializationData& init_data,
} }
CdmResponseType CdmLicense::PrepareKeyUpdateRequest( CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
bool is_renewal, bool is_renewal, CdmKeyMessage* signed_request, std::string* server_url) {
CdmKeyMessage* signed_request,
std::string* server_url) {
if (!initialized_) { if (!initialized_) {
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized"); LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -512,21 +489,18 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
int64_t seconds_since_started, seconds_since_last_played; int64_t seconds_since_started, seconds_since_last_played;
CryptoSession::UsageDurationStatus usage_duration_status = CryptoSession::UsageDurationStatus usage_duration_status =
CryptoSession::kUsageDurationsInvalid; CryptoSession::kUsageDurationsInvalid;
if (!provider_session_token_.empty()) { if (!provider_session_token_.empty()) {
if (!is_renewal) { if (!is_renewal) {
CdmResponseType status = CdmResponseType status =
session_->DeactivateUsageInformation(provider_session_token_); session_->DeactivateUsageInformation(provider_session_token_);
if (NO_ERROR != status) if (NO_ERROR != status) return status;
return status;
} }
std::string usage_report; std::string usage_report;
CdmResponseType status = CdmResponseType status = session_->GenerateUsageReport(
session_->GenerateUsageReport(provider_session_token_, provider_session_token_, &usage_report, &usage_duration_status,
&usage_report, &usage_duration_status, &seconds_since_started, &seconds_since_last_played);
&seconds_since_started,
&seconds_since_last_played);
if (!is_renewal) { if (!is_renewal) {
if (NO_ERROR == status) if (NO_ERROR == status)
current_license->set_session_usage_table_entry(usage_report); current_license->set_session_usage_table_entry(usage_report);
@@ -611,8 +585,9 @@ CdmResponseType CdmLicense::HandleKeyResponse(
case SignedMessage::ERROR_RESPONSE: case SignedMessage::ERROR_RESPONSE:
return HandleKeyErrorResponse(signed_response); return HandleKeyErrorResponse(signed_response);
default: default:
LOGE("CdmLicense::HandleKeyResponse: unrecognized signed message type: %d" LOGE(
, signed_response.type()); "CdmLicense::HandleKeyResponse: unrecognized signed message type: %d",
signed_response.type());
return KEY_ERROR; return KEY_ERROR;
} }
@@ -675,18 +650,14 @@ CdmResponseType CdmLicense::HandleKeyResponse(
policy_engine_->SetLicense(license); policy_engine_->SetLicense(license);
CdmResponseType resp = session_->LoadKeys(signed_response.msg(), CdmResponseType resp = session_->LoadKeys(
signed_response.signature(), signed_response.msg(), signed_response.signature(), mac_key_iv, mac_key,
mac_key_iv, key_array, provider_session_token_);
mac_key,
key_array,
provider_session_token_);
if (KEY_ADDED == resp) { if (KEY_ADDED == resp) {
loaded_keys_.clear(); loaded_keys_.clear();
for (std::vector<CryptoKey>::iterator it = key_array.begin(); for (std::vector<CryptoKey>::iterator it = key_array.begin();
it != key_array.end(); it != key_array.end(); ++it) {
++it) {
loaded_keys_.insert(it->key_id()); loaded_keys_.insert(it->key_id());
} }
} }
@@ -738,10 +709,9 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
if (!license.id().has_provider_session_token()) return KEY_ADDED; if (!license.id().has_provider_session_token()) return KEY_ADDED;
provider_session_token_ = license.id().provider_session_token(); provider_session_token_ = license.id().provider_session_token();
CdmResponseType status = CdmResponseType status = session_->ReleaseUsageInformation(
session_->ReleaseUsageInformation(signed_response.msg(), signed_response.msg(), signed_response.signature(),
signed_response.signature(), provider_session_token_);
provider_session_token_);
return (NO_ERROR == status) ? KEY_ADDED : status; return (NO_ERROR == status) ? KEY_ADDED : status;
} }
@@ -763,8 +733,7 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
bool CdmLicense::RestoreOfflineLicense( bool CdmLicense::RestoreOfflineLicense(
const CdmKeyMessage& license_request, const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response, const CdmKeyResponse& license_response,
const CdmKeyResponse& license_renewal_response, const CdmKeyResponse& license_renewal_response, int64_t playback_start_time,
int64_t playback_start_time,
int64_t last_playback_time) { int64_t last_playback_time) {
if (license_request.empty() || license_response.empty()) { if (license_request.empty() || license_response.empty()) {
LOGE( LOGE(
@@ -810,8 +779,8 @@ bool CdmLicense::RestoreOfflineLicense(
CryptoSession::kUsageDurationsInvalid; CryptoSession::kUsageDurationsInvalid;
int64_t seconds_since_started, seconds_since_last_played; int64_t seconds_since_started, seconds_since_last_played;
sts = session_->GenerateUsageReport( sts = session_->GenerateUsageReport(
provider_session_token_, &usage_report, &usage_duration_status, provider_session_token_, &usage_report, &usage_duration_status,
&seconds_since_started, &seconds_since_last_played); &seconds_since_started, &seconds_since_last_played);
if (NO_ERROR == sts) { if (NO_ERROR == sts) {
switch (usage_duration_status) { switch (usage_duration_status) {
@@ -840,7 +809,6 @@ bool CdmLicense::RestoreOfflineLicense(
bool CdmLicense::RestoreLicenseForRelease( bool CdmLicense::RestoreLicenseForRelease(
const CdmKeyMessage& license_request, const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response) { const CdmKeyResponse& license_response) {
if (license_request.empty() || license_response.empty()) { if (license_request.empty() || license_response.empty()) {
LOGE( LOGE(
"CdmLicense::RestoreLicenseForRelease: key_request or response empty:" "CdmLicense::RestoreLicenseForRelease: key_request or response empty:"
@@ -872,27 +840,26 @@ bool CdmLicense::RestoreLicenseForRelease(
SignedMessage signed_response; SignedMessage signed_response;
if (!signed_response.ParseFromString(license_response)) { if (!signed_response.ParseFromString(license_response)) {
LOGE("CdmLicense::RestoreLicenseForRelease: unable to parse signed license" LOGE("CdmLicense::RestoreLicenseForRelease: unable to parse signed license"
" response"); " response");
return false; return false;
} }
if (SignedMessage::LICENSE != signed_response.type()) { if (SignedMessage::LICENSE != signed_response.type()) {
LOGE("CdmLicense::RestoreLicenseForRelease: unrecognized signed message " LOGE("CdmLicense::RestoreLicenseForRelease: unrecognized signed message "
"type: %d" "type: %d", signed_response.type());
, signed_response.type());
return false; return false;
} }
if (!signed_response.has_signature()) { if (!signed_response.has_signature()) {
LOGE("CdmLicense::RestoreLicenseForRelease: license response is not" LOGE("CdmLicense::RestoreLicenseForRelease: license response is not"
" signed"); " signed");
return false; return false;
} }
License license; License license;
if (!license.ParseFromString(signed_response.msg())) { if (!license.ParseFromString(signed_response.msg())) {
LOGE("CdmLicense::RestoreLicenseForRelease: unable to parse license" LOGE("CdmLicense::RestoreLicenseForRelease: unable to parse license"
" response"); " response");
return false; return false;
} }
@@ -953,7 +920,6 @@ bool CdmLicense::PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
CdmResponseType CdmLicense::HandleServiceCertificateResponse( CdmResponseType CdmLicense::HandleServiceCertificateResponse(
const video_widevine_server::sdk::SignedMessage& signed_response) { const video_widevine_server::sdk::SignedMessage& signed_response) {
SignedDeviceCertificate signed_service_certificate; SignedDeviceCertificate signed_service_certificate;
if (!signed_service_certificate.ParseFromString(signed_response.msg())) { if (!signed_service_certificate.ParseFromString(signed_response.msg())) {
LOGE( LOGE(
@@ -1006,7 +972,6 @@ CdmResponseType CdmLicense::HandleServiceCertificateResponse(
CdmResponseType CdmLicense::HandleKeyErrorResponse( CdmResponseType CdmLicense::HandleKeyErrorResponse(
const SignedMessage& signed_message) { const SignedMessage& signed_message) {
LicenseError license_error; LicenseError license_error;
if (!license_error.ParseFromString(signed_message.msg())) { if (!license_error.ParseFromString(signed_message.msg())) {
LOGE("CdmLicense::HandleKeyErrorResponse: Unable to parse license error"); LOGE("CdmLicense::HandleKeyErrorResponse: Unable to parse license error");
@@ -1026,7 +991,7 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse(
} }
} }
template<typename T> template <typename T>
bool CdmLicense::PrepareContentId(const CdmLicenseType license_type, bool CdmLicense::PrepareContentId(const CdmLicenseType license_type,
const std::string& request_id, const std::string& request_id,
T* content_id) { T* content_id) {
@@ -1035,8 +1000,7 @@ bool CdmLicense::PrepareContentId(const CdmLicenseType license_type,
content_id->set_license_type(video_widevine_server::sdk::OFFLINE); content_id->set_license_type(video_widevine_server::sdk::OFFLINE);
break; break;
case kLicenseTypeStreaming: case kLicenseTypeStreaming:
content_id->set_license_type( content_id->set_license_type(video_widevine_server::sdk::STREAMING);
video_widevine_server::sdk::STREAMING);
break; break;
default: default:
LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d", LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d",

View File

@@ -11,15 +11,16 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <stdio.h> #include <stdio.h>
#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include "level3.h" #include <cstring>
#include "log.h" #include <iostream>
#include "lock.h" #include <map>
#include <string>
#include "file_store.h" #include "file_store.h"
#include "level3.h"
#include "lock.h"
#include "log.h"
#include "properties.h" #include "properties.h"
using namespace wvoec3; using namespace wvoec3;
@@ -45,8 +46,8 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
const uint8_t* pst, size_t pst_length); size_t pst_length);
typedef OEMCryptoResult (*L1_LoadKeys_V8_t)( typedef OEMCryptoResult (*L1_LoadKeys_V8_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
@@ -87,17 +88,13 @@ typedef OEMCryptoResult (*L1_RewrapDeviceRSAKey_t)(
typedef OEMCryptoResult (*L1_LoadDeviceRSAKey_t)(OEMCrypto_SESSION session, typedef OEMCryptoResult (*L1_LoadDeviceRSAKey_t)(OEMCrypto_SESSION session,
const uint8_t* wrapped_rsa_key, const uint8_t* wrapped_rsa_key,
size_t wrapped_rsa_key_length); size_t wrapped_rsa_key_length);
typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(OEMCrypto_SESSION session, typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(
const uint8_t* message, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t message_length, uint8_t* signature, size_t* signature_length,
uint8_t* signature, RSA_Padding_Scheme padding_scheme);
size_t* signature_length, typedef OEMCryptoResult (*L1_GenerateRSASignature_V8_t)(
RSA_Padding_Scheme padding_scheme); OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
typedef OEMCryptoResult (*L1_GenerateRSASignature_V8_t)(OEMCrypto_SESSION session, uint8_t* signature, size_t* signature_length);
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length);
typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)( typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)(
OEMCrypto_SESSION session, const uint8_t* enc_session_key, OEMCrypto_SESSION session, const uint8_t* enc_session_key,
size_t enc_session_key_length, const uint8_t* mac_key_context, size_t enc_session_key_length, const uint8_t* mac_key_context,
@@ -125,24 +122,21 @@ typedef OEMCryptoResult (*L1_Generic_Verify_t)(OEMCrypto_SESSION session,
size_t signature_length); size_t signature_length);
typedef uint32_t (*L1_APIVersion_t)(); typedef uint32_t (*L1_APIVersion_t)();
typedef const char* (*L1_SecurityLevel_t)(); typedef const char* (*L1_SecurityLevel_t)();
typedef OEMCryptoResult (*L1_GetHDCPCapability_t)(OEMCrypto_HDCP_Capability *current, typedef OEMCryptoResult (*L1_GetHDCPCapability_t)(
OEMCrypto_HDCP_Capability *maximum); OEMCrypto_HDCP_Capability* current, OEMCrypto_HDCP_Capability* maximum);
typedef bool (*L1_SupportsUsageTable_t)(); typedef bool (*L1_SupportsUsageTable_t)();
typedef OEMCryptoResult (*L1_UpdateUsageTable_t)(); typedef OEMCryptoResult (*L1_UpdateUsageTable_t)();
typedef OEMCryptoResult (*L1_DeactivateUsageEntry_t)(const uint8_t *pst, typedef OEMCryptoResult (*L1_DeactivateUsageEntry_t)(const uint8_t* pst,
size_t pst_length); size_t pst_length);
typedef OEMCryptoResult (*L1_ReportUsage_t)(OEMCrypto_SESSION session, typedef OEMCryptoResult (*L1_ReportUsage_t)(OEMCrypto_SESSION session,
const uint8_t *pst, const uint8_t* pst,
size_t pst_length, size_t pst_length,
OEMCrypto_PST_Report *buffer, OEMCrypto_PST_Report* buffer,
size_t *buffer_length); size_t* buffer_length);
typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(OEMCrypto_SESSION session, typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(
const uint8_t* pst, OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
size_t pst_length, const uint8_t* message, size_t message_length, const uint8_t* signature,
const uint8_t *message, size_t signature_length);
size_t message_length,
const uint8_t *signature,
size_t signature_length);
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)(); typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
struct FunctionPointers { struct FunctionPointers {
@@ -194,13 +188,12 @@ struct LevelSession {
#define QUOTE_DEFINE(A) #A #define QUOTE_DEFINE(A) #A
#define QUOTE(A) QUOTE_DEFINE(A) #define QUOTE(A) QUOTE_DEFINE(A)
#define LOOKUP(Name, Function) \ #define LOOKUP(Name, Function) \
level1_.Name = \ level1_.Name = (L1_##Name##_t)dlsym(level1_library_, QUOTE(Function)); \
(L1_##Name##_t)dlsym(level1_library_, QUOTE(Function)); \ if (!level1_.Name) { \
if (!level1_.Name) { \ LOGW("Could not load L1 %s. Falling Back to L3.", \
LOGW("Could not load L1 %s. Falling Back to L3.", \ QUOTE(OEMCrypto_##Name)); \
QUOTE(OEMCrypto_##Name)); \ return false; \
return false; \
} }
class Adapter { class Adapter {
@@ -283,19 +276,19 @@ class Adapter {
level1_.Terminate(); level1_.Terminate();
return false; return false;
} }
if( level1_.version == 8 ) { if (level1_.version == 8) {
LOOKUP(LoadKeys_V8, OEMCrypto_LoadKeys_V8); LOOKUP(LoadKeys_V8, OEMCrypto_LoadKeys_V8);
LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature_V8); LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature_V8);
} else { } else {
LOOKUP(LoadKeys, OEMCrypto_LoadKeys); LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature); LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature);
LOOKUP(GetHDCPCapability, OEMCrypto_GetHDCPCapability); LOOKUP(GetHDCPCapability, OEMCrypto_GetHDCPCapability);
LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable); LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable);
LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable); LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable);
LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry); LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry);
LOOKUP(ReportUsage, OEMCrypto_ReportUsage); LOOKUP(ReportUsage, OEMCrypto_ReportUsage);
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry); LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable); LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable);
} }
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) { if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
return true; return true;
@@ -434,6 +427,7 @@ class Adapter {
// id will match the internal session id in the last two digits. // id will match the internal session id in the last two digits.
static const OEMCrypto_SESSION kLevel3Offset = 25600; static const OEMCrypto_SESSION kLevel3Offset = 25600;
}; };
static Adapter* kAdapter = 0; static Adapter* kAdapter = 0;
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) { extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
@@ -503,15 +497,15 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
const uint8_t* pst, size_t pst_length) { size_t pst_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version == 8) { if (pair.fcn->version == 8) {
return pair.fcn->LoadKeys_V8(pair.session, message, message_length, signature, return pair.fcn->LoadKeys_V8(pair.session, message, message_length,
signature_length, enc_mac_key_iv, enc_mac_key, signature, signature_length, enc_mac_key_iv,
num_keys, key_array); enc_mac_key, num_keys, key_array);
} else { } else {
return pair.fcn->LoadKeys(pair.session, message, message_length, signature, return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key, signature_length, enc_mac_key_iv, enc_mac_key,
@@ -644,19 +638,20 @@ extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
return pair.fcn return pair.fcn->LoadDeviceRSAKey(pair.session, wrapped_rsa_key,
->LoadDeviceRSAKey(pair.session, wrapped_rsa_key, wrapped_rsa_key_length); wrapped_rsa_key_length);
} }
extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature( extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme) { uint8_t* signature, size_t* signature_length,
RSA_Padding_Scheme padding_scheme) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version == 8) { if (pair.fcn->version == 8) {
return pair.fcn->GenerateRSASignature_V8(pair.session, message, message_length, return pair.fcn->GenerateRSASignature_V8(
signature, signature_length); pair.session, message, message_length, signature, signature_length);
} else { } else {
return pair.fcn->GenerateRSASignature(pair.session, message, message_length, return pair.fcn->GenerateRSASignature(pair.session, message, message_length,
signature, signature_length, signature, signature_length,
@@ -702,7 +697,6 @@ const char* OEMCrypto_SecurityLevel(SecurityLevel level) {
extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt( extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) { const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
@@ -744,13 +738,12 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Verify(
algorithm, signature, signature_length); algorithm, signature, signature_length);
} }
extern "C" extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability(
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, OEMCrypto_HDCP_Capability* current, OEMCrypto_HDCP_Capability* maximum) {
OEMCrypto_HDCP_Capability *maximum) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(kLevelDefault); const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( fcn->version == 8 ) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (fcn->version == 8) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->GetHDCPCapability(current, maximum); return fcn->GetHDCPCapability(current, maximum);
} }
@@ -776,7 +769,7 @@ extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
return sts; return sts;
} }
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst,
size_t pst_length) { size_t pst_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault); const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
@@ -794,32 +787,29 @@ extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
} }
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t *pst, const uint8_t* pst,
size_t pst_length, size_t pst_length,
OEMCrypto_PST_Report *buffer, OEMCrypto_PST_Report* buffer,
size_t *buffer_length) { size_t* buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( pair.fcn->version > 8 ) { if (pair.fcn->version > 8) {
return pair.fcn->ReportUsage(pair.session, pst, pst_length,buffer, return pair.fcn->ReportUsage(pair.session, pst, pst_length, buffer,
buffer_length); buffer_length);
} else { } else {
return OEMCrypto_ERROR_NOT_IMPLEMENTED; return OEMCrypto_ERROR_NOT_IMPLEMENTED;
} }
} }
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(
const uint8_t* pst, OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
size_t pst_length, const uint8_t* message, size_t message_length, const uint8_t* signature,
const uint8_t *message, size_t signature_length) {
size_t message_length,
const uint8_t *signature,
size_t signature_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( pair.fcn->version > 8 ) { if (pair.fcn->version > 8) {
return pair.fcn->DeleteUsageEntry(pair.session, pst, pst_length, message, return pair.fcn->DeleteUsageEntry(pair.session, pst, pst_length, message,
message_length, signature, message_length, signature,
signature_length); signature_length);

View File

@@ -27,8 +27,7 @@ PolicyEngine::PolicyEngine(CryptoSession* crypto_session, Clock* clock)
} }
PolicyEngine::~PolicyEngine() { PolicyEngine::~PolicyEngine() {
if (clock_) if (clock_) delete clock_;
delete clock_;
} }
void PolicyEngine::Init(Clock* clock) { void PolicyEngine::Init(Clock* clock) {
@@ -52,7 +51,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
// License expiration trumps all. // License expiration trumps all.
if ((IsLicenseDurationExpired(current_time) || if ((IsLicenseDurationExpired(current_time) ||
IsPlaybackDurationExpired(current_time)) && IsPlaybackDurationExpired(current_time)) &&
license_state_ != kLicenseStateExpired) { license_state_ != kLicenseStateExpired) {
license_state_ = kLicenseStateExpired; license_state_ = kLicenseStateExpired;
can_decrypt_ = false; can_decrypt_ = false;
@@ -66,8 +65,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
// Test to determine if renewal should be attempted. // Test to determine if renewal should be attempted.
switch (license_state_) { switch (license_state_) {
case kLicenseStateCanPlay: { case kLicenseStateCanPlay: {
if (IsRenewalDelayExpired(current_time)) if (IsRenewalDelayExpired(current_time)) renewal_needed = true;
renewal_needed = true;
break; break;
} }
@@ -77,8 +75,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
} }
case kLicenseStateWaitingLicenseUpdate: { case kLicenseStateWaitingLicenseUpdate: {
if (IsRenewalRetryIntervalExpired(current_time)) if (IsRenewalRetryIntervalExpired(current_time)) renewal_needed = true;
renewal_needed = true;
break; break;
} }
@@ -122,8 +119,7 @@ void PolicyEngine::SetLicense(
void PolicyEngine::UpdateLicense( void PolicyEngine::UpdateLicense(
const video_widevine_server::sdk::License& license) { const video_widevine_server::sdk::License& license) {
if (!license.has_policy()) if (!license.has_policy()) return;
return;
if (kLicenseStateExpired == license_state_) { if (kLicenseStateExpired == license_state_) {
LOGD("PolicyEngine::UpdateLicense: updating an expired license"); LOGD("PolicyEngine::UpdateLicense: updating an expired license");
@@ -157,15 +153,13 @@ void PolicyEngine::UpdateLicense(
policy_max_duration_seconds_ = policy_.rental_duration_seconds(); policy_max_duration_seconds_ = policy_.rental_duration_seconds();
if ((policy_.license_duration_seconds() > 0) && if ((policy_.license_duration_seconds() > 0) &&
((policy_.license_duration_seconds() < ((policy_.license_duration_seconds() < policy_max_duration_seconds_) ||
policy_max_duration_seconds_) ||
policy_max_duration_seconds_ == 0)) { policy_max_duration_seconds_ == 0)) {
policy_max_duration_seconds_ = policy_.license_duration_seconds(); policy_max_duration_seconds_ = policy_.license_duration_seconds();
} }
int64_t current_time = clock_->GetCurrentTime(); int64_t current_time = clock_->GetCurrentTime();
if (!policy_.can_play() || if (!policy_.can_play() || IsLicenseDurationExpired(current_time) ||
IsLicenseDurationExpired(current_time) ||
IsPlaybackDurationExpired(current_time)) { IsPlaybackDurationExpired(current_time)) {
license_state_ = kLicenseStateExpired; license_state_ = kLicenseStateExpired;
return; return;
@@ -221,14 +215,15 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) {
} }
(*key_info)[QUERY_KEY_LICENSE_TYPE] = (*key_info)[QUERY_KEY_LICENSE_TYPE] =
license_id_.type() == video_widevine_server::sdk::STREAMING ? license_id_.type() == video_widevine_server::sdk::STREAMING
QUERY_VALUE_STREAMING : QUERY_VALUE_OFFLINE; ? QUERY_VALUE_STREAMING
(*key_info)[QUERY_KEY_PLAY_ALLOWED] = policy_.can_play() ? : QUERY_VALUE_OFFLINE;
QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; (*key_info)[QUERY_KEY_PLAY_ALLOWED] =
(*key_info)[QUERY_KEY_PERSIST_ALLOWED] = policy_.can_persist() ? policy_.can_play() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; (*key_info)[QUERY_KEY_PERSIST_ALLOWED] =
(*key_info)[QUERY_KEY_RENEW_ALLOWED] = policy_.can_renew() ? policy_.can_persist() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; (*key_info)[QUERY_KEY_RENEW_ALLOWED] =
policy_.can_renew() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
ss << GetLicenseDurationRemaining(current_time); ss << GetLicenseDurationRemaining(current_time);
(*key_info)[QUERY_KEY_LICENSE_DURATION_REMAINING] = ss.str(); (*key_info)[QUERY_KEY_LICENSE_DURATION_REMAINING] = ss.str();
ss.str(""); ss.str("");
@@ -270,15 +265,14 @@ void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
// will always return false if the value is 0. // will always return false if the value is 0.
bool PolicyEngine::IsLicenseDurationExpired(int64_t current_time) { bool PolicyEngine::IsLicenseDurationExpired(int64_t current_time) {
return policy_max_duration_seconds_ && return policy_max_duration_seconds_ &&
license_start_time_ + policy_max_duration_seconds_ <= license_start_time_ + policy_max_duration_seconds_ <= current_time;
current_time;
} }
int64_t PolicyEngine::GetLicenseDurationRemaining(int64_t current_time) { int64_t PolicyEngine::GetLicenseDurationRemaining(int64_t current_time) {
if (0 == policy_max_duration_seconds_) return LLONG_MAX; if (0 == policy_max_duration_seconds_) return LLONG_MAX;
int64_t remaining_time = policy_max_duration_seconds_ int64_t remaining_time =
+ license_start_time_ - current_time; policy_max_duration_seconds_ + license_start_time_ - current_time;
if (remaining_time < 0) if (remaining_time < 0)
remaining_time = 0; remaining_time = 0;
@@ -288,43 +282,38 @@ int64_t PolicyEngine::GetLicenseDurationRemaining(int64_t current_time) {
} }
bool PolicyEngine::IsPlaybackDurationExpired(int64_t current_time) { bool PolicyEngine::IsPlaybackDurationExpired(int64_t current_time) {
return (policy_.playback_duration_seconds() > 0) && return (policy_.playback_duration_seconds() > 0) && playback_start_time_ &&
playback_start_time_ && playback_start_time_ + policy_.playback_duration_seconds() <=
playback_start_time_ + policy_.playback_duration_seconds() <= current_time;
current_time;
} }
int64_t PolicyEngine::GetPlaybackDurationRemaining(int64_t current_time) { int64_t PolicyEngine::GetPlaybackDurationRemaining(int64_t current_time) {
if (0 == policy_.playback_duration_seconds()) return LLONG_MAX; if (0 == policy_.playback_duration_seconds()) return LLONG_MAX;
if (0 == playback_start_time_) return policy_.playback_duration_seconds(); if (0 == playback_start_time_) return policy_.playback_duration_seconds();
int64_t remaining_time = policy_.playback_duration_seconds() int64_t remaining_time =
+ playback_start_time_ - current_time; policy_.playback_duration_seconds() + playback_start_time_ - current_time;
if (remaining_time < 0) remaining_time = 0; if (remaining_time < 0) remaining_time = 0;
return remaining_time; return remaining_time;
} }
bool PolicyEngine::IsRenewalDelayExpired(int64_t current_time) { bool PolicyEngine::IsRenewalDelayExpired(int64_t current_time) {
return policy_.can_renew() && return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) &&
(policy_.renewal_delay_seconds() > 0) && license_start_time_ + policy_.renewal_delay_seconds() <= current_time;
license_start_time_ + policy_.renewal_delay_seconds() <=
current_time;
} }
bool PolicyEngine::IsRenewalRecoveryDurationExpired( bool PolicyEngine::IsRenewalRecoveryDurationExpired(int64_t current_time) {
int64_t current_time) { // NOTE: Renewal Recovery Duration is currently not used.
// NOTE: Renewal Recovery Duration is currently not used.
return (policy_.renewal_recovery_duration_seconds() > 0) && return (policy_.renewal_recovery_duration_seconds() > 0) &&
license_start_time_ + policy_.renewal_recovery_duration_seconds() <= license_start_time_ + policy_.renewal_recovery_duration_seconds() <=
current_time; current_time;
} }
bool PolicyEngine::IsRenewalRetryIntervalExpired( bool PolicyEngine::IsRenewalRetryIntervalExpired(int64_t current_time) {
int64_t current_time) {
return policy_.can_renew() && return policy_.can_renew() &&
(policy_.renewal_retry_interval_seconds() > 0) && (policy_.renewal_retry_interval_seconds() > 0) &&
next_renewal_time_ <= current_time; next_renewal_time_ <= current_time;
} }
} // wvcdm } // wvcdm

View File

@@ -13,9 +13,7 @@ AesCbcKey::AesCbcKey() {}
AesCbcKey::~AesCbcKey() {} AesCbcKey::~AesCbcKey() {}
bool AesCbcKey::Init(const std::string& key) { bool AesCbcKey::Init(const std::string& key) { return false; }
return false;
}
bool AesCbcKey::Encrypt(const std::string& in, std::string* out, bool AesCbcKey::Encrypt(const std::string& in, std::string* out,
std::string* iv) { std::string* iv) {
@@ -26,9 +24,7 @@ RsaPublicKey::RsaPublicKey() {}
RsaPublicKey::~RsaPublicKey() {} RsaPublicKey::~RsaPublicKey() {}
bool RsaPublicKey::Init(const std::string& serialized_key) { bool RsaPublicKey::Init(const std::string& serialized_key) { return false; }
return false;
}
bool RsaPublicKey::Encrypt(const std::string& clear_message, bool RsaPublicKey::Encrypt(const std::string& clear_message,
std::string* encrypted_message) { std::string* encrypted_message) {

View File

@@ -43,7 +43,8 @@ std::vector<uint8_t> a2b_hex(const std::string& byte) {
unsigned char lsb = 0; // least significant 4 bits unsigned char lsb = 0; // least significant 4 bits
if (!CharToDigit(byte[i * 2], &msb) || if (!CharToDigit(byte[i * 2], &msb) ||
!CharToDigit(byte[i * 2 + 1], &lsb)) { !CharToDigit(byte[i * 2 + 1], &lsb)) {
LOGE("Invalid hex value %c%c at index %d", byte[i*2], byte[i*2+1], i); LOGE("Invalid hex value %c%c at index %d", byte[i * 2], byte[i * 2 + 1],
i);
return array; return array;
} }
array.push_back((msb << 4) | lsb); array.push_back((msb << 4) | lsb);
@@ -53,10 +54,11 @@ std::vector<uint8_t> a2b_hex(const std::string& byte) {
// converts an ascii hex string(2 bytes per digit) into a decimal byte string // converts an ascii hex string(2 bytes per digit) into a decimal byte string
// dump the string with the label. // dump the string with the label.
std::vector<uint8_t> a2b_hex(const std::string& label, const std::string& byte) { std::vector<uint8_t> a2b_hex(const std::string& label,
const std::string& byte) {
std::cout << std::endl << "[[DUMP: " << label << " ]= \"" << byte << "\"]" std::cout << std::endl
<< std::endl << std::endl; << "[[DUMP: " << label << " ]= \"" << byte << "\"]" << std::endl
<< std::endl;
return a2b_hex(byte); return a2b_hex(byte);
} }
@@ -71,7 +73,7 @@ std::string b2a_hex(const std::vector<uint8_t>& byte) {
} }
std::string b2a_hex(const std::string& byte) { std::string b2a_hex(const std::string& byte) {
return HexEncode(reinterpret_cast<const uint8_t *>(byte.data()), return HexEncode(reinterpret_cast<const uint8_t*>(byte.data()),
byte.length()); byte.length());
} }
@@ -90,9 +92,8 @@ std::string Base64SafeEncode(const std::vector<uint8_t>& bin_input) {
int in_size = bin_input.size(); int in_size = bin_input.size();
std::string b64_output(modp_b64w_encode_len(in_size), 0); std::string b64_output(modp_b64w_encode_len(in_size), 0);
int out_size = modp_b64w_encode(&b64_output[0], int out_size = modp_b64w_encode(
reinterpret_cast<const char*>(&bin_input[0]), &b64_output[0], reinterpret_cast<const char*>(&bin_input[0]), in_size);
in_size);
if (out_size == -1) { if (out_size == -1) {
LOGE("Base64SafeEncode failed"); LOGE("Base64SafeEncode failed");
return std::string(); return std::string();
@@ -119,8 +120,7 @@ std::vector<uint8_t> Base64SafeDecode(const std::string& b64_input) {
int in_size = b64_input.size(); int in_size = b64_input.size();
std::vector<uint8_t> bin_output(modp_b64w_decode_len(in_size), 0); std::vector<uint8_t> bin_output(modp_b64w_decode_len(in_size), 0);
int out_size = modp_b64w_decode(reinterpret_cast<char*>(&bin_output[0]), int out_size = modp_b64w_decode(reinterpret_cast<char*>(&bin_output[0]),
b64_input.data(), b64_input.data(), in_size);
in_size);
if (out_size == -1) { if (out_size == -1) {
LOGE("Base64SafeDecode failed"); LOGE("Base64SafeDecode failed");
return std::vector<uint8_t>(0); return std::vector<uint8_t>(0);

View File

@@ -38,28 +38,28 @@ const std::string kTwoBytesOverB64Data("SGVsbG8gRnJpZW5kISE=");
const std::string kB64TestData = "GPFc9rc-INmI8FwtyTrUrv6xnKHWZNZ_5uaT21nFjNg="; const std::string kB64TestData = "GPFc9rc-INmI8FwtyTrUrv6xnKHWZNZ_5uaT21nFjNg=";
const std::pair<const std::string*, const std::string*> kBase64TestVectors[] = { const std::pair<const std::string*, const std::string*> kBase64TestVectors[] = {
make_pair(&kNullString, &kNullString), make_pair(&kNullString, &kNullString),
make_pair(&kf, &kfB64), make_pair(&kf, &kfB64),
make_pair(&kfo, &kfoB64), make_pair(&kfo, &kfoB64),
make_pair(&kfoo, &kfooB64), make_pair(&kfoo, &kfooB64),
make_pair(&kfoob, &kfoobB64), make_pair(&kfoob, &kfoobB64),
make_pair(&kfooba, &kfoobaB64), make_pair(&kfooba, &kfoobaB64),
make_pair(&kfoobar, &kfoobarB64), make_pair(&kfoobar, &kfoobarB64),
make_pair(&kMultipleOf24BitsData, &kMultipleOf24BitsB64Data), make_pair(&kMultipleOf24BitsData, &kMultipleOf24BitsB64Data),
make_pair(&kOneByteOverData, &kOneByteOverB64Data), make_pair(&kOneByteOverData, &kOneByteOverB64Data),
make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data), make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data),
make_pair(&kTestData, &kB64TestData), make_pair(&kTestData, &kB64TestData)};
};
} // unnamed namespace } // unnamed namespace
namespace wvcdm { namespace wvcdm {
class Base64EncodeDecodeTest : public ::testing::TestWithParam< class Base64EncodeDecodeTest
std::pair<const std::string*, const std::string*> > {}; : public ::testing::TestWithParam<
std::pair<const std::string*, const std::string*> > {};
TEST_P(Base64EncodeDecodeTest, EncodeDecodeTest) { TEST_P(Base64EncodeDecodeTest, EncodeDecodeTest) {
std::pair<const std::string*, const std::string*> values = GetParam(); std::pair<const std::string *, const std::string *> values = GetParam();
std::vector<uint8_t> decoded_vector = Base64SafeDecode(values.second->data()); std::vector<uint8_t> decoded_vector = Base64SafeDecode(values.second->data());
std::string decoded_string(decoded_vector.begin(), decoded_vector.end()); std::string decoded_string(decoded_vector.begin(), decoded_vector.end());
EXPECT_STREQ(values.first->data(), decoded_string.data()); EXPECT_STREQ(values.first->data(), decoded_string.data());

View File

@@ -46,7 +46,8 @@ namespace wvcdm {
class WvCdmEngineTest : public testing::Test { class WvCdmEngineTest : public testing::Test {
public: public:
virtual void SetUp() { virtual void SetUp() {
CdmResponseType status = cdm_engine_.OpenSession(g_key_system, NULL, &session_id_); CdmResponseType status =
cdm_engine_.OpenSession(g_key_system, NULL, &session_id_);
if (status == NEED_PROVISIONING) { if (status == NEED_PROVISIONING) {
Provision(); Provision();
status = cdm_engine_.OpenSession(g_key_system, NULL, &session_id_); status = cdm_engine_.OpenSession(g_key_system, NULL, &session_id_);
@@ -64,19 +65,16 @@ class WvCdmEngineTest : public testing::Test {
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority; std::string cert_authority;
std::string cert, wrapped_key; std::string cert, wrapped_key;
ASSERT_EQ(NO_ERROR, ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
cdm_engine_.GetProvisioningRequest(cert_type, cert_type, cert_authority, &prov_request,
cert_authority, &provisioning_server_url));
&prov_request,
&provisioning_server_url));
UrlRequest url_request(provisioning_server_url); UrlRequest url_request(provisioning_server_url);
url_request.PostCertRequestInQueryString(prov_request); url_request.PostCertRequestInQueryString(prov_request);
std::string message; std::string message;
bool ok = url_request.GetResponse(&message); bool ok = url_request.GetResponse(&message);
EXPECT_TRUE(ok); EXPECT_TRUE(ok);
ASSERT_EQ(NO_ERROR, ASSERT_EQ(NO_ERROR, cdm_engine_.HandleProvisioningResponse(message, &cert,
cdm_engine_.HandleProvisioningResponse(message, &wrapped_key));
&cert, &wrapped_key));
} }
void GenerateKeyRequest(const std::string& key_id, void GenerateKeyRequest(const std::string& key_id,
@@ -88,27 +86,21 @@ class WvCdmEngineTest : public testing::Test {
InitializationData init_data(init_data_type_string, key_id); InitializationData init_data(init_data_type_string, key_id);
EXPECT_EQ(KEY_MESSAGE, EXPECT_EQ(KEY_MESSAGE,
cdm_engine_.GenerateKeyRequest(session_id_, cdm_engine_.GenerateKeyRequest(
key_set_id, session_id_, key_set_id, init_data, kLicenseTypeStreaming,
init_data, app_parameters, &key_msg_, &server_url, NULL));
kLicenseTypeStreaming,
app_parameters,
&key_msg_,
&server_url,
NULL));
} }
void GenerateRenewalRequest() { void GenerateRenewalRequest() {
EXPECT_EQ(KEY_MESSAGE, EXPECT_EQ(KEY_MESSAGE, cdm_engine_.GenerateRenewalRequest(
cdm_engine_.GenerateRenewalRequest(session_id_, session_id_, &key_msg_, &server_url_));
&key_msg_,
&server_url_));
} }
std::string GetKeyRequestResponse(const std::string& server_url, std::string GetKeyRequestResponse(const std::string& server_url,
const std::string& client_auth) { const std::string& client_auth) {
return GetKeyRequestResponse(server_url, client_auth, true); return GetKeyRequestResponse(server_url, client_auth, true);
} }
std::string FailToGetKeyRequestResponse(const std::string& server_url, std::string FailToGetKeyRequestResponse(const std::string& server_url,
const std::string& client_auth) { const std::string& client_auth) {
return GetKeyRequestResponse(server_url, client_auth, false); return GetKeyRequestResponse(server_url, client_auth, false);
@@ -140,18 +132,18 @@ class WvCdmEngineTest : public testing::Test {
LicenseRequest lic_request; LicenseRequest lic_request;
lic_request.GetDrmMessage(response, drm_msg); lic_request.GetDrmMessage(response, drm_msg);
LOGV("drm msg: %u bytes\r\n%s", drm_msg.size(), LOGV("drm msg: %u bytes\r\n%s", drm_msg.size(),
HexEncode(reinterpret_cast<const uint8_t*>(drm_msg.data()), HexEncode(reinterpret_cast<const uint8_t*>(drm_msg.data()),
drm_msg.size()).c_str()); drm_msg.size()).c_str());
return drm_msg; return drm_msg;
} }
} }
void VerifyNewKeyResponse(const std::string& server_url, void VerifyNewKeyResponse(const std::string& server_url,
const std::string& client_auth){ const std::string& client_auth) {
std::string resp = GetKeyRequestResponse(server_url, std::string resp = GetKeyRequestResponse(server_url, client_auth);
client_auth);
CdmKeySetId key_set_id; CdmKeySetId key_set_id;
EXPECT_EQ(wvcdm::KEY_ADDED, cdm_engine_.AddKey(session_id_, resp, &key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED,
cdm_engine_.AddKey(session_id_, resp, &key_set_id));
} }
void VerifyRenewalKeyResponse(const std::string& server_url, void VerifyRenewalKeyResponse(const std::string& server_url,
@@ -213,7 +205,7 @@ TEST_F(WvCdmEngineTest, LicenseRenewal) {
} // namespace wvcdm } // namespace wvcdm
int main(int argc, char **argv) { int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
wvcdm::InitLogging(argc, argv); wvcdm::InitLogging(argc, argv);
@@ -229,14 +221,14 @@ int main(int argc, char **argv) {
int show_usage = 0; int show_usage = 0;
static const struct option long_options[] = { static const struct option long_options[] = {
{ "keyid", required_argument, NULL, 'k' }, {"keyid", required_argument, NULL, 'k'},
{ "server", required_argument, NULL, 's' }, {"server", required_argument, NULL, 's'},
{ NULL, 0, NULL, '\0' } {NULL, 0, NULL, '\0'}};
};
int option_index = 0; int option_index = 0;
int opt = 0; int opt = 0;
while ((opt = getopt_long(argc, argv, "k:s:v", long_options, &option_index)) != -1) { while ((opt = getopt_long(argc, argv, "k:s:v", long_options,
&option_index)) != -1) {
switch (opt) { switch (opt) {
case 'k': { case 'k': {
g_key_id_pssh.clear(); g_key_id_pssh.clear();
@@ -269,11 +261,16 @@ int main(int argc, char **argv) {
if (show_usage) { if (show_usage) {
std::cout << std::endl; std::cout << std::endl;
std::cout << "usage: " << argv[0] << " [options]" << std::endl << std::endl; std::cout << "usage: " << argv[0] << " [options]" << std::endl << std::endl;
std::cout << " enclose multiple arguments in '' when using adb shell" << std::endl; std::cout << " enclose multiple arguments in '' when using adb shell"
std::cout << " e.g. adb shell '" << argv[0] << " --server=\"url\"'" << std::endl << std::endl; << std::endl;
std::cout << " e.g. adb shell '" << argv[0] << " --server=\"url\"'"
<< std::endl
<< std::endl;
std::cout << std::setw(30) << std::left << " --server=<server_url>"; std::cout << std::setw(30) << std::left << " --server=<server_url>";
std::cout << "configure the license server url, please include http[s] in the url" << std::endl; std::cout
<< "configure the license server url, please include http[s] in the url"
<< std::endl;
std::cout << std::setw(30) << std::left << " "; std::cout << std::setw(30) << std::left << " ";
std::cout << "default: " << license_server << std::endl; std::cout << "default: " << license_server << std::endl;

View File

@@ -6,25 +6,24 @@ namespace {
const std::string kWidevineKeySystem = "com.widevine.alpha"; const std::string kWidevineKeySystem = "com.widevine.alpha";
// Content Protection license server data // Content Protection license server data
const std::string kCpLicenseServer = const std::string kCpLicenseServer = "http://widevine-proxy.appspot.com/proxy";
"http://widevine-proxy.appspot.com/proxy";
const std::string kCpClientAuth = ""; const std::string kCpClientAuth = "";
const std::string kCpKeyId = const std::string kCpKeyId =
"00000042" // blob size "00000042" // blob size
"70737368" // "pssh" "70737368" // "pssh"
"00000000" // flags "00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000022" // pssh data size "00000022" // pssh data size
// pssh data: // pssh data:
"08011a0d7769646576696e655f746573" "08011a0d7769646576696e655f746573"
"74220f73747265616d696e675f636c69" "74220f73747265616d696e675f636c69"
"7031"; "7031";
const std::string kCpOfflineKeyId = const std::string kCpOfflineKeyId =
"00000040" // blob size "00000040" // blob size
"70737368" // "pssh" "70737368" // "pssh"
"00000000" // flags "00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000020" // pssh data size "00000020" // pssh data size
// pssh data: // pssh data:
"08011a0d7769646576696e655f746573" "08011a0d7769646576696e655f746573"
"74220d6f66666c696e655f636c697032"; "74220d6f66666c696e655f636c697032";
@@ -40,18 +39,17 @@ const std::string kGpLicenseServer =
const std::string kGpClientAuth = const std::string kGpClientAuth =
"?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine"; "?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
const std::string kGpKeyId = const std::string kGpKeyId =
"00000034" // blob size "00000034" // blob size
"70737368" // "pssh" "70737368" // "pssh"
"00000000" // flags "00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000014" // pssh data size "00000014" // pssh data size
// pssh data: // pssh data:
"08011210e02562e04cd55351b14b3d74" "08011210e02562e04cd55351b14b3d74"
"8d36ed8e"; "8d36ed8e";
const std::string kGpOfflineKeyId = kGpKeyId; const std::string kGpOfflineKeyId = kGpKeyId;
const std::string kGpClientOfflineQueryParameters = const std::string kGpClientOfflineQueryParameters = "&offline=true";
"&offline=true";
const std::string kGpClientOfflineRenewalQueryParameters = const std::string kGpClientOfflineRenewalQueryParameters =
"&offline=true&renewal=true"; "&offline=true&renewal=true";
const std::string kGpClientOfflineReleaseQueryParameters = const std::string kGpClientOfflineReleaseQueryParameters =
@@ -59,11 +57,11 @@ const std::string kGpClientOfflineReleaseQueryParameters =
// An invalid key id, expected to fail // An invalid key id, expected to fail
const std::string kWrongKeyId = const std::string kWrongKeyId =
"00000034" // blob size "00000034" // blob size
"70737368" // "pssh" "70737368" // "pssh"
"00000000" // flags "00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000014" // pssh data size "00000014" // pssh data size
// pssh data: // pssh data:
"0901121094889920e8d6520098577df8" "0901121094889920e8d6520098577df8"
"f2dd5546"; "f2dd5546";
@@ -75,24 +73,21 @@ const std::string kProductionProvisioningServerUrl =
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
const wvcdm::ConfigTestEnv::LicenseServerConfiguration license_servers[] = { const wvcdm::ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
{ wvcdm::kGooglePlayServer, kGpLicenseServer, {wvcdm::kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
kGpClientAuth, kGpKeyId, kGpOfflineKeyId }, kGpOfflineKeyId},
{ wvcdm::kContentProtectionServer, kCpLicenseServer, {wvcdm::kContentProtectionServer, kCpLicenseServer, kCpClientAuth, kCpKeyId,
kCpClientAuth, kCpKeyId, kCpOfflineKeyId }, kCpOfflineKeyId},
}; };
} // namespace } // namespace
namespace wvcdm { namespace wvcdm {
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id) { ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id) { Init(server_id); }
Init(server_id);
}
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming) { ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming) {
Init(server_id); Init(server_id);
if (!streaming) if (!streaming) key_id_ = license_servers[server_id].offline_key_id;
key_id_ = license_servers[server_id].offline_key_id;
} }
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming, ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming,
@@ -119,7 +114,7 @@ void ConfigTestEnv::Init(LicenseServerId server_id) {
key_system_ = kWidevineKeySystem; key_system_ = kWidevineKeySystem;
license_server_ = license_servers[server_id].url; license_server_ = license_servers[server_id].url;
provisioning_server_url_ = kProductionProvisioningServerUrl; provisioning_server_url_ = kProductionProvisioningServerUrl;
wrong_key_id_= kWrongKeyId; wrong_key_id_ = kWrongKeyId;
} }
} // namespace wvcdm } // namespace wvcdm

View File

@@ -1370,8 +1370,9 @@ TEST_F(DeviceFilesTest, ReadCertificate) {
.WillOnce(Return(data.size())); .WillOnce(Return(data.size()));
EXPECT_CALL(file, Open(StrEq(device_certificate_path), IsBinaryFileFlagSet())) EXPECT_CALL(file, Open(StrEq(device_certificate_path), IsBinaryFileFlagSet()))
.WillOnce(Return(true)); .WillOnce(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))).WillOnce(DoAll( EXPECT_CALL(file, Read(NotNull(), Eq(data.size())))
SetArrayArgument<0>(data.begin(), data.end()), Return(data.size()))); .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data.size())));
EXPECT_CALL(file, Close()).Times(1); EXPECT_CALL(file, Close()).Times(1);
EXPECT_CALL(file, Write(_, _)).Times(0); EXPECT_CALL(file, Write(_, _)).Times(0);
@@ -1530,10 +1531,11 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
EXPECT_CALL(file, FileSize(StrEq(license_path))).WillOnce(Return(size)); EXPECT_CALL(file, FileSize(StrEq(license_path))).WillOnce(Return(size));
EXPECT_CALL(file, Open(StrEq(license_path), IsBinaryFileFlagSet())) EXPECT_CALL(file, Open(StrEq(license_path), IsBinaryFileFlagSet()))
.WillOnce(Return(true)); .WillOnce(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(size))).WillOnce( EXPECT_CALL(file, Read(NotNull(), Eq(size)))
DoAll(SetArrayArgument<0>(license_test_data[i].file_data.begin(), .WillOnce(
license_test_data[i].file_data.end()), DoAll(SetArrayArgument<0>(license_test_data[i].file_data.begin(),
Return(size))); license_test_data[i].file_data.end()),
Return(size)));
} }
EXPECT_CALL(file, Close()).Times(kNumberOfLicenses); EXPECT_CALL(file, Close()).Times(kNumberOfLicenses);
EXPECT_CALL(file, Write(_, _)).Times(0); EXPECT_CALL(file, Write(_, _)).Times(0);
@@ -1628,8 +1630,9 @@ TEST_F(DeviceFilesTest, SecurityLevelPathBackwardCompatibility) {
EXPECT_CALL(file, Exists(StrEq(new_path))).WillOnce(Return(true)); EXPECT_CALL(file, Exists(StrEq(new_path))).WillOnce(Return(true));
EXPECT_CALL(file, FileSize(_)).WillOnce(Return(data.size())); EXPECT_CALL(file, FileSize(_)).WillOnce(Return(data.size()));
EXPECT_CALL(file, Open(_, _)).WillOnce(Return(true)); EXPECT_CALL(file, Open(_, _)).WillOnce(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))).WillOnce(DoAll( EXPECT_CALL(file, Read(NotNull(), Eq(data.size())))
SetArrayArgument<0>(data.begin(), data.end()), Return(data.size()))); .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data.size())));
EXPECT_CALL(file, Close()).Times(1); EXPECT_CALL(file, Close()).Times(1);
EXPECT_CALL(file, Write(_, _)).Times(0); EXPECT_CALL(file, Write(_, _)).Times(0);
@@ -1709,10 +1712,11 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
EXPECT_CALL(file, FileSize(StrEq(license_path))).WillOnce(Return(size)); EXPECT_CALL(file, FileSize(StrEq(license_path))).WillOnce(Return(size));
EXPECT_CALL(file, Open(StrEq(license_path), IsBinaryFileFlagSet())) EXPECT_CALL(file, Open(StrEq(license_path), IsBinaryFileFlagSet()))
.WillOnce(Return(true)); .WillOnce(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(size))).WillOnce( EXPECT_CALL(file, Read(NotNull(), Eq(size)))
DoAll(SetArrayArgument<0>(license_test_data[0].file_data.begin(), .WillOnce(
license_test_data[0].file_data.end()), DoAll(SetArrayArgument<0>(license_test_data[0].file_data.begin(),
Return(size))); license_test_data[0].file_data.end()),
Return(size)));
EXPECT_CALL(file, Remove(StrEq(license_path))).WillOnce(Return(true)); EXPECT_CALL(file, Remove(StrEq(license_path))).WillOnce(Return(true));
EXPECT_CALL(file, Close()).Times(1); EXPECT_CALL(file, Close()).Times(1);
EXPECT_CALL(file, Write(_, _)).Times(0); EXPECT_CALL(file, Write(_, _)).Times(0);
@@ -1778,8 +1782,9 @@ TEST_F(DeviceFilesTest, ReserveLicenseIds) {
TEST_P(DeviceFilesUsageInfoTest, Read) { TEST_P(DeviceFilesUsageInfoTest, Read) {
MockFile file; MockFile file;
std::string app_id; // TODO(fredgc): expand tests. std::string app_id; // TODO(fredgc): add tests with multiple app_ids.
std::string path = device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); std::string path =
device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id);
int index = GetParam(); int index = GetParam();
std::string data; std::string data;
@@ -1791,12 +1796,14 @@ TEST_P(DeviceFilesUsageInfoTest, Read) {
EXPECT_CALL(file, FileSize(StrEq(path))).WillOnce(Return(data.size())); EXPECT_CALL(file, FileSize(StrEq(path))).WillOnce(Return(data.size()));
EXPECT_CALL(file, Open(StrEq(path), IsBinaryFileFlagSet())) EXPECT_CALL(file, Open(StrEq(path), IsBinaryFileFlagSet()))
.WillOnce(Return(true)); .WillOnce(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))).WillOnce(DoAll( EXPECT_CALL(file, Read(NotNull(), Eq(data.size())))
SetArrayArgument<0>(data.begin(), data.end()), Return(data.size()))); .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data.size())));
EXPECT_CALL(file, Close()).Times(1); EXPECT_CALL(file, Close()).Times(1);
} else { } else {
EXPECT_CALL(file, Exists(StrEq(path))).Times(2).WillRepeatedly( EXPECT_CALL(file, Exists(StrEq(path)))
Return(false)); .Times(2)
.WillRepeatedly(Return(false));
EXPECT_CALL(file, FileSize(_)).Times(0); EXPECT_CALL(file, FileSize(_)).Times(0);
EXPECT_CALL(file, Open(_, _)).Times(0); EXPECT_CALL(file, Open(_, _)).Times(0);
EXPECT_CALL(file, Close()).Times(0); EXPECT_CALL(file, Close()).Times(0);
@@ -1831,11 +1838,12 @@ TEST_P(DeviceFilesUsageInfoTest, Read) {
TEST_P(DeviceFilesUsageInfoTest, Store) { TEST_P(DeviceFilesUsageInfoTest, Store) {
MockFile file; MockFile file;
std::string app_id; // TODO(fredgc): expand tests. std::string app_id; // TODO(fredgc): multiple app ids.
std::string pst(GenerateRandomData(kProviderSessionTokenLen)); std::string pst(GenerateRandomData(kProviderSessionTokenLen));
std::string license_request(GenerateRandomData(kLicenseRequestLen)); std::string license_request(GenerateRandomData(kLicenseRequestLen));
std::string license(GenerateRandomData(kLicenseLen)); std::string license(GenerateRandomData(kLicenseLen));
std::string path = device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); std::string path =
device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id);
int index = GetParam(); int index = GetParam();
std::string data; std::string data;
@@ -1852,8 +1860,9 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
EXPECT_CALL(file, Open(StrEq(path), IsBinaryFileFlagSet())) EXPECT_CALL(file, Open(StrEq(path), IsBinaryFileFlagSet()))
.Times(2) .Times(2)
.WillRepeatedly(Return(true)); .WillRepeatedly(Return(true));
EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))).WillOnce(DoAll( EXPECT_CALL(file, Read(NotNull(), Eq(data.size())))
SetArrayArgument<0>(data.begin(), data.end()), Return(data.size()))); .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data.size())));
EXPECT_CALL(file, Close()).Times(2); EXPECT_CALL(file, Close()).Times(2);
} else { } else {
EXPECT_CALL(file, FileSize(_)).Times(0); EXPECT_CALL(file, FileSize(_)).Times(0);
@@ -1869,13 +1878,15 @@ TEST_P(DeviceFilesUsageInfoTest, Store) {
EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
device_files.SetTestFile(&file); device_files.SetTestFile(&file);
ASSERT_TRUE(device_files.StoreUsageInfo(pst, license_request, license, app_id)); ASSERT_TRUE(
device_files.StoreUsageInfo(pst, license_request, license, app_id));
} }
TEST_P(DeviceFilesUsageInfoTest, Delete) { TEST_P(DeviceFilesUsageInfoTest, Delete) {
MockFile file; MockFile file;
std::string app_id; // TODO(fredgc): expand tests. std::string app_id; // TODO(fredgc): expand tests.
std::string path = device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); std::string path =
device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id);
int index = GetParam(); int index = GetParam();
if (index < 0) return; if (index < 0) return;
@@ -1912,8 +1923,9 @@ TEST_P(DeviceFilesUsageInfoTest, Delete) {
EXPECT_CALL(file, Write(_, _)).Times(0); EXPECT_CALL(file, Write(_, _)).Times(0);
EXPECT_CALL(file, Close()).Times(1); EXPECT_CALL(file, Close()).Times(1);
} }
EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))).WillOnce(DoAll( EXPECT_CALL(file, Read(NotNull(), Eq(data.size())))
SetArrayArgument<0>(data.begin(), data.end()), Return(data.size()))); .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data.size())));
DeviceFiles device_files; DeviceFiles device_files;
EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); EXPECT_TRUE(device_files.Init(kSecurityLevelL1));

View File

@@ -257,8 +257,7 @@ TEST_F(FileTest, ListFiles) {
EXPECT_EQ(3u, files.size()); EXPECT_EQ(3u, files.size());
for (size_t i = 0; i < files.size(); ++i) { for (size_t i = 0; i < files.size(); ++i) {
EXPECT_TRUE(files[i] == kTestDirName || EXPECT_TRUE(files[i] == kTestDirName || files[i] == kTestFileName ||
files[i] == kTestFileName ||
files[i] == kTestFileName2); files[i] == kTestFileName2);
} }
} }

View File

@@ -41,8 +41,7 @@ SSL_CTX* InitSslContext() {
SSL_load_error_strings(); SSL_load_error_strings();
method = SSLv3_client_method(); method = SSLv3_client_method();
ctx = SSL_CTX_new(method); ctx = SSL_CTX_new(method);
if (!ctx) if (!ctx) LOGE("failed to create SSL context");
LOGE("failed to create SSL context");
return ctx; return ctx;
} }
@@ -77,8 +76,8 @@ bool SocketWait(int fd, bool for_read, int timeout_in_ms) {
tv.tv_sec = timeout_in_ms / 1000; tv.tv_sec = timeout_in_ms / 1000;
tv.tv_usec = (timeout_in_ms % 1000) * 1000; tv.tv_usec = (timeout_in_ms % 1000) * 1000;
fd_set *read_fds = NULL; fd_set* read_fds = NULL;
fd_set *write_fds = NULL; fd_set* write_fds = NULL;
if (for_read) { if (for_read) {
read_fds = &fds; read_fds = &fds;
} else { } else {
@@ -104,12 +103,9 @@ namespace wvcdm {
// Parses the URL and extracts all relevant information. // Parses the URL and extracts all relevant information.
// static // static
bool HttpSocket::ParseUrl(const std::string& url, bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme,
std::string* scheme, bool* secure_connect, std::string* domain_name,
bool* secure_connect, int* port, std::string* path) {
std::string* domain_name,
int* port,
std::string* path) {
size_t offset = 0; size_t offset = 0;
if (!Tokenize(url, "://", offset, scheme, &offset)) { if (!Tokenize(url, "://", offset, scheme, &offset)) {
@@ -143,8 +139,7 @@ bool HttpSocket::ParseUrl(const std::string& url,
// The domain name may optionally contain a port which overrides the default. // The domain name may optionally contain a port which overrides the default.
std::string domain_name_without_port; std::string domain_name_without_port;
size_t port_offset; size_t port_offset;
if (Tokenize(*domain_name, ":", 0, &domain_name_without_port, if (Tokenize(*domain_name, ":", 0, &domain_name_without_port, &port_offset)) {
&port_offset)) {
*port = atoi(domain_name->c_str() + port_offset); *port = atoi(domain_name->c_str() + port_offset);
if (*port <= 0 || *port >= 65536) { if (*port <= 0 || *port >= 65536) {
LOGE("Invalid URL, port not valid: %s", url.c_str()); LOGE("Invalid URL, port not valid: %s", url.c_str());
@@ -157,17 +152,13 @@ bool HttpSocket::ParseUrl(const std::string& url,
} }
HttpSocket::HttpSocket(const std::string& url) HttpSocket::HttpSocket(const std::string& url)
: socket_fd_(-1), : socket_fd_(-1), ssl_(NULL), ssl_ctx_(NULL) {
ssl_(NULL),
ssl_ctx_(NULL) {
valid_url_ = ParseUrl(url, &scheme_, &secure_connect_, &domain_name_, &port_, valid_url_ = ParseUrl(url, &scheme_, &secure_connect_, &domain_name_, &port_,
&resource_path_); &resource_path_);
SSL_library_init(); SSL_library_init();
} }
HttpSocket::~HttpSocket() { HttpSocket::~HttpSocket() { CloseSocket(); }
CloseSocket();
}
void HttpSocket::CloseSocket() { void HttpSocket::CloseSocket() {
if (socket_fd_ != -1) { if (socket_fd_ != -1) {
@@ -223,8 +214,8 @@ bool HttpSocket::Connect(int timeout_in_ms) {
} }
// set the port // set the port
struct sockaddr_in* addr_ipv4 = reinterpret_cast<struct sockaddr_in*>( struct sockaddr_in* addr_ipv4 =
addr_info->ai_addr); reinterpret_cast<struct sockaddr_in*>(addr_info->ai_addr);
addr_ipv4->sin_port = htons(port_); addr_ipv4->sin_port = htons(port_);
// connect to the server // connect to the server
@@ -276,8 +267,7 @@ bool HttpSocket::Connect(int timeout_in_ms) {
ret = SSL_connect(ssl_); ret = SSL_connect(ssl_);
if (ret != 1) { if (ret != 1) {
int ssl_err = SSL_get_error(ssl_, ret); int ssl_err = SSL_get_error(ssl_, ret);
if (ssl_err != SSL_ERROR_WANT_READ && if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) {
ssl_err != SSL_ERROR_WANT_WRITE) {
char buf[256]; char buf[256];
LOGE("SSL_connect error: %s", ERR_error_string(ERR_get_error(), buf)); LOGE("SSL_connect error: %s", ERR_error_string(ERR_get_error(), buf));
CloseSocket(); CloseSocket();

View File

@@ -32,12 +32,9 @@ class HttpSocket {
int Write(const char* data, int len, int timeout_in_ms); int Write(const char* data, int len, int timeout_in_ms);
private: private:
static bool ParseUrl(const std::string& url, static bool ParseUrl(const std::string& url, std::string* scheme,
std::string* scheme, bool* secure_connect, std::string* domain_name,
bool* secure_connect, int* port, std::string* path);
std::string* domain_name,
int* port,
std::string* path);
FRIEND_TEST(HttpSocketTest, ParseUrlTest); FRIEND_TEST(HttpSocketTest, ParseUrlTest);
std::string scheme_; std::string scheme_;

View File

@@ -103,63 +103,63 @@ struct ParseUrlTests {
}; };
ParseUrlTests parse_url_tests[] = { ParseUrlTests parse_url_tests[] = {
{ {
"https://code.google.com/p/googletest/wiki/Primer", // url "https://code.google.com/p/googletest/wiki/Primer", // url
"https", // scheme "https", // scheme
true, // secure_connect true, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
443, // port 443, // port
"/p/googletest/wiki/Primer", // path "/p/googletest/wiki/Primer", // path
}, },
{ {
"http://code.google.com/p/googletest/wiki/Primer/", // url "http://code.google.com/p/googletest/wiki/Primer/", // url
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port 80, // port
"/p/googletest/wiki/Primer/", // path "/p/googletest/wiki/Primer/", // path
}, },
{ {
"http://code.google.com/", // url "http://code.google.com/", // url
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port 80, // port
"/", // path "/", // path
}, },
{ {
"http://code.google.com", // url "http://code.google.com", // url
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port 80, // port
"/", // path "/", // path
}, },
{ {
"http://10.11.12.13:8888/drm", // url "http://10.11.12.13:8888/drm", // url
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port 8888, // port
"/drm", // path "/drm", // path
}, },
{ {
"http://10.11.12.13:8888", // url "http://10.11.12.13:8888", // url
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port 8888, // port
"/", // path "/", // path
}, },
{ {
"https://10.11.12.13:8888", // url "https://10.11.12.13:8888", // url
"https", // scheme "https", // scheme
true, // secure_connect true, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port 8888, // port
"/", // path "/", // path
}, },
{ NULL } // list terminator {NULL} // list terminator
}; };
TEST_F(HttpSocketTest, ParseUrlTest) { TEST_F(HttpSocketTest, ParseUrlTest) {

View File

@@ -137,8 +137,7 @@ const std::string kZeroSizedPsshBox = wvcdm::a2bs_hex(
// data: // data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031"); "08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
class InitializationDataTest class InitializationDataTest : public ::testing::TestWithParam<std::string> {};
: public ::testing::TestWithParam<std::string> {};
} // namespace } // namespace

View File

@@ -9,13 +9,13 @@ static const std::string kTwoBlankLines("\r\n\r\n");
size_t LicenseRequest::FindHeaderEndPosition( size_t LicenseRequest::FindHeaderEndPosition(
const std::string& response) const { const std::string& response) const {
return(response.find(kTwoBlankLines)); return response.find(kTwoBlankLines);
} }
// This routine parses the license server's response message and // This routine parses the license server's response message and
// extracts the drm message from the response header. // extracts the drm message from the response header.
void LicenseRequest::GetDrmMessage(const std::string& response, void LicenseRequest::GetDrmMessage(const std::string& response,
std::string& drm_msg) { std::string& drm_msg) {
if (response.empty()) { if (response.empty()) {
drm_msg.clear(); drm_msg.clear();
return; return;
@@ -27,7 +27,7 @@ void LicenseRequest::GetDrmMessage(const std::string& response,
// the drm message length as below instead of using Content-Length // the drm message length as below instead of using Content-Length
size_t header_end_pos = FindHeaderEndPosition(response); size_t header_end_pos = FindHeaderEndPosition(response);
if (header_end_pos != std::string::npos) { if (header_end_pos != std::string::npos) {
header_end_pos += kTwoBlankLines.size(); // points to response body header_end_pos += kTwoBlankLines.size(); // points to response body
drm_msg.clear(); drm_msg.clear();
// Messages from Google Play server add a GLS wrapper. These start // Messages from Google Play server add a GLS wrapper. These start
@@ -64,11 +64,10 @@ void LicenseRequest::GetHeartbeatUrl(const std::string& response,
size_t header_end_pos = FindHeaderEndPosition(response); size_t header_end_pos = FindHeaderEndPosition(response);
if (header_end_pos != std::string::npos) { if (header_end_pos != std::string::npos) {
header_end_pos += kTwoBlankLines.size(); // points to response body header_end_pos += kTwoBlankLines.size(); // points to response body
heartbeat_url.clear(); heartbeat_url.clear();
size_t heartbeat_url_pos = response.find("Heartbeat-Url: ", size_t heartbeat_url_pos = response.find("Heartbeat-Url: ", header_end_pos);
header_end_pos);
if (heartbeat_url_pos != std::string::npos) { if (heartbeat_url_pos != std::string::npos) {
heartbeat_url_pos += sizeof("Heartbeat-Url: "); heartbeat_url_pos += sizeof("Heartbeat-Url: ");
heartbeat_url.assign(response.substr(heartbeat_url_pos)); heartbeat_url.assign(response.substr(heartbeat_url_pos));
@@ -80,4 +79,4 @@ void LicenseRequest::GetHeartbeatUrl(const std::string& response,
} }
} }
} // namespace wvcdm } // namespace wvcdm

View File

@@ -45,8 +45,7 @@ static const char* kInvalidResponse =
const std::string kCencMimeType = "video/mp4"; const std::string kCencMimeType = "video/mp4";
const std::string kWebmMimeType = "video/webm"; const std::string kWebmMimeType = "video/webm";
} // namespace
}
namespace wvcdm { namespace wvcdm {
@@ -88,12 +87,8 @@ TEST_F(LicenseTest, DISABLED_PrepareIsoBmffKeyRequest) {
std::string server_url; std::string server_url;
CdmSessionId session_id; CdmSessionId session_id;
InitializationData init_data(kCencMimeType, a2bs_hex(kInitData)); InitializationData init_data(kCencMimeType, a2bs_hex(kInitData));
license_.PrepareKeyRequest(init_data, license_.PrepareKeyRequest(init_data, kLicenseTypeStreaming, app_parameters,
kLicenseTypeStreaming, session_id, &signed_request, &server_url);
app_parameters,
session_id,
&signed_request,
&server_url);
EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest)); EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest));
} }
@@ -104,12 +99,8 @@ TEST_F(LicenseTest, DISABLED_PrepareWebmKeyRequest) {
std::string server_url; std::string server_url;
CdmSessionId session_id; CdmSessionId session_id;
InitializationData init_data(kWebmMimeType, a2bs_hex(kInitData)); InitializationData init_data(kWebmMimeType, a2bs_hex(kInitData));
license_.PrepareKeyRequest(init_data, license_.PrepareKeyRequest(init_data, kLicenseTypeStreaming, app_parameters,
kLicenseTypeStreaming, session_id, &signed_request, &server_url);
app_parameters,
session_id,
&signed_request,
&server_url);
EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest)); EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest));
} }
@@ -120,12 +111,8 @@ TEST_F(LicenseTest, DISABLED_HandleKeyResponseValid) {
CdmSessionId session_id; CdmSessionId session_id;
std::string server_url; std::string server_url;
InitializationData init_data(kCencMimeType, a2bs_hex(kInitData)); InitializationData init_data(kCencMimeType, a2bs_hex(kInitData));
license_.PrepareKeyRequest(init_data, license_.PrepareKeyRequest(init_data, kLicenseTypeStreaming, app_parameters,
kLicenseTypeStreaming, session_id, &signed_request, &server_url);
app_parameters,
session_id,
&signed_request,
&server_url);
EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest)); EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest));
EXPECT_TRUE(license_.HandleKeyResponse(a2bs_hex(kValidResponse))); EXPECT_TRUE(license_.HandleKeyResponse(a2bs_hex(kValidResponse)));
} }
@@ -137,17 +124,12 @@ TEST_F(LicenseTest, DISABLED_HandleKeyResponseInvalid) {
CdmSessionId session_id; CdmSessionId session_id;
std::string server_url; std::string server_url;
InitializationData init_data(kCencMimeType, a2bs_hex(kInitData)); InitializationData init_data(kCencMimeType, a2bs_hex(kInitData));
license_.PrepareKeyRequest(init_data, license_.PrepareKeyRequest(init_data, kLicenseTypeStreaming, app_parameters,
kLicenseTypeStreaming, session_id, &signed_request, &server_url);
app_parameters,
session_id,
&signed_request,
&server_url);
EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest)); EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest));
EXPECT_FALSE(license_.HandleKeyResponse(a2bs_hex(kInvalidResponse))); EXPECT_FALSE(license_.HandleKeyResponse(a2bs_hex(kInvalidResponse)));
} }
// TODO(kqyang): add unit test cases for PrepareKeyRenewalRequest // TODO(kqyang): add unit test cases for PrepareKeyRenewalRequest
// and HandleRenewalKeyResponse // and HandleRenewalKeyResponse
} }

View File

@@ -226,8 +226,7 @@ TEST_F(MaxResEngineTest, RequestsHdcpImmediatelyAndOnlyAfterInterval) {
{ {
InSequence calls; InSequence calls;
EXPECT_CALL(*mock_clock_, GetCurrentTime()) EXPECT_CALL(*mock_clock_, GetCurrentTime()).WillOnce(Return(start_time));
.WillOnce(Return(start_time));
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillOnce( .WillOnce(
DoAll(SetArgPointee<0>(CryptoSession::kOemCryptoHdcpVersion2_2), DoAll(SetArgPointee<0>(CryptoSession::kOemCryptoHdcpVersion2_2),
@@ -249,8 +248,7 @@ TEST_F(MaxResEngineTest, RequestsHdcpImmediatelyAndOnlyAfterInterval) {
} }
TEST_F(MaxResEngineTest, DoesNotRequestHdcpWithoutALicense) { TEST_F(MaxResEngineTest, DoesNotRequestHdcpWithoutALicense) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
.Times(0);
max_res_engine_->OnTimerEvent(); max_res_engine_->OnTimerEvent();
} }
@@ -310,8 +308,7 @@ TEST_F(MaxResEngineTest, HandlesNoHdcp) {
} }
TEST_F(MaxResEngineTest, IgnoresHdcpWithoutAResolution) { TEST_F(MaxResEngineTest, IgnoresHdcpWithoutAResolution) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
.Times(0);
max_res_engine_->SetLicense(license_); max_res_engine_->SetLicense(license_);
max_res_engine_->OnTimerEvent(); max_res_engine_->OnTimerEvent();

View File

@@ -7,7 +7,7 @@
namespace wvcdm { namespace wvcdm {
void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
switch(value) { switch (value) {
case NO_ERROR: *os << "NO_ERROR"; case NO_ERROR: *os << "NO_ERROR";
break; break;
case UNKNOWN_ERROR: *os << "UNKNOWN_ERROR"; case UNKNOWN_ERROR: *os << "UNKNOWN_ERROR";
@@ -35,7 +35,7 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
} }
void PrintTo(const enum CdmEventType& value, ::std::ostream* os) { void PrintTo(const enum CdmEventType& value, ::std::ostream* os) {
switch(value) { switch (value) {
case LICENSE_EXPIRED_EVENT: *os << "LICENSE_EXPIRED_EVENT"; case LICENSE_EXPIRED_EVENT: *os << "LICENSE_EXPIRED_EVENT";
break; break;
case LICENSE_RENEWAL_NEEDED_EVENT: *os << "LICENSE_RENEWAL_NEEDED_EVENT"; case LICENSE_RENEWAL_NEEDED_EVENT: *os << "LICENSE_RENEWAL_NEEDED_EVENT";
@@ -47,7 +47,7 @@ void PrintTo(const enum CdmEventType& value, ::std::ostream* os) {
}; };
void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) { void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) {
switch(value) { switch (value) {
case kLicenseTypeOffline: *os << "kLicenseTypeOffline"; case kLicenseTypeOffline: *os << "kLicenseTypeOffline";
break; break;
case kLicenseTypeStreaming: *os << "kLicenseTypeStreaming"; case kLicenseTypeStreaming: *os << "kLicenseTypeStreaming";
@@ -61,7 +61,7 @@ void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) {
}; };
void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os) { void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os) {
switch(value) { switch (value) {
case kSecurityLevelUninitialized: *os << "kSecurityLevelUninitialized"; case kSecurityLevelUninitialized: *os << "kSecurityLevelUninitialized";
break; break;
case kSecurityLevelL1: *os << "kSecurityLevelL1"; case kSecurityLevelL1: *os << "kSecurityLevelL1";
@@ -79,7 +79,7 @@ void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os) {
}; };
void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os) { void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os) {
switch(value) { switch (value) {
case kCertificateWidevine: *os << "kCertificateWidevine"; case kCertificateWidevine: *os << "kCertificateWidevine";
break; break;
case kCertificateX509: *os << "kCertificateX509"; case kCertificateX509: *os << "kCertificateX509";

View File

@@ -10,9 +10,7 @@ class TestTimerHandler : public TimerHandler {
TestTimerHandler() : timer_events_(0) {}; TestTimerHandler() : timer_events_(0) {};
virtual ~TestTimerHandler() {}; virtual ~TestTimerHandler() {};
virtual void OnTimerEvent() { virtual void OnTimerEvent() { timer_events_++; }
timer_events_++;
}
uint32_t timer_events() { return timer_events_; } uint32_t timer_events() { return timer_events_; }
void ResetTimerEvents() { timer_events_ = 0; } void ResetTimerEvents() { timer_events_ = 0; }
@@ -41,14 +39,14 @@ TEST(TimerTest, TimerCheck) {
EXPECT_TRUE(timer.IsRunning()); EXPECT_TRUE(timer.IsRunning());
sleep(duration); sleep(duration);
EXPECT_LE(duration-1, handler.timer_events()); EXPECT_LE(duration - 1, handler.timer_events());
EXPECT_LE(handler.timer_events(), duration+1); EXPECT_LE(handler.timer_events(), duration + 1);
timer.Stop(); timer.Stop();
EXPECT_FALSE(timer.IsRunning()); EXPECT_FALSE(timer.IsRunning());
sleep(duration); sleep(duration);
EXPECT_LE(duration-1, handler.timer_events()); EXPECT_LE(duration - 1, handler.timer_events());
EXPECT_LE(handler.timer_events(), duration+1); EXPECT_LE(handler.timer_events(), duration + 1);
} }
} }

View File

@@ -69,7 +69,6 @@ void ConcatenateChunkedResponse(const std::string http_response,
} // namespace } // namespace
namespace wvcdm { namespace wvcdm {
UrlRequest::UrlRequest(const std::string& url) UrlRequest::UrlRequest(const std::string& url)