Merge "Support Per-Origin Provisioning"

This commit is contained in:
John "Juce" Bruce
2015-04-10 18:20:54 +00:00
committed by Android (Google) Code Review
19 changed files with 627 additions and 313 deletions

View File

@@ -32,13 +32,14 @@ class CdmEngine {
// Session related methods // Session related methods
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system, virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
const CdmClientPropertySet* property_set, const CdmClientPropertySet* property_set,
const std::string& origin,
WvCdmEventListener* event_listener, WvCdmEventListener* event_listener,
CdmSessionId* session_id); CdmSessionId* session_id);
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 CdmClientPropertySet* property_set, const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set,
WvCdmEventListener* event_listener); const std::string& origin, WvCdmEventListener* event_listener);
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id); virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
// License related methods // License related methods
@@ -113,13 +114,18 @@ class CdmEngine {
// Provisioning related methods // Provisioning related methods
virtual CdmResponseType GetProvisioningRequest( virtual CdmResponseType GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority, CdmCertificateType cert_type, const std::string& cert_authority,
CdmProvisioningRequest* request, std::string* default_url); const std::string& origin, CdmProvisioningRequest* request,
std::string* default_url);
virtual CdmResponseType HandleProvisioningResponse( virtual CdmResponseType HandleProvisioningResponse(
CdmProvisioningResponse& response, std::string* cert, const std::string& origin, CdmProvisioningResponse& response,
std::string* wrapped_key); std::string* cert, std::string* wrapped_key);
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level); virtual bool IsProvisioned(CdmSecurityLevel security_level,
const std::string& origin);
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level,
const std::string& origin);
// Usage related methods for streaming licenses // Usage related methods for streaming licenses
// Retrieve a random usage info from the list of all usage infos for this app // Retrieve a random usage info from the list of all usage infos for this app

View File

@@ -4,6 +4,7 @@
#define WVCDM_CORE_CDM_SESSION_H_ #define WVCDM_CORE_CDM_SESSION_H_
#include <set> #include <set>
#include <string>
#include "crypto_session.h" #include "crypto_session.h"
#include "device_files.h" #include "device_files.h"
@@ -22,7 +23,7 @@ class WvCdmEventListener;
class CdmSession { class CdmSession {
public: public:
CdmSession(const CdmClientPropertySet* cdm_client_property_set, CdmSession(const CdmClientPropertySet* cdm_client_property_set,
WvCdmEventListener* event_listener); const std::string& origin, WvCdmEventListener* event_listener);
virtual ~CdmSession(); virtual ~CdmSession();
virtual CdmResponseType Init(); virtual CdmResponseType Init();
@@ -128,6 +129,7 @@ class CdmSession {
// instance variables // instance variables
bool initialized_; bool initialized_;
CdmSessionId session_id_; CdmSessionId session_id_;
const std::string origin_;
scoped_ptr<CdmLicense> license_parser_; scoped_ptr<CdmLicense> license_parser_;
scoped_ptr<CryptoSession> crypto_session_; scoped_ptr<CryptoSession> crypto_session_;
scoped_ptr<PolicyEngine> policy_engine_; scoped_ptr<PolicyEngine> policy_engine_;

View File

@@ -3,6 +3,8 @@
#ifndef WVCDM_CORE_CERTIFICATE_PROVISIONING_H_ #ifndef WVCDM_CORE_CERTIFICATE_PROVISIONING_H_
#define WVCDM_CORE_CERTIFICATE_PROVISIONING_H_ #define WVCDM_CORE_CERTIFICATE_PROVISIONING_H_
#include <string>
#include "crypto_session.h" #include "crypto_session.h"
#include "oemcrypto_adapter.h" #include "oemcrypto_adapter.h"
#include "wv_cdm_types.h" #include "wv_cdm_types.h"
@@ -20,9 +22,11 @@ class CertificateProvisioning {
CdmResponseType GetProvisioningRequest(SecurityLevel requested_security_level, CdmResponseType GetProvisioningRequest(SecurityLevel requested_security_level,
CdmCertificateType cert_type, CdmCertificateType cert_type,
const std::string& cert_authority, const std::string& cert_authority,
const std::string& origin,
CdmProvisioningRequest* request, CdmProvisioningRequest* request,
std::string* default_url); std::string* default_url);
CdmResponseType HandleProvisioningResponse(CdmProvisioningResponse& response, CdmResponseType HandleProvisioningResponse(const std::string& origin,
CdmProvisioningResponse& response,
std::string* cert, std::string* cert,
std::string* wrapped_key); std::string* wrapped_key);

View File

@@ -4,6 +4,7 @@
#define WVCDM_CORE_DEVICE_FILES_H_ #define WVCDM_CORE_DEVICE_FILES_H_
#include <unistd.h> #include <unistd.h>
#include <string>
#include "scoped_ptr.h" #include "scoped_ptr.h"
#include "wv_cdm_types.h" #include "wv_cdm_types.h"
@@ -32,10 +33,14 @@ class DeviceFiles {
return Init(security_level); return Init(security_level);
} }
virtual bool StoreCertificate(const std::string& certificate, virtual bool StoreCertificate(const std::string& origin,
const std::string& certificate,
const std::string& wrapped_private_key); const std::string& wrapped_private_key);
virtual bool RetrieveCertificate(std::string* certificate, virtual bool RetrieveCertificate(const std::string& origin,
std::string* certificate,
std::string* wrapped_private_key); std::string* wrapped_private_key);
virtual bool HasCertificate(const std::string& origin);
virtual bool RemoveCertificate(const std::string& origin);
virtual bool StoreLicense(const std::string& key_set_id, virtual bool StoreLicense(const std::string& key_set_id,
const LicenseState state, const LicenseState state,
@@ -100,18 +105,21 @@ class DeviceFiles {
// stored in a common directory and need to be copied over. // stored in a common directory and need to be copied over.
virtual void SecurityLevelPathBackwardCompatibility(); virtual void SecurityLevelPathBackwardCompatibility();
// For testing only: static std::string GetCertificateFileName(const std::string& origin);
static std::string GetCertificateFileName();
static std::string GetLicenseFileNameExtension(); static std::string GetLicenseFileNameExtension();
static std::string GetUsageInfoFileName(const std::string& app_id); static std::string GetUsageInfoFileName(const std::string& app_id);
static std::string GetBlankFileData(); static std::string GetBlankFileData();
static std::string GetFileNameSafeHash(const std::string& input);
// For testing only:
void SetTestFile(File* file); void SetTestFile(File* file);
#if defined(UNIT_TEST) #if defined(UNIT_TEST)
FRIEND_TEST(DeviceFilesSecurityLevelTest, SecurityLevel); FRIEND_TEST(DeviceFilesSecurityLevelTest, SecurityLevel);
FRIEND_TEST(DeviceFilesStoreTest, StoreCertificate); FRIEND_TEST(DeviceCertificateStoreTest, StoreCertificate);
FRIEND_TEST(DeviceCertificateTest, ReadCertificate);
FRIEND_TEST(DeviceCertificateTest, HasCertificate);
FRIEND_TEST(DeviceFilesStoreTest, StoreLicense); FRIEND_TEST(DeviceFilesStoreTest, StoreLicense);
FRIEND_TEST(DeviceFilesTest, DeleteLicense); FRIEND_TEST(DeviceFilesTest, DeleteLicense);
FRIEND_TEST(DeviceFilesTest, ReadCertificate);
FRIEND_TEST(DeviceFilesTest, ReserveLicenseIds); FRIEND_TEST(DeviceFilesTest, ReserveLicenseIds);
FRIEND_TEST(DeviceFilesTest, RetrieveLicenses); FRIEND_TEST(DeviceFilesTest, RetrieveLicenses);
FRIEND_TEST(DeviceFilesTest, SecurityLevelPathBackwardCompatibility); FRIEND_TEST(DeviceFilesTest, SecurityLevelPathBackwardCompatibility);

View File

@@ -75,6 +75,8 @@ static const std::string WEBM_VIDEO_MIME_TYPE = "video/webm";
static const std::string WEBM_AUDIO_MIME_TYPE = "audio/webm"; static const std::string WEBM_AUDIO_MIME_TYPE = "audio/webm";
static const std::string CENC_INIT_DATA_FORMAT = "cenc"; static const std::string CENC_INIT_DATA_FORMAT = "cenc";
static const std::string WEBM_INIT_DATA_FORMAT = "webm"; static const std::string WEBM_INIT_DATA_FORMAT = "webm";
static const char EMPTY_ORIGIN[] = "";
} // namespace wvcdm } // namespace wvcdm
#endif // WVCDM_CORE_WV_CDM_CONSTANTS_H_ #endif // WVCDM_CORE_WV_CDM_CONSTANTS_H_

View File

@@ -76,6 +76,7 @@ CdmEngine::~CdmEngine() {
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
const CdmClientPropertySet* property_set, const CdmClientPropertySet* property_set,
const std::string& origin,
WvCdmEventListener* event_listener, WvCdmEventListener* event_listener,
CdmSessionId* session_id) { CdmSessionId* session_id) {
LOGI("CdmEngine::OpenSession"); LOGI("CdmEngine::OpenSession");
@@ -91,7 +92,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
} }
scoped_ptr<CdmSession> new_session( scoped_ptr<CdmSession> new_session(
new CdmSession(property_set, event_listener)); new CdmSession(property_set, origin, event_listener));
if (new_session->session_id().empty()) { if (new_session->session_id().empty()) {
LOGE("CdmEngine::OpenSession: failure to generate session ID"); LOGE("CdmEngine::OpenSession: failure to generate session ID");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -115,7 +116,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
CdmResponseType CdmEngine::OpenKeySetSession( CdmResponseType CdmEngine::OpenKeySetSession(
const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set, const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set,
WvCdmEventListener* event_listener) { const std::string& origin, WvCdmEventListener* event_listener) {
LOGI("CdmEngine::OpenKeySetSession"); LOGI("CdmEngine::OpenKeySetSession");
if (key_set_id.empty()) { if (key_set_id.empty()) {
@@ -125,7 +126,8 @@ CdmResponseType CdmEngine::OpenKeySetSession(
CdmSessionId session_id; CdmSessionId session_id;
CdmResponseType sts = CdmResponseType sts =
OpenSession(KEY_SYSTEM, property_set, event_listener, &session_id); OpenSession(KEY_SYSTEM, property_set, origin, event_listener,
&session_id);
if (sts != NO_ERROR) return sts; if (sts != NO_ERROR) return sts;
@@ -503,9 +505,10 @@ CdmResponseType CdmEngine::QueryKeyControlInfo(const CdmSessionId& session_id,
*/ */
CdmResponseType CdmEngine::GetProvisioningRequest( CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority, CdmCertificateType cert_type, const std::string& cert_authority,
CdmProvisioningRequest* request, std::string* default_url) { const std::string& origin, CdmProvisioningRequest* request,
std::string* default_url) {
if (!request || !default_url) { if (!request || !default_url) {
LOGE("CdmEngine::GetProvisioningRequest: invalid input parameters"); LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
if (NULL == cert_provisioning_.get()) { if (NULL == cert_provisioning_.get()) {
@@ -513,7 +516,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
} }
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest( CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
cert_provisioning_requested_security_level_, cert_type, cert_authority, cert_provisioning_requested_security_level_, cert_type, cert_authority,
request, default_url); origin, request, default_url);
if (ret != NO_ERROR) { if (ret != NO_ERROR) {
cert_provisioning_.reset(NULL); // Release resources. cert_provisioning_.reset(NULL); // Release resources.
} }
@@ -528,8 +531,8 @@ 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, std::string* cert, const std::string& origin, CdmProvisioningResponse& response,
std::string* wrapped_key) { std::string* cert, std::string* wrapped_key) {
if (response.empty()) { if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response."); LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
cert_provisioning_.reset(NULL); cert_provisioning_.reset(NULL);
@@ -553,35 +556,55 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse(
response, cert, wrapped_key); origin, response, cert, wrapped_key);
cert_provisioning_.reset(NULL); // Release resources. cert_provisioning_.reset(NULL); // Release resources.
return ret; return ret;
} }
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level,
const std::string& origin) {
DeviceFiles handle;
if (!handle.Init(security_level)) {
LOGE("CdmEngine::IsProvisioned: unable to initialize device files");
return false;
}
return handle.HasCertificate(origin);
}
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level,
const std::string& origin) {
DeviceFiles handle; DeviceFiles handle;
if (!handle.Init(security_level)) { if (!handle.Init(security_level)) {
LOGE("CdmEngine::Unprovision: unable to initialize device files"); LOGE("CdmEngine::Unprovision: unable to initialize device files");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
if (!handle.DeleteAllFiles()) { if (origin != EMPTY_ORIGIN) {
LOGE("CdmEngine::Unprovision: unable to delete files"); if (!handle.RemoveCertificate(origin)) {
return UNKNOWN_ERROR; LOGE("CdmEngine::Unprovision: unable to delete certificate for origin %s",
} origin.c_str());
return UNKNOWN_ERROR;
}
return NO_ERROR;
} else {
if (!handle.DeleteAllFiles()) {
LOGE("CdmEngine::Unprovision: unable to delete files");
return UNKNOWN_ERROR;
}
scoped_ptr<CryptoSession> crypto_session(new CryptoSession()); scoped_ptr<CryptoSession> crypto_session(new CryptoSession());
CdmResponseType status = crypto_session->Open( CdmResponseType status = crypto_session->Open(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
if (NO_ERROR != status) { if (NO_ERROR != status) {
LOGE("CdmEngine::Unprovision: error opening crypto session: %d", status); LOGE("CdmEngine::Unprovision: error opening crypto session: %d", status);
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
}
status = crypto_session->DeleteAllUsageReports();
if (status != NO_ERROR) {
LOGE("CdmEngine::Unprovision: error deleteing usage reports: %d", status);
}
return status;
} }
status = crypto_session->DeleteAllUsageReports();
if (status != NO_ERROR) {
LOGE("CdmEngine::Unprovision: error deleteing usage reports: %d", status);
}
return status;
} }
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
@@ -592,7 +615,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
} }
usage_property_set_->set_security_level(kLevelDefault); usage_property_set_->set_security_level(kLevelDefault);
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get(), NULL)); usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL));
CdmResponseType status = usage_session_->Init(); CdmResponseType status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error"); LOGE("CdmEngine::GetUsageInfo: session init error");
@@ -610,7 +634,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
&license_response)) { &license_response)) {
usage_property_set_->set_security_level(kLevel3); usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get(), NULL)); usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL));
status = usage_session_->Init(); status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error"); LOGE("CdmEngine::GetUsageInfo: session init error");
@@ -678,7 +703,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_security_level(requested_security_level); usage_property_set_->set_security_level(requested_security_level);
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get(), NULL)); usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL));
CdmResponseType status = usage_session_->Init(); CdmResponseType status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {

View File

@@ -24,9 +24,11 @@ const size_t kKeySetIdLength = 14;
namespace wvcdm { namespace wvcdm {
CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set, CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set,
const std::string& origin,
WvCdmEventListener* event_listener) WvCdmEventListener* event_listener)
: initialized_(false), : initialized_(false),
session_id_(GenerateSessionId()), session_id_(GenerateSessionId()),
origin_(origin),
license_parser_(new CdmLicense), license_parser_(new CdmLicense),
crypto_session_(new CryptoSession), crypto_session_(new CryptoSession),
policy_engine_( policy_engine_(
@@ -70,7 +72,7 @@ CdmResponseType CdmSession::Init() {
if (Properties::use_certificates_as_identification()) { if (Properties::use_certificates_as_identification()) {
std::string wrapped_key; std::string wrapped_key;
if (!file_handle_->Init(security_level_) || if (!file_handle_->Init(security_level_) ||
!file_handle_->RetrieveCertificate(&token, &wrapped_key) || !file_handle_->RetrieveCertificate(origin_, &token, &wrapped_key) ||
!crypto_session_->LoadCertificatePrivateKey(wrapped_key)) { !crypto_session_->LoadCertificatePrivateKey(wrapped_key)) {
return NEED_PROVISIONING; return NEED_PROVISIONING;
} }

View File

@@ -57,8 +57,8 @@ void CertificateProvisioning::ComposeJsonRequestAsQueryString(
*/ */
CdmResponseType CertificateProvisioning::GetProvisioningRequest( CdmResponseType CertificateProvisioning::GetProvisioningRequest(
SecurityLevel requested_security_level, CdmCertificateType cert_type, SecurityLevel requested_security_level, CdmCertificateType cert_type,
const std::string& cert_authority, CdmProvisioningRequest* request, const std::string& cert_authority, const std::string& origin,
std::string* default_url) { CdmProvisioningRequest* request, 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");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -113,6 +113,15 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
cert_type_ = cert_type; cert_type_ = cert_type;
options->set_certificate_authority(cert_authority); options->set_certificate_authority(cert_authority);
if (origin != EMPTY_ORIGIN) {
std::string device_unique_id;
if (!crypto_session_.GetDeviceUniqueId(&device_unique_id)) {
LOGE("GetProvisioningRequest: fails to get device unique ID");
return UNKNOWN_ERROR;
}
provisioning_request.set_stable_id(device_unique_id + origin);
}
std::string serialized_message; std::string serialized_message;
provisioning_request.SerializeToString(&serialized_message); provisioning_request.SerializeToString(&serialized_message);
@@ -180,8 +189,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, std::string* cert, const std::string& origin, CdmProvisioningResponse& response,
std::string* wrapped_key) { std::string* cert, 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 = "\"";
@@ -255,7 +264,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
LOGE("HandleProvisioningResponse: failed to init DeviceFiles"); LOGE("HandleProvisioningResponse: failed to init DeviceFiles");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
if (!handle.StoreCertificate(device_certificate, wrapped_rsa_key)) { if (!handle.StoreCertificate(origin, device_certificate, wrapped_rsa_key)) {
LOGE("HandleProvisioningResponse: failed to save provisioning certificate"); LOGE("HandleProvisioningResponse: failed to save provisioning certificate");
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }

View File

@@ -10,6 +10,7 @@
#include "log.h" #include "log.h"
#include "properties.h" #include "properties.h"
#include "string_conversions.h" #include "string_conversions.h"
#include "wv_cdm_constants.h"
#if defined(__APPLE__) #if defined(__APPLE__)
#include <CommonCrypto/CommonDigest.h> #include <CommonCrypto/CommonDigest.h>
@@ -31,7 +32,8 @@ using video_widevine_client::sdk::UsageInfo_ProviderSession;
namespace { namespace {
const char kCertificateFileName[] = "cert.bin"; const char kCertificateFileNamePrefix[] = "cert";
const char kCertificateFileNameExt[] = ".bin";
const char kUsageInfoFileNamePrefix[] = "usage"; const char kUsageInfoFileNamePrefix[] = "usage";
const char kUsageInfoFileNameExt[] = ".bin"; const char kUsageInfoFileNameExt[] = ".bin";
const char kLicenseFileNameExt[] = ".lic"; const char kLicenseFileNameExt[] = ".lic";
@@ -86,7 +88,8 @@ bool DeviceFiles::Init(CdmSecurityLevel security_level) {
return true; return true;
} }
bool DeviceFiles::StoreCertificate(const std::string& certificate, bool DeviceFiles::StoreCertificate(const std::string& origin,
const std::string& certificate,
const std::string& wrapped_private_key) { const std::string& wrapped_private_key) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::StoreCertificate: not initialized"); LOGW("DeviceFiles::StoreCertificate: not initialized");
@@ -106,10 +109,11 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate,
std::string serialized_file; std::string serialized_file;
file.SerializeToString(&serialized_file); file.SerializeToString(&serialized_file);
return StoreFileWithHash(kCertificateFileName, serialized_file); return StoreFileWithHash(GetCertificateFileName(origin), serialized_file);
} }
bool DeviceFiles::RetrieveCertificate(std::string* certificate, bool DeviceFiles::RetrieveCertificate(const std::string& origin,
std::string* certificate,
std::string* wrapped_private_key) { std::string* wrapped_private_key) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::RetrieveCertificate: not initialized"); LOGW("DeviceFiles::RetrieveCertificate: not initialized");
@@ -121,7 +125,9 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
} }
std::string serialized_file; std::string serialized_file;
if (!RetrieveHashedFile(kCertificateFileName, &serialized_file)) return false; if (!RetrieveHashedFile(GetCertificateFileName(origin), &serialized_file)) {
return false;
}
video_widevine_client::sdk::File file; video_widevine_client::sdk::File file;
if (!file.ParseFromString(serialized_file)) { if (!file.ParseFromString(serialized_file)) {
@@ -151,6 +157,24 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate,
return true; return true;
} }
bool DeviceFiles::HasCertificate(const std::string& origin) {
if (!initialized_) {
LOGW("DeviceFiles::HasCertificate: not initialized");
return false;
}
return FileExists(GetCertificateFileName(origin));
}
bool DeviceFiles::RemoveCertificate(const std::string& origin) {
if (!initialized_) {
LOGW("DeviceFiles::RemoveCertificate: not initialized");
return false;
}
return RemoveFile(GetCertificateFileName(origin));
}
bool DeviceFiles::StoreLicense(const std::string& key_set_id, bool DeviceFiles::StoreLicense(const std::string& key_set_id,
const LicenseState state, const LicenseState state,
const CdmInitData& pssh_data, const CdmInitData& pssh_data,
@@ -749,8 +773,12 @@ void DeviceFiles::SecurityLevelPathBackwardCompatibility() {
} }
} }
std::string DeviceFiles::GetCertificateFileName() { std::string DeviceFiles::GetCertificateFileName(const std::string& origin) {
return kCertificateFileName; std::string hash;
if (origin != EMPTY_ORIGIN) {
hash = GetFileNameSafeHash(origin);
}
return kCertificateFileNamePrefix + hash + kCertificateFileNameExt;
} }
std::string DeviceFiles::GetLicenseFileNameExtension() { std::string DeviceFiles::GetLicenseFileNameExtension() {
@@ -758,20 +786,23 @@ 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 == "") { std::string hash;
return std::string(kUsageInfoFileNamePrefix) + if (app_id != "") {
std::string(kUsageInfoFileNameExt); hash = GetFileNameSafeHash(app_id);
} }
std::vector<uint8_t> hash(MD5_DIGEST_LENGTH); return kUsageInfoFileNamePrefix + hash + kUsageInfoFileNameExt;
const unsigned char* input =
reinterpret_cast<const unsigned char*>(app_id.data());
MD5(input, app_id.size(), &hash[0]);
return std::string(kUsageInfoFileNamePrefix) + wvcdm::Base64SafeEncode(hash) +
std::string(kUsageInfoFileNameExt);
} }
std::string DeviceFiles::GetBlankFileData() { return kBlankFileData; } std::string DeviceFiles::GetBlankFileData() { return kBlankFileData; }
std::string DeviceFiles::GetFileNameSafeHash(const std::string& input) {
std::vector<uint8_t> hash(MD5_DIGEST_LENGTH);
const unsigned char* input_ptr =
reinterpret_cast<const unsigned char*>(input.data());
MD5(input_ptr, input.size(), &hash[0]);
return wvcdm::Base64SafeEncode(hash);
}
void DeviceFiles::SetTestFile(File* file) { void DeviceFiles::SetTestFile(File* file) {
file_.reset(file); file_.reset(file);
test_file_ = true; test_file_ = true;

View File

@@ -48,10 +48,12 @@ class WvCdmEngineTest : public testing::Test {
public: public:
virtual void SetUp() { virtual void SetUp() {
CdmResponseType status = CdmResponseType status =
cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_); cdm_engine_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
&session_id_);
if (status == NEED_PROVISIONING) { if (status == NEED_PROVISIONING) {
Provision(); Provision();
status = cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_); status = cdm_engine_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
&session_id_);
} }
ASSERT_EQ(NO_ERROR, status); ASSERT_EQ(NO_ERROR, status);
ASSERT_NE("", session_id_) << "Could not open CDM session."; ASSERT_NE("", session_id_) << "Could not open CDM session.";
@@ -67,14 +69,15 @@ class WvCdmEngineTest : public testing::Test {
std::string cert_authority; std::string cert_authority;
std::string cert, wrapped_key; std::string cert, wrapped_key;
ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest( ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, &prov_request, cert_type, cert_authority, EMPTY_ORIGIN,
&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, cdm_engine_.HandleProvisioningResponse(message, &cert, ASSERT_EQ(NO_ERROR, cdm_engine_.HandleProvisioningResponse(EMPTY_ORIGIN,
message, &cert,
&wrapped_key)); &wrapped_key));
} }

View File

@@ -8,6 +8,7 @@
#include "scoped_ptr.h" #include "scoped_ptr.h"
#include "string_conversions.h" #include "string_conversions.h"
#include "test_printers.h" #include "test_printers.h"
#include "wv_cdm_constants.h"
namespace { namespace {
const std::string kToken = wvcdm::a2bs_hex( const std::string kToken = wvcdm::a2bs_hex(
@@ -83,6 +84,9 @@ const std::string kWrappedKey = wvcdm::a2bs_hex(
"33EF70621A98184DDAB5E14BC971CF98CF6C91A37FFA83B00AD3BCABBAAB2DEF1C52F43003" "33EF70621A98184DDAB5E14BC971CF98CF6C91A37FFA83B00AD3BCABBAAB2DEF1C52F43003"
"E74C92B44F9205D22262FB47948654229DE1920F8EDF96A19A88A1CA1552F8856FB4CBF83B" "E74C92B44F9205D22262FB47948654229DE1920F8EDF96A19A88A1CA1552F8856FB4CBF83B"
"AA3348419159D207F65FCE9C1A500C6818"); "AA3348419159D207F65FCE9C1A500C6818");
const std::string kTestOrigin = "com.google";
} // namespace } // namespace
namespace wvcdm { namespace wvcdm {
@@ -99,7 +103,8 @@ using ::testing::StrEq;
class MockDeviceFiles : public DeviceFiles { class MockDeviceFiles : public DeviceFiles {
public: public:
MOCK_METHOD1(Init, bool(CdmSecurityLevel)); MOCK_METHOD1(Init, bool(CdmSecurityLevel));
MOCK_METHOD2(RetrieveCertificate, bool(std::string*, std::string*)); MOCK_METHOD3(RetrieveCertificate, bool(const std::string&, std::string*,
std::string*));
}; };
class MockCryptoSession : public CryptoSession { class MockCryptoSession : public CryptoSession {
@@ -127,7 +132,7 @@ class MockCdmLicense : public CdmLicense {
class CdmSessionTest : public ::testing::Test { class CdmSessionTest : public ::testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
cdm_session_.reset(new CdmSession(NULL, NULL)); cdm_session_.reset(new CdmSession(NULL, kTestOrigin, NULL));
// Inject testing mocks. // Inject testing mocks.
license_parser_ = new MockCdmLicense(); license_parser_ = new MockCdmLicense();
cdm_session_->set_license_parser(license_parser_); cdm_session_->set_license_parser(license_parser_);
@@ -156,8 +161,9 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
.InSequence(crypto_session_seq) .InSequence(crypto_session_seq)
.WillOnce(Return(level)); .WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
.WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey), NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true))); Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq) .InSequence(crypto_session_seq)
@@ -202,8 +208,9 @@ TEST_F(CdmSessionTest, ReInitFail) {
.InSequence(crypto_session_seq) .InSequence(crypto_session_seq)
.WillOnce(Return(level)); .WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
.WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey), NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true))); Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq) .InSequence(crypto_session_seq)
@@ -238,7 +245,8 @@ TEST_F(CdmSessionTest, InitNeedsProvisioning) {
.InSequence(crypto_session_seq) .InSequence(crypto_session_seq)
.WillOnce(Return(level)); .WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
NotNull()))
.WillOnce(Return(false)); .WillOnce(Return(false));
Properties::set_use_certificates_as_identification(true); Properties::set_use_certificates_as_identification(true);

View File

@@ -1,11 +1,13 @@
// Copyright 2013 Google Inc. All Rights Reserved. // Copyright 2013 Google Inc. All Rights Reserved.
#include <string>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "device_files.h" #include "device_files.h"
#include "file_store.h" #include "file_store.h"
#include "properties.h" #include "properties.h"
#include "string_conversions.h" #include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h" #include "wv_cdm_types.h"
namespace wvcdm { namespace wvcdm {
@@ -1230,6 +1232,8 @@ UsageInfo kUsageInfoTestData[] = {
"0E12202FF1FBA9926A24A1F79970EC427DDF87B4421488F7952499BC33CEB282D9E48" "0E12202FF1FBA9926A24A1F79970EC427DDF87B4421488F7952499BC33CEB282D9E48"
"A")}}; "A")}};
const std::string kTestOrigin = "com.google";
} // namespace } // namespace
class MockFile : public File { class MockFile : public File {
@@ -1278,6 +1282,23 @@ class DeviceFilesTest : public ::testing::Test {
class DeviceFilesStoreTest : public DeviceFilesTest, class DeviceFilesStoreTest : public DeviceFilesTest,
public ::testing::WithParamInterface<bool> {}; public ::testing::WithParamInterface<bool> {};
struct CertStorageVariant {
CertStorageVariant(bool dir_exists_value, const std::string& origin_value)
: dir_exists(dir_exists_value),
origin(origin_value) {}
const bool dir_exists;
const std::string origin;
};
class DeviceCertificateStoreTest
: public DeviceFilesTest,
public ::testing::WithParamInterface<CertStorageVariant> {};
class DeviceCertificateTest
: public DeviceFilesTest,
public ::testing::WithParamInterface<std::string> {};
class DeviceFilesSecurityLevelTest class DeviceFilesSecurityLevelTest
: public DeviceFilesTest, : public DeviceFilesTest,
public ::testing::WithParamInterface<CdmSecurityLevel> {}; public ::testing::WithParamInterface<CdmSecurityLevel> {};
@@ -1323,17 +1344,17 @@ MATCHER_P6(Contains, str1, str2, str3, str4, str5, str6, "") {
data.find(str6) != std::string::npos); data.find(str6) != std::string::npos);
} }
TEST_P(DeviceFilesStoreTest, StoreCertificate) { TEST_P(DeviceCertificateStoreTest, StoreCertificate) {
MockFile file; MockFile file;
CertStorageVariant params = GetParam();
std::string certificate(GenerateRandomData(kCertificateLen)); std::string certificate(GenerateRandomData(kCertificateLen));
std::string wrapped_private_key(GenerateRandomData(kWrappedKeyLen)); std::string wrapped_private_key(GenerateRandomData(kWrappedKeyLen));
std::string device_certificate_path = std::string device_certificate_path =
device_base_path_ + DeviceFiles::GetCertificateFileName(); device_base_path_ + DeviceFiles::GetCertificateFileName(params.origin);
bool dir_exists = GetParam();
EXPECT_CALL(file, IsDirectory(StrEq(device_base_path_))) EXPECT_CALL(file, IsDirectory(StrEq(device_base_path_)))
.WillOnce(Return(dir_exists)); .WillOnce(Return(params.dir_exists));
if (dir_exists) { if (params.dir_exists) {
EXPECT_CALL(file, CreateDirectory(_)).Times(0); EXPECT_CALL(file, CreateDirectory(_)).Times(0);
} else { } else {
EXPECT_CALL(file, CreateDirectory(StrEq(device_base_path_))) EXPECT_CALL(file, CreateDirectory(StrEq(device_base_path_)))
@@ -1352,16 +1373,22 @@ TEST_P(DeviceFilesStoreTest, StoreCertificate) {
DeviceFiles device_files; DeviceFiles device_files;
EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
device_files.SetTestFile(&file); device_files.SetTestFile(&file);
EXPECT_TRUE(device_files.StoreCertificate(certificate, wrapped_private_key)); EXPECT_TRUE(device_files.StoreCertificate(params.origin, certificate,
wrapped_private_key));
} }
INSTANTIATE_TEST_CASE_P(StoreCertificate, DeviceFilesStoreTest, INSTANTIATE_TEST_CASE_P(
::testing::Bool()); StoreCertificate, DeviceCertificateStoreTest,
::testing::Values(CertStorageVariant(true, EMPTY_ORIGIN),
CertStorageVariant(true, kTestOrigin),
CertStorageVariant(false, EMPTY_ORIGIN),
CertStorageVariant(false, kTestOrigin)));
TEST_F(DeviceFilesTest, ReadCertificate) { TEST_P(DeviceCertificateTest, ReadCertificate) {
MockFile file; MockFile file;
std::string origin = GetParam();
std::string device_certificate_path = std::string device_certificate_path =
device_base_path_ + DeviceFiles::GetCertificateFileName(); device_base_path_ + DeviceFiles::GetCertificateFileName(origin);
std::string data = a2bs_hex(kTestCertificateFileData); std::string data = a2bs_hex(kTestCertificateFileData);
EXPECT_CALL(file, Exists(StrEq(device_certificate_path))) EXPECT_CALL(file, Exists(StrEq(device_certificate_path)))
@@ -1382,11 +1409,36 @@ TEST_F(DeviceFilesTest, ReadCertificate) {
std::string certificate, wrapped_private_key; std::string certificate, wrapped_private_key;
ASSERT_TRUE( ASSERT_TRUE(
device_files.RetrieveCertificate(&certificate, &wrapped_private_key)); device_files.RetrieveCertificate(origin, &certificate,
&wrapped_private_key));
EXPECT_EQ(kTestCertificate, b2a_hex(certificate)); EXPECT_EQ(kTestCertificate, b2a_hex(certificate));
EXPECT_EQ(kTestWrappedPrivateKey, b2a_hex(wrapped_private_key)); EXPECT_EQ(kTestWrappedPrivateKey, b2a_hex(wrapped_private_key));
} }
TEST_P(DeviceCertificateTest, HasCertificate) {
MockFile file;
std::string origin = GetParam();
std::string device_certificate_path =
device_base_path_ + DeviceFiles::GetCertificateFileName(origin);
EXPECT_CALL(file, Exists(StrEq(device_certificate_path)))
.WillOnce(Return(false))
.WillOnce(Return(true));
EXPECT_CALL(file, Open(_, _)).Times(0);
DeviceFiles device_files;
ASSERT_TRUE(device_files.Init(kSecurityLevelL1));
device_files.SetTestFile(&file);
// MockFile returns false.
EXPECT_FALSE(device_files.HasCertificate(origin));
// MockFile returns true.
EXPECT_TRUE(device_files.HasCertificate(origin));
}
INSTANTIATE_TEST_CASE_P(CertificateUseTests, DeviceCertificateTest,
::testing::Values(EMPTY_ORIGIN, kTestOrigin));
TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) { TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) {
MockFile file; MockFile file;
std::string certificate(GenerateRandomData(kCertificateLen)); std::string certificate(GenerateRandomData(kCertificateLen));
@@ -1397,7 +1449,7 @@ TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) {
ASSERT_TRUE( ASSERT_TRUE(
Properties::GetDeviceFilesBasePath(security_level, &device_base_path)); Properties::GetDeviceFilesBasePath(security_level, &device_base_path));
std::string device_certificate_path = std::string device_certificate_path =
device_base_path + DeviceFiles::GetCertificateFileName(); device_base_path + DeviceFiles::GetCertificateFileName(EMPTY_ORIGIN);
EXPECT_CALL(file, IsDirectory(StrEq(device_base_path))) EXPECT_CALL(file, IsDirectory(StrEq(device_base_path)))
.WillOnce(Return(false)); .WillOnce(Return(false));
@@ -1416,7 +1468,8 @@ TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) {
DeviceFiles device_files; DeviceFiles device_files;
EXPECT_TRUE(device_files.Init(security_level)); EXPECT_TRUE(device_files.Init(security_level));
device_files.SetTestFile(&file); device_files.SetTestFile(&file);
EXPECT_TRUE(device_files.StoreCertificate(certificate, wrapped_private_key)); EXPECT_TRUE(device_files.StoreCertificate(EMPTY_ORIGIN, certificate,
wrapped_private_key));
} }
INSTANTIATE_TEST_CASE_P(SecurityLevel, DeviceFilesSecurityLevelTest, INSTANTIATE_TEST_CASE_P(SecurityLevel, DeviceFilesSecurityLevelTest,
@@ -1595,13 +1648,15 @@ TEST_F(DeviceFilesTest, SecurityLevelPathBackwardCompatibility) {
EXPECT_CALL(file, CreateDirectory(StrEq(new_path))).WillOnce(Return(true)); EXPECT_CALL(file, CreateDirectory(StrEq(new_path))).WillOnce(Return(true));
} }
std::string old_path = base_path + DeviceFiles::GetCertificateFileName(); std::string old_path =
old_files.push_back(DeviceFiles::GetCertificateFileName()); base_path + DeviceFiles::GetCertificateFileName(EMPTY_ORIGIN);
old_files.push_back(DeviceFiles::GetCertificateFileName(EMPTY_ORIGIN));
EXPECT_CALL(file, IsRegularFile(StrEq(old_path))).WillOnce(Return(true)); EXPECT_CALL(file, IsRegularFile(StrEq(old_path))).WillOnce(Return(true));
EXPECT_CALL(file, Remove(StrEq(old_path))).WillOnce(Return(true)); EXPECT_CALL(file, Remove(StrEq(old_path))).WillOnce(Return(true));
for (size_t i = 0; i < security_dirs.size(); ++i) { for (size_t i = 0; i < security_dirs.size(); ++i) {
new_path = new_path =
base_path + security_dirs[i] + DeviceFiles::GetCertificateFileName(); base_path + security_dirs[i] +
DeviceFiles::GetCertificateFileName(EMPTY_ORIGIN);
EXPECT_CALL(file, Copy(StrEq(old_path), StrEq(new_path))) EXPECT_CALL(file, Copy(StrEq(old_path), StrEq(new_path)))
.WillOnce(Return(true)); .WillOnce(Return(true));
} }
@@ -1625,7 +1680,8 @@ TEST_F(DeviceFilesTest, SecurityLevelPathBackwardCompatibility) {
std::string data = a2bs_hex(kTestCertificateFileData); std::string data = a2bs_hex(kTestCertificateFileData);
new_path = device_base_path_ + DeviceFiles::GetCertificateFileName(); new_path =
device_base_path_ + DeviceFiles::GetCertificateFileName(EMPTY_ORIGIN);
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));
@@ -1642,7 +1698,8 @@ TEST_F(DeviceFilesTest, SecurityLevelPathBackwardCompatibility) {
Properties::Init(); Properties::Init();
std::string certificate, wrapped_private_key; std::string certificate, wrapped_private_key;
ASSERT_TRUE( ASSERT_TRUE(
device_files.RetrieveCertificate(&certificate, &wrapped_private_key)); device_files.RetrieveCertificate(EMPTY_ORIGIN, &certificate,
&wrapped_private_key));
} }
TEST_F(DeviceFilesTest, UpdateLicenseState) { TEST_F(DeviceFilesTest, UpdateLicenseState) {

View File

@@ -28,6 +28,7 @@ class WvContentDecryptionModule : public TimerHandler {
// Session related methods // Session related methods
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system, virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
CdmClientPropertySet* property_set, CdmClientPropertySet* property_set,
const std::string& origin,
WvCdmEventListener* event_listener, WvCdmEventListener* event_listener,
CdmSessionId* session_id); CdmSessionId* session_id);
virtual CdmResponseType CloseSession(const CdmSessionId& session_id); virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
@@ -40,6 +41,7 @@ class WvContentDecryptionModule : public TimerHandler {
const CdmLicenseType license_type, const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters, CdmAppParameterMap& app_parameters,
CdmClientPropertySet* property_set, CdmClientPropertySet* property_set,
const std::string& origin,
CdmKeyMessage* key_request, CdmKeyMessage* key_request,
CdmKeyRequestType* key_request_type, CdmKeyRequestType* key_request_type,
std::string* server_url); std::string* server_url);
@@ -75,15 +77,18 @@ class WvContentDecryptionModule : public TimerHandler {
virtual CdmResponseType GetProvisioningRequest( virtual CdmResponseType GetProvisioningRequest(
CdmCertificateType cert_type, CdmCertificateType cert_type,
const std::string& cert_authority, const std::string& cert_authority,
const std::string& origin,
CdmProvisioningRequest* request, CdmProvisioningRequest* request,
std::string* default_url); std::string* default_url);
virtual CdmResponseType HandleProvisioningResponse( virtual CdmResponseType HandleProvisioningResponse(
const std::string& origin,
CdmProvisioningResponse& response, CdmProvisioningResponse& response,
std::string* cert, std::string* cert,
std::string* wrapped_key); std::string* wrapped_key);
virtual CdmResponseType Unprovision(CdmSecurityLevel level); virtual CdmResponseType Unprovision(CdmSecurityLevel level,
const std::string& origin);
// Secure stop related methods // Secure stop related methods
virtual CdmResponseType GetUsageInfo(const std::string& app_id, virtual CdmResponseType GetUsageInfo(const std::string& app_id,

View File

@@ -39,15 +39,16 @@ bool WvContentDecryptionModule::IsWebm(const std::string& init_data_type) {
CdmResponseType WvContentDecryptionModule::OpenSession( CdmResponseType WvContentDecryptionModule::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set, const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
WvCdmEventListener* event_listener, CdmSessionId* session_id) { const std::string& origin, WvCdmEventListener* event_listener,
CdmSessionId* session_id) {
if (property_set && property_set->is_session_sharing_enabled()) { if (property_set && property_set->is_session_sharing_enabled()) {
AutoLock auto_lock(session_sharing_id_generation_lock_); AutoLock auto_lock(session_sharing_id_generation_lock_);
if (property_set->session_sharing_id() == 0) if (property_set->session_sharing_id() == 0)
property_set->set_session_sharing_id(GenerateSessionSharingId()); property_set->set_session_sharing_id(GenerateSessionSharingId());
} }
return cdm_engine_->OpenSession(key_system, property_set, event_listener, return cdm_engine_->OpenSession(key_system, property_set, origin,
session_id); event_listener, session_id);
} }
CdmResponseType WvContentDecryptionModule::CloseSession( CdmResponseType WvContentDecryptionModule::CloseSession(
@@ -61,11 +62,13 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
const std::string& init_data_type, const CdmInitData& init_data, const std::string& init_data_type, const CdmInitData& init_data,
const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters,
CdmClientPropertySet* property_set, CdmKeyMessage* key_request, CdmClientPropertySet* property_set, const std::string& origin,
CdmKeyRequestType* key_request_type, std::string* server_url) { CdmKeyMessage* key_request, CdmKeyRequestType* key_request_type,
std::string* server_url) {
CdmResponseType sts; CdmResponseType sts;
if (license_type == kLicenseTypeRelease) { if (license_type == kLicenseTypeRelease) {
sts = cdm_engine_->OpenKeySetSession(key_set_id, property_set, NULL); sts = cdm_engine_->OpenKeySetSession(key_set_id, property_set, origin,
NULL);
if (sts != NO_ERROR) return sts; if (sts != NO_ERROR) return sts;
} }
InitializationData initialization_data(init_data_type, init_data); InitializationData initialization_data(init_data_type, init_data);
@@ -132,22 +135,26 @@ CdmResponseType WvContentDecryptionModule::QueryKeyControlInfo(
CdmResponseType WvContentDecryptionModule::GetProvisioningRequest( CdmResponseType WvContentDecryptionModule::GetProvisioningRequest(
CdmCertificateType cert_type, CdmCertificateType cert_type,
const std::string& cert_authority, const std::string& cert_authority,
const std::string& origin,
CdmProvisioningRequest* request, CdmProvisioningRequest* request,
std::string* default_url) { std::string* default_url) {
return cdm_engine_->GetProvisioningRequest(cert_type, cert_authority, return cdm_engine_->GetProvisioningRequest(cert_type, cert_authority, origin,
request, default_url); request, default_url);
} }
CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse( CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse(
const std::string& origin,
CdmProvisioningResponse& response, CdmProvisioningResponse& response,
std::string* cert, std::string* cert,
std::string* wrapped_key) { std::string* wrapped_key) {
return cdm_engine_->HandleProvisioningResponse(response, cert, wrapped_key); return cdm_engine_->HandleProvisioningResponse(origin, response, cert,
wrapped_key);
} }
CdmResponseType WvContentDecryptionModule::Unprovision( CdmResponseType WvContentDecryptionModule::Unprovision(
CdmSecurityLevel level) { CdmSecurityLevel level,
return cdm_engine_->Unprovision(level); const std::string& origin) {
return cdm_engine_->Unprovision(level, origin);
} }
CdmResponseType WvContentDecryptionModule::GetUsageInfo( CdmResponseType WvContentDecryptionModule::GetUsageInfo(

View File

@@ -268,8 +268,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
CdmKeyRequestType key_request_type; CdmKeyRequestType key_request_type;
EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest( EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest(
session_id_, key_set_id_, "video/mp4", init_data, session_id_, key_set_id_, "video/mp4", init_data,
license_type, app_parameters, NULL, &key_msg_, license_type, app_parameters, NULL, EMPTY_ORIGIN,
&key_request_type, &server_url)); &key_msg_, &key_request_type, &server_url));
EXPECT_EQ(kKeyRequestTypeInitial, key_request_type); EXPECT_EQ(kKeyRequestTypeInitial, key_request_type);
EXPECT_EQ(0u, server_url.size()); EXPECT_EQ(0u, server_url.size());
} }
@@ -283,8 +283,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
CdmKeyRequestType key_request_type; CdmKeyRequestType key_request_type;
EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest( EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest(
session_id_, key_set_id_, "video/mp4", init_data, session_id_, key_set_id_, "video/mp4", init_data,
license_type, app_parameters, NULL, &key_msg_, license_type, app_parameters, NULL, EMPTY_ORIGIN,
&key_request_type, server_url)); &key_msg_, &key_request_type, server_url));
EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type); EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type);
// TODO(edwinwong, rfrias): Add tests cases for when license server url // TODO(edwinwong, rfrias): Add tests cases for when license server url
// is empty on renewal. Need appropriate key id at the server. // is empty on renewal. Need appropriate key id at the server.
@@ -300,7 +300,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest( EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest(
session_id, key_set_id, "video/mp4", init_data, session_id, key_set_id, "video/mp4", init_data,
kLicenseTypeRelease, app_parameters, NULL, kLicenseTypeRelease, app_parameters, NULL,
&key_msg_, &key_request_type, &server_url)); EMPTY_ORIGIN, &key_msg_, &key_request_type,
&server_url));
EXPECT_EQ(kKeyRequestTypeRelease, key_request_type); EXPECT_EQ(kKeyRequestTypeRelease, key_request_type);
} }
@@ -398,13 +399,14 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
} }
void Unprovision() { void Unprovision() {
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1)); EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, EMPTY_ORIGIN));
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3)); EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, EMPTY_ORIGIN));
} }
void Provision() { void Provision() {
CdmResponseType status = CdmResponseType status =
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
&session_id_);
switch (status) { switch (status) {
case NO_ERROR: case NO_ERROR:
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -421,7 +423,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
status = decryptor_.GetProvisioningRequest( status = decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, &provisioning_server_url); cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
&provisioning_server_url);
EXPECT_EQ(NO_ERROR, status); EXPECT_EQ(NO_ERROR, status);
if (NO_ERROR != status) return; if (NO_ERROR != status) return;
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
@@ -429,8 +432,9 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert, EXPECT_EQ(NO_ERROR,
&wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -614,7 +618,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
} }
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) { std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
decryptor_.OpenSession(g_key_system, property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
&session_id_);
CdmQueryMap query_info; CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, EXPECT_EQ(NO_ERROR,
decryptor_.QuerySessionStatus(session_id_, &query_info)); decryptor_.QuerySessionStatus(session_id_, &query_info));
@@ -647,7 +652,7 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) { TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
EXPECT_TRUE(!key_msg_.empty()); EXPECT_TRUE(!key_msg_.empty());
@@ -715,7 +720,7 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) { TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -803,7 +808,8 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) {
EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &provider_session_tokens)); EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &provider_session_tokens));
for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) { for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) {
decryptor_.OpenSession(g_key_system, property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
&session_id_);
std::string key_id = a2bs_hex( std::string key_id = a2bs_hex(
"000000427073736800000000" // blob size and pssh "000000427073736800000000" // blob size and pssh
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
@@ -843,7 +849,7 @@ TEST_P(WvCdmStreamingNoPstTest, UsageTest) {
Unprovision(); Unprovision();
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -917,7 +923,7 @@ TEST_P(WvCdmStreamingPstTest, UsageTest) {
Unprovision(); Unprovision();
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming); GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -982,7 +988,7 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) {
Unprovision(); Unprovision();
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming); GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1078,7 +1084,7 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
Unprovision(); Unprovision();
Provision(); Provision();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline); GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1101,7 +1107,7 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
for (size_t i = 0; i < GetParam(); ++i) { for (size_t i = 0; i < GetParam(); ++i) {
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
// Query and validate usage information // Query and validate usage information
@@ -1144,7 +1150,7 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
} }
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
// Query and validate usage information // Query and validate usage information

View File

@@ -493,7 +493,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
EXPECT_EQ(wvcdm::KEY_MESSAGE, EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest( decryptor_.GenerateKeyRequest(
session_id_, key_set_id, "video/mp4", init_data, license_type, session_id_, key_set_id, "video/mp4", init_data, license_type,
app_parameters, property_set, &key_msg_, NULL, &server_url)); app_parameters, property_set, EMPTY_ORIGIN, &key_msg_, NULL,
&server_url));
EXPECT_EQ(0u, server_url.size()); EXPECT_EQ(0u, server_url.size());
} }
@@ -513,8 +514,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
EXPECT_EQ(wvcdm::KEY_MESSAGE, EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest( decryptor_.GenerateKeyRequest(
session_id_, key_set_id_, "video/mp4", init_data, session_id_, key_set_id_, "video/mp4", init_data,
license_type, app_parameters, property_set, &key_msg_, license_type, app_parameters, property_set, EMPTY_ORIGIN,
&key_request_type, server_url)); &key_msg_, &key_request_type, server_url));
EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type); EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type);
// TODO(edwinwong, rfrias): Add tests cases for when license server url // TODO(edwinwong, rfrias): Add tests cases for when license server url
// is empty on renewal. Need appropriate key id at the server. // is empty on renewal. Need appropriate key id at the server.
@@ -535,8 +536,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
EXPECT_EQ(wvcdm::KEY_MESSAGE, EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest( decryptor_.GenerateKeyRequest(
session_id, key_set_id, "video/mp4", init_data, session_id, key_set_id, "video/mp4", init_data,
kLicenseTypeRelease, app_parameters, property_set, &key_msg_, kLicenseTypeRelease, app_parameters, property_set,
&key_request_type, &server_url)); EMPTY_ORIGIN, &key_msg_, &key_request_type, &server_url));
EXPECT_EQ(kKeyRequestTypeRelease, key_request_type); EXPECT_EQ(kKeyRequestTypeRelease, key_request_type);
} }
@@ -635,8 +636,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
} }
void Unprovision() { void Unprovision() {
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1)); EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, EMPTY_ORIGIN));
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3)); EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, EMPTY_ORIGIN));
} }
void Provision(SecurityLevel level) { void Provision(SecurityLevel level) {
@@ -649,7 +650,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
} }
CdmResponseType status = CdmResponseType status =
decryptor_.OpenSession(g_key_system, property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
&session_id_);
switch (status) { switch (status) {
case NO_ERROR: case NO_ERROR:
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -666,7 +668,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
status = decryptor_.GetProvisioningRequest( status = decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, &provisioning_server_url); cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
&provisioning_server_url);
EXPECT_EQ(wvcdm::NO_ERROR, status); EXPECT_EQ(wvcdm::NO_ERROR, status);
if (NO_ERROR != status) return; if (NO_ERROR != status) return;
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
@@ -674,8 +677,9 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::NO_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -683,7 +687,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
} }
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) { std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, property_set, NULL, EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, property_set,
EMPTY_ORIGIN, NULL,
&session_id_)); &session_id_));
CdmQueryMap query_info; CdmQueryMap query_info;
EXPECT_EQ(wvcdm::NO_ERROR, EXPECT_EQ(wvcdm::NO_ERROR,
@@ -720,21 +725,22 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
}; };
TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) { TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::NO_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -748,48 +754,52 @@ TEST_F(WvCdmRequestLicenseTest, UnprovisionTest) {
handle.SetTestFile(&file); handle.SetTestFile(&file);
std::string certificate; std::string certificate;
std::string wrapped_private_key; std::string wrapped_private_key;
EXPECT_TRUE(handle.RetrieveCertificate(&certificate, &wrapped_private_key)); EXPECT_TRUE(handle.RetrieveCertificate(EMPTY_ORIGIN, &certificate,
&wrapped_private_key));
EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(security_level)); EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(security_level, EMPTY_ORIGIN));
EXPECT_FALSE(handle.RetrieveCertificate(&certificate, &wrapped_private_key)); EXPECT_FALSE(handle.RetrieveCertificate(EMPTY_ORIGIN, &certificate,
&wrapped_private_key));
} }
TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) { TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::NO_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
response = response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::UNKNOWN_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::UNKNOWN_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
} }
TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) { TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateX509; CdmCertificateType cert_type = kCertificateX509;
// TODO(rfrias): insert appropriate CA here // TODO(rfrias): insert appropriate CA here
@@ -797,15 +807,16 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) {
std::string cert, wrapped_key; std::string cert, wrapped_key;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::NO_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_NE(0, static_cast<int>(cert.size())); EXPECT_NE(0, static_cast<int>(cert.size()));
EXPECT_NE(0, static_cast<int>(wrapped_key.size())); EXPECT_NE(0, static_cast<int>(wrapped_key.size()));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -821,34 +832,39 @@ TEST_F(WvCdmRequestLicenseTest, PropertySetTest) {
property_set_L1.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L1); property_set_L1.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L1);
property_set_L1.set_use_privacy_mode(true); property_set_L1.set_use_privacy_mode(true);
decryptor_.OpenSession(g_key_system, &property_set_L1, NULL, &session_id_L1); decryptor_.OpenSession(g_key_system, &property_set_L1, EMPTY_ORIGIN, NULL,
&session_id_L1);
property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
property_set_L3.set_use_privacy_mode(false); property_set_L3.set_use_privacy_mode(false);
CdmResponseType sts = decryptor_.OpenSession(g_key_system, &property_set_L3, CdmResponseType sts = decryptor_.OpenSession(g_key_system, &property_set_L3,
NULL, &session_id_L3); EMPTY_ORIGIN, NULL,
&session_id_L3);
if (NEED_PROVISIONING == sts) { if (NEED_PROVISIONING == sts) {
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert, EXPECT_EQ(NO_ERROR,
&wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set_L3, EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set_L3,
NULL, &session_id_L3)); EMPTY_ORIGIN, NULL,
&session_id_L3));
} else { } else {
EXPECT_EQ(NO_ERROR, sts); EXPECT_EQ(NO_ERROR, sts);
} }
property_set_Ln.set_security_level(""); property_set_Ln.set_security_level("");
decryptor_.OpenSession(g_key_system, &property_set_Ln, NULL, &session_id_Ln); decryptor_.OpenSession(g_key_system, &property_set_Ln, EMPTY_ORIGIN, NULL,
&session_id_Ln);
std::string security_level; std::string security_level;
EXPECT_TRUE(Properties::GetSecurityLevel(session_id_L1, &security_level)); EXPECT_TRUE(Properties::GetSecurityLevel(session_id_L1, &security_level));
@@ -889,22 +905,24 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
EXPECT_EQ( EXPECT_EQ(
NEED_PROVISIONING, NEED_PROVISIONING,
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_)); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_));
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
&provisioning_server_url)); &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert, EXPECT_EQ(NO_ERROR,
&wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set, NULL, EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
&session_id_)); EMPTY_ORIGIN, NULL, &session_id_));
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -914,7 +932,8 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeTest) {
TestWvCdmClientPropertySet property_set; TestWvCdmClientPropertySet property_set;
property_set.set_use_privacy_mode(true); property_set.set_use_privacy_mode(true);
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
std::string resp = GetKeyRequestResponse(g_license_server, g_client_auth); std::string resp = GetKeyRequestResponse(g_license_server, g_client_auth);
@@ -930,21 +949,22 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) {
property_set.set_use_privacy_mode(true); property_set.set_use_privacy_mode(true);
property_set.set_service_certificate(a2bs_hex(kServiceCertificate)); property_set.set_service_certificate(a2bs_hex(kServiceCertificate));
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
} }
TEST_F(WvCdmRequestLicenseTest, BaseMessageTest) { TEST_F(WvCdmRequestLicenseTest, BaseMessageTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
GetKeyRequestResponse(g_license_server, g_client_auth); GetKeyRequestResponse(g_license_server, g_client_auth);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
} }
TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) { TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string wrong_message = wvcdm::a2bs_hex(g_wrong_key_id); std::string wrong_message = wvcdm::a2bs_hex(g_wrong_key_id);
GenerateKeyRequest(wrong_message, kLicenseTypeStreaming); GenerateKeyRequest(wrong_message, kLicenseTypeStreaming);
@@ -972,7 +992,7 @@ TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) {
} }
TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) { TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -987,7 +1007,7 @@ TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1002,7 +1022,7 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1011,7 +1031,7 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) {
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
} }
@@ -1025,7 +1045,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1035,7 +1055,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1055,7 +1075,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1065,7 +1085,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1074,7 +1094,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
GenerateKeyRelease(key_set_id); GenerateKeyRelease(key_set_id);
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1097,28 +1117,32 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
CdmResponseType sts = CdmResponseType sts =
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
if (NEED_PROVISIONING == sts) { if (NEED_PROVISIONING == sts) {
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
&provisioning_server_url)); &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert, EXPECT_EQ(NO_ERROR,
&wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set, EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
NULL, &session_id_)); EMPTY_ORIGIN, NULL,
&session_id_));
} else { } else {
EXPECT_EQ(NO_ERROR, sts); EXPECT_EQ(NO_ERROR, sts);
} }
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set); GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1128,7 +1152,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1137,7 +1162,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
GenerateKeyRelease(key_set_id, &property_set); GenerateKeyRelease(key_set_id, &property_set);
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
EXPECT_EQ( EXPECT_EQ(
wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id)); wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1158,7 +1184,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1169,7 +1195,8 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
StrictMock<TestWvCdmEventListener> listener; StrictMock<TestWvCdmEventListener> listener;
decryptor_.OpenSession(g_key_system, NULL, &listener, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, &listener,
&session_id_);
CdmSessionId restore_session_id = session_id_; CdmSessionId restore_session_id = session_id_;
EXPECT_CALL(listener, EXPECT_CALL(listener,
OnSessionKeysChange(restore_session_id, OnSessionKeysChange(restore_session_id,
@@ -1197,7 +1224,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
} }
TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) { TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1214,7 +1241,7 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) {
std::string client_auth; std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth); GetOfflineConfiguration(&key_id, &client_auth);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
@@ -1227,7 +1254,8 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) {
TEST_F(WvCdmRequestLicenseTest, RemoveKeys) { TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
ASSERT_EQ(NO_ERROR, ASSERT_EQ(NO_ERROR,
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_)); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
&session_id_));
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_)); ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_));
@@ -1248,7 +1276,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts)); EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts));
SubSampleInfo* data = &usage_info_sub_samples_icp[0]; SubSampleInfo* data = &usage_info_sub_samples_icp[0];
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string key_id = a2bs_hex( std::string key_id = a2bs_hex(
"000000427073736800000000" // blob size and pssh "000000427073736800000000" // blob size and pssh
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
@@ -1326,7 +1354,8 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
for (size_t i = 0; i < usage_info_data->usage_info; ++i) { for (size_t i = 0; i < usage_info_data->usage_info; ++i) {
SubSampleInfo* data = usage_info_data->sub_sample + i; SubSampleInfo* data = usage_info_data->sub_sample + i;
decryptor_.OpenSession(g_key_system, property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
&session_id_);
std::string key_id = a2bs_hex( std::string key_id = a2bs_hex(
"000000427073736800000000" // blob size and pssh "000000427073736800000000" // blob size and pssh
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
@@ -1405,7 +1434,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) {
Unprovision(); Unprovision();
Provision(kLevelDefault); Provision(kLevelDefault);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1478,7 +1507,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyControlInfo) {
Unprovision(); Unprovision();
Provision(kLevelDefault); Provision(kLevelDefault);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1540,26 +1569,27 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
file.Remove(path); file.Remove(path);
} }
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN,
&provisioning_server_url)); &key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( EXPECT_EQ(wvcdm::NO_ERROR,
response, &cert, &wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
std::vector<std::string> files; std::vector<std::string> files;
EXPECT_TRUE(file.List(base_path, &files)); EXPECT_TRUE(file.List(base_path, &files));
size_t number_of_files = files.size(); size_t number_of_files = files.size();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline); GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
CdmKeySetId key_set_id = key_set_id_; CdmKeySetId key_set_id = key_set_id_;
@@ -1585,11 +1615,11 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
// Setup complete to earlier version (non-security level based) path. // Setup complete to earlier version (non-security level based) path.
// Restore persistent license, retrieve L1, L3 streaming licenses to verify // Restore persistent license, retrieve L1, L3 streaming licenses to verify
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
@@ -1601,26 +1631,28 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
EXPECT_EQ( EXPECT_EQ(
wvcdm::NEED_PROVISIONING, wvcdm::NEED_PROVISIONING,
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_)); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_));
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, &key_msg_, cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
&provisioning_server_url)); &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
response = response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert, EXPECT_EQ(NO_ERROR,
&wrapped_key)); decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key));
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set, NULL, EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
&session_id_)); EMPTY_ORIGIN, NULL, &session_id_));
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
} }
TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) { TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeOffline); GenerateKeyRequest(g_key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1673,7 +1705,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) {
} }
TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) { TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) {
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeOffline); GenerateKeyRequest(g_key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
CdmKeySetId key_set_id = key_set_id_; CdmKeySetId key_set_id = key_set_id_;
@@ -1681,7 +1713,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) {
decryptor_.CloseSession(session_id_); decryptor_.CloseSession(session_id_);
session_id_.clear(); session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
/* /*
// key 1, encrypted, 256b // key 1, encrypted, 256b
@@ -1798,7 +1830,8 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) {
property_set.set_session_sharing_mode( property_set.set_session_sharing_mode(
session_sharing_info->session_sharing_enabled); session_sharing_info->session_sharing_enabled);
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
CdmSessionId gp_session_id_1 = session_id_; CdmSessionId gp_session_id_1 = session_id_;
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1811,7 +1844,8 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) {
"edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id "edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id
"08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data "08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data
decryptor_.OpenSession(g_key_system, &property_set, NULL, &session_id_); decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
&session_id_);
CdmSessionId gp_session_id_2 = session_id_; CdmSessionId gp_session_id_2 = session_id_;
GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming); GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false); VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false);
@@ -1846,7 +1880,7 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionKeyExpiredTest) {
"EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id "EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id
"0801121030313233343536373839616263646566"); // pssh data "0801121030313233343536373839616263646566"); // pssh data
SubSampleInfo* data = &single_encrypted_sub_sample_short_expiry; SubSampleInfo* data = &single_encrypted_sub_sample_short_expiry;
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
if (data->retrieve_key) { if (data->retrieve_key) {
GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming); GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
@@ -1876,7 +1910,7 @@ class WvCdmDecryptionTest
TEST_P(WvCdmDecryptionTest, DecryptionTest) { TEST_P(WvCdmDecryptionTest, DecryptionTest) {
SubSampleInfo* data = GetParam(); SubSampleInfo* data = GetParam();
decryptor_.OpenSession(g_key_system, NULL, NULL, &session_id_); decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
if (data->retrieve_key) { if (data->retrieve_key) {
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false); VerifyKeyRequestResponse(g_license_server, g_client_auth, false);

View File

@@ -252,6 +252,8 @@ class WVDrmPlugin : public android::DrmPlugin,
WvContentDecryptionModule* mCDM; WvContentDecryptionModule* mCDM;
WVGenericCryptoInterface* mCrypto; WVGenericCryptoInterface* mCrypto;
std::string mOrigin;
Mutex mCryptoSessionsMutex; Mutex mCryptoSessionsMutex;
map<CdmSessionId, CryptoSession> mCryptoSessions; map<CdmSessionId, CryptoSession> mCryptoSessions;
@@ -273,6 +275,8 @@ class WVDrmPlugin : public android::DrmPlugin,
status_t mapOEMCryptoResult(OEMCryptoResult res); status_t mapOEMCryptoResult(OEMCryptoResult res);
bool InitDataResemblesPSSH(const Vector<uint8_t>& initData); bool InitDataResemblesPSSH(const Vector<uint8_t>& initData);
const char* determineOrigin() const;
}; };
} // namespace wvdrm } // namespace wvdrm

View File

@@ -74,7 +74,8 @@ DrmPlugin::KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) {
WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm, WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm,
WVGenericCryptoInterface* crypto) WVGenericCryptoInterface* crypto)
: mCDM(cdm), mCrypto(crypto), mCryptoSessionsMutex(), mCryptoSessions() {} : mCDM(cdm), mCrypto(crypto), mOrigin(), mCryptoSessionsMutex(),
mCryptoSessions() {}
WVDrmPlugin::~WVDrmPlugin() { WVDrmPlugin::~WVDrmPlugin() {
typedef map<CdmSessionId, CryptoSession>::iterator mapIterator; typedef map<CdmSessionId, CryptoSession>::iterator mapIterator;
@@ -93,7 +94,8 @@ WVDrmPlugin::~WVDrmPlugin() {
status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) { status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) {
CdmSessionId cdmSessionId; CdmSessionId cdmSessionId;
CdmResponseType res = CdmResponseType res =
mCDM->OpenSession("com.widevine", &mPropertySet, this, &cdmSessionId); mCDM->OpenSession("com.widevine", &mPropertySet, determineOrigin(), this,
&cdmSessionId);
if (!isCdmResponseTypeSuccess(res)) { if (!isCdmResponseTypeSuccess(res)) {
return mapAndNotifyOfCdmResponseType(sessionId, res); return mapAndNotifyOfCdmResponseType(sessionId, res);
@@ -234,8 +236,8 @@ status_t WVDrmPlugin::getKeyRequest(
string cdmDefaultUrl; string cdmDefaultUrl;
CdmResponseType res = mCDM->GenerateKeyRequest( CdmResponseType res = mCDM->GenerateKeyRequest(
cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData, cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData,
cdmLicenseType, cdmParameters, &mPropertySet, &keyRequest, cdmLicenseType, cdmParameters, &mPropertySet, determineOrigin(),
&cdmKeyRequestType, &cdmDefaultUrl); &keyRequest, &cdmKeyRequestType, &cdmDefaultUrl);
*keyRequestType = ConvertFromCdmKeyRequestType(cdmKeyRequestType); *keyRequestType = ConvertFromCdmKeyRequestType(cdmKeyRequestType);
if (isCdmResponseTypeSuccess(res)) { if (isCdmResponseTypeSuccess(res)) {
@@ -361,6 +363,7 @@ status_t WVDrmPlugin::getProvisionRequest(const String8& cert_type,
CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType, CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType,
cdmCertAuthority, cdmCertAuthority,
determineOrigin(),
&cdmProvisionRequest, &cdmProvisionRequest,
&cdmDefaultUrl); &cdmDefaultUrl);
@@ -384,7 +387,8 @@ status_t WVDrmPlugin::provideProvisionResponse(
CdmProvisioningResponse cdmResponse(response.begin(), response.end()); CdmProvisioningResponse cdmResponse(response.begin(), response.end());
string cdmCertificate; string cdmCertificate;
string cdmWrappedKey; string cdmWrappedKey;
CdmResponseType res = mCDM->HandleProvisioningResponse(cdmResponse, CdmResponseType res = mCDM->HandleProvisioningResponse(determineOrigin(),
cdmResponse,
&cdmCertificate, &cdmCertificate,
&cdmWrappedKey); &cdmWrappedKey);
if (isCdmResponseTypeSuccess(res)) { if (isCdmResponseTypeSuccess(res)) {
@@ -403,8 +407,8 @@ status_t WVDrmPlugin::provideProvisionResponse(
} }
status_t WVDrmPlugin::unprovisionDevice() { status_t WVDrmPlugin::unprovisionDevice() {
CdmResponseType res1 = mCDM->Unprovision(kSecurityLevelL1); CdmResponseType res1 = mCDM->Unprovision(kSecurityLevelL1, determineOrigin());
CdmResponseType res3 = mCDM->Unprovision(kSecurityLevelL3); CdmResponseType res3 = mCDM->Unprovision(kSecurityLevelL3, determineOrigin());
if (!isCdmResponseTypeSuccess(res1)) if (!isCdmResponseTypeSuccess(res1))
{ {
return mapCdmResponseType(res1); return mapCdmResponseType(res1);
@@ -511,6 +515,8 @@ status_t WVDrmPlugin::getPropertyString(const String8& name,
return queryProperty(QUERY_KEY_MAX_NUMBER_OF_SESSIONS, value); return queryProperty(QUERY_KEY_MAX_NUMBER_OF_SESSIONS, value);
} else if (name == "appId") { } else if (name == "appId") {
value = mPropertySet.app_id().c_str(); value = mPropertySet.app_id().c_str();
} else if (name == "origin") {
value = mOrigin.c_str();
} else { } else {
ALOGE("App requested unknown string property %s", name.string()); ALOGE("App requested unknown string property %s", name.string());
return android::ERROR_DRM_CANNOT_HANDLE; return android::ERROR_DRM_CANNOT_HANDLE;
@@ -609,6 +615,18 @@ status_t WVDrmPlugin::setPropertyString(const String8& name,
ALOGE("App tried to set the application id while sessions are opened."); ALOGE("App tried to set the application id while sessions are opened.");
return kErrorSessionIsOpen; return kErrorSessionIsOpen;
} }
} else if (name == "origin") {
size_t sessionCount = 0;
{
Mutex::Autolock lock(mCryptoSessionsMutex);
sessionCount = mCryptoSessions.size();
}
if (sessionCount == 0) {
mOrigin = value.string();
} else {
ALOGE("App tried to set the origin while sessions are opened.");
return kErrorSessionIsOpen;
}
} else { } else {
ALOGE("App set unknown string property %s", name.string()); ALOGE("App set unknown string property %s", name.string());
return android::ERROR_DRM_CANNOT_HANDLE; return android::ERROR_DRM_CANNOT_HANDLE;
@@ -1009,4 +1027,8 @@ bool WVDrmPlugin::InitDataResemblesPSSH(const Vector<uint8_t>& initData) {
return id == kPsshTag; return id == kPsshTag;
} }
const char* WVDrmPlugin::determineOrigin() const {
return mOrigin.empty() ? EMPTY_ORIGIN : mOrigin.c_str();
}
} // namespace wvdrm } // namespace wvdrm

View File

@@ -4,6 +4,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ostream>
#include <string> #include <string>
#include "cdm_client_property_set.h" #include "cdm_client_property_set.h"
@@ -24,21 +25,28 @@ using namespace testing;
using namespace wvcdm; using namespace wvcdm;
using namespace wvdrm; using namespace wvdrm;
namespace {
const String8 kEmptyString;
const String8 kOrigin("widevine.com");
const String8 kAppId("com.unittest.mock.app.id");
}
class MockCDM : public WvContentDecryptionModule { class MockCDM : public WvContentDecryptionModule {
public: public:
MOCK_METHOD4(OpenSession, CdmResponseType(const CdmKeySystem&, MOCK_METHOD5(OpenSession, CdmResponseType(const CdmKeySystem&,
CdmClientPropertySet*, CdmClientPropertySet*,
const std::string&,
WvCdmEventListener*, WvCdmEventListener*,
CdmSessionId*)); CdmSessionId*));
MOCK_METHOD1(CloseSession, CdmResponseType(const CdmSessionId&)); MOCK_METHOD1(CloseSession, CdmResponseType(const CdmSessionId&));
MOCK_METHOD10(GenerateKeyRequest, MOCK_METHOD11(GenerateKeyRequest,
CdmResponseType(const CdmSessionId&, const CdmKeySetId&, CdmResponseType(const CdmSessionId&, const CdmKeySetId&,
const std::string&, const CdmInitData&, const std::string&, const CdmInitData&,
const CdmLicenseType, CdmAppParameterMap&, const CdmLicenseType, CdmAppParameterMap&,
CdmClientPropertySet*, CdmKeyMessage*, CdmClientPropertySet*, const std::string&,
CdmKeyRequestType*, string*)); CdmKeyMessage*, CdmKeyRequestType*, string*));
MOCK_METHOD3(AddKey, CdmResponseType(const CdmSessionId&, MOCK_METHOD3(AddKey, CdmResponseType(const CdmSessionId&,
const CdmKeyResponse&, const CdmKeyResponse&,
@@ -57,13 +65,18 @@ class MockCDM : public WvContentDecryptionModule {
MOCK_METHOD2(QueryKeyControlInfo, CdmResponseType(const CdmSessionId&, MOCK_METHOD2(QueryKeyControlInfo, CdmResponseType(const CdmSessionId&,
CdmQueryMap*)); CdmQueryMap*));
MOCK_METHOD4(GetProvisioningRequest, CdmResponseType(CdmCertificateType, MOCK_METHOD5(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
const std::string&,
const std::string&, const std::string&,
CdmProvisioningRequest*, CdmProvisioningRequest*,
std::string*)); std::string*));
MOCK_METHOD3(HandleProvisioningResponse, MOCK_METHOD4(HandleProvisioningResponse,
CdmResponseType(CdmProvisioningResponse&, std::string*, std::string*)); CdmResponseType(const std::string&, CdmProvisioningResponse&,
std::string*, std::string*));
MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel,
const std::string&));
MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&, MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&,
CdmUsageInfo*)); CdmUsageInfo*));
@@ -72,8 +85,6 @@ class MockCDM : public WvContentDecryptionModule {
const CdmSecureStopId&, const CdmSecureStopId&,
CdmUsageInfo*)); CdmUsageInfo*));
MOCK_METHOD1(Unprovision, CdmResponseType(CdmSecurityLevel));
MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&)); MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&));
MOCK_METHOD1(ReleaseUsageInfo, MOCK_METHOD1(ReleaseUsageInfo,
@@ -149,14 +160,35 @@ class WVDrmPluginTest : public Test {
} }
}; };
struct OriginTestVariant {
// For a test that does not expect any follow-up queries
OriginTestVariant(const std::string& nameValue, const String8& originValue,
const std::string& expectedOriginValue)
: name(nameValue), origin(originValue),
expectedOrigin(expectedOriginValue) {}
const std::string name;
const String8 origin;
const std::string expectedOrigin;
};
void PrintTo(const OriginTestVariant& param, ::std::ostream* os) {
*os << param.name << " Variant";
}
class WVDrmPluginOriginTest : public WVDrmPluginTest,
public WithParamInterface<OriginTestVariant> {};
TEST_F(WVDrmPluginTest, OpensSessions) { TEST_F(WVDrmPluginTest, OpensSessions) {
StrictMock<MockCDM> cdm; StrictMock<MockCDM> cdm;
StrictMock<MockCrypto> crypto; StrictMock<MockCrypto> crypto;
WVDrmPlugin plugin(&cdm, &crypto); WVDrmPlugin plugin(&cdm, &crypto);
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm,
.WillOnce(DoAll(SetArgPointee<3>(cdmSessionId), OpenSession(StrEq("com.widevine"), _, StrEq(EMPTY_ORIGIN), _, _))
Return(wvcdm::NO_ERROR))); .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -270,26 +302,27 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) {
EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData,
kLicenseTypeOffline, cdmParameters, _, kLicenseTypeOffline, cdmParameters, _,
_, _, _)) _, _, _, _))
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest), .WillOnce(DoAll(SetArgPointee<8>(cdmRequest),
SetArgPointee<8>(kKeyRequestTypeInitial), SetArgPointee<9>(kKeyRequestTypeInitial),
SetArgPointee<9>(kDefaultUrl), SetArgPointee<10>(kDefaultUrl),
Return(wvcdm::KEY_MESSAGE))); Return(wvcdm::KEY_MESSAGE)));
EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData,
kLicenseTypeStreaming, cdmParameters, kLicenseTypeStreaming, cdmParameters,
_, _, _, _)) _, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest), .WillOnce(DoAll(SetArgPointee<8>(cdmRequest),
SetArgPointee<8>(kKeyRequestTypeRenewal), SetArgPointee<9>(kKeyRequestTypeRenewal),
SetArgPointee<9>(kDefaultUrl), SetArgPointee<10>(kDefaultUrl),
Return(wvcdm::KEY_MESSAGE))); Return(wvcdm::KEY_MESSAGE)));
EXPECT_CALL(cdm, GenerateKeyRequest("", cdmKeySetId, mimeType, initData, EXPECT_CALL(cdm, GenerateKeyRequest("", cdmKeySetId, mimeType, initData,
kLicenseTypeRelease, cdmParameters, kLicenseTypeRelease, cdmParameters,
NotNull(), _, _, _)) NotNull(), StrEq(EMPTY_ORIGIN), _, _,
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest), _))
SetArgPointee<8>(kKeyRequestTypeRelease), .WillOnce(DoAll(SetArgPointee<8>(cdmRequest),
SetArgPointee<9>(kDefaultUrl), SetArgPointee<9>(kKeyRequestTypeRelease),
SetArgPointee<10>(kDefaultUrl),
Return(wvcdm::KEY_MESSAGE))); Return(wvcdm::KEY_MESSAGE)));
} }
} }
@@ -384,10 +417,10 @@ TEST_F(WVDrmPluginTest, HandlesPrivacyCertCaseOfAddKey) {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -512,9 +545,9 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
static const char* kDefaultUrl = "http://google.com/"; static const char* kDefaultUrl = "http://google.com/";
EXPECT_CALL(cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(), EXPECT_CALL(cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(),
_, _)) EMPTY_ORIGIN, _, _))
.WillOnce(DoAll(SetArgPointee<2>(cdmRequest), .WillOnce(DoAll(SetArgPointee<3>(cdmRequest),
SetArgPointee<3>(kDefaultUrl), SetArgPointee<4>(kDefaultUrl),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
Vector<uint8_t> request; Vector<uint8_t> request;
@@ -542,7 +575,8 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) {
Vector<uint8_t> response; Vector<uint8_t> response;
response.appendArray(responseRaw, kResponseSize); response.appendArray(responseRaw, kResponseSize);
EXPECT_CALL(cdm, HandleProvisioningResponse(ElementsAreArray(responseRaw, EXPECT_CALL(cdm, HandleProvisioningResponse(EMPTY_ORIGIN,
ElementsAreArray(responseRaw,
kResponseSize), kResponseSize),
_, _)) _, _))
.Times(1); .Times(1);
@@ -560,9 +594,9 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) {
StrictMock<MockCrypto> crypto; StrictMock<MockCrypto> crypto;
WVDrmPlugin plugin(&cdm, &crypto); WVDrmPlugin plugin(&cdm, &crypto);
EXPECT_CALL(cdm, Unprovision(kSecurityLevelL1)) EXPECT_CALL(cdm, Unprovision(kSecurityLevelL1, EMPTY_ORIGIN))
.Times(1); .Times(1);
EXPECT_CALL(cdm, Unprovision(kSecurityLevelL3)) EXPECT_CALL(cdm, Unprovision(kSecurityLevelL3, EMPTY_ORIGIN))
.Times(1); .Times(1);
status_t res = plugin.unprovisionDevice(); status_t res = plugin.unprovisionDevice();
@@ -576,11 +610,11 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) {
// Tests that both Unprovisions are called even if one fails. Also tests that // Tests that both Unprovisions are called even if one fails. Also tests that
// no matter which fails, the function always propagates the error. // no matter which fails, the function always propagates the error.
EXPECT_CALL(cdm, Unprovision(kSecurityLevelL1)) EXPECT_CALL(cdm, Unprovision(kSecurityLevelL1, EMPTY_ORIGIN))
.WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR))
.WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::NO_ERROR))
.WillOnce(Return(wvcdm::UNKNOWN_ERROR)); .WillOnce(Return(wvcdm::UNKNOWN_ERROR));
EXPECT_CALL(cdm, Unprovision(kSecurityLevelL3)) EXPECT_CALL(cdm, Unprovision(kSecurityLevelL3, EMPTY_ORIGIN))
.WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::NO_ERROR))
.WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR))
.WillOnce(Return(wvcdm::UNKNOWN_ERROR)); .WillOnce(Return(wvcdm::UNKNOWN_ERROR));
@@ -824,9 +858,9 @@ TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) {
bool match; bool match;
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -903,9 +937,9 @@ TEST_F(WVDrmPluginTest, CallsGenericEncrypt) {
} }
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -963,9 +997,9 @@ TEST_F(WVDrmPluginTest, CallsGenericDecrypt) {
} }
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1025,9 +1059,9 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) {
} }
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1097,9 +1131,9 @@ TEST_F(WVDrmPluginTest, CallsGenericVerify) {
} }
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1130,9 +1164,9 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) {
WVDrmPlugin plugin(&cdm, &crypto); WVDrmPlugin plugin(&cdm, &crypto);
// Provide expected behavior to support session creation // Provide expected behavior to support session creation
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, &plugin, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, &plugin, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1163,10 +1197,10 @@ TEST_F(WVDrmPluginTest, UnregistersForAllEventsOnDestruction) {
CdmSessionId cdmSessionId1(sessionIdRaw1, sessionIdRaw1 + kSessionIdSize); CdmSessionId cdmSessionId1(sessionIdRaw1, sessionIdRaw1 + kSessionIdSize);
CdmSessionId cdmSessionId2(sessionIdRaw2, sessionIdRaw2 + kSessionIdSize); CdmSessionId cdmSessionId2(sessionIdRaw2, sessionIdRaw2 + kSessionIdSize);
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.WillOnce(DoAll(SetArgPointee<3>(cdmSessionId1), .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId1),
Return(wvcdm::NO_ERROR))) Return(wvcdm::NO_ERROR)))
.WillOnce(DoAll(SetArgPointee<3>(cdmSessionId2), .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId2),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId1, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId1, _))
@@ -1281,9 +1315,9 @@ TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) {
NULL)) NULL))
.Times(1); .Times(1);
EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _)) EXPECT_CALL(cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1)) .Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NEED_PROVISIONING))); Return(wvcdm::NEED_PROVISIONING)));
EXPECT_CALL(cdm, CloseSession(_)) EXPECT_CALL(cdm, CloseSession(_))
@@ -1307,10 +1341,10 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1330,6 +1364,7 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
EXPECT_EQ(0u, propertySet->session_sharing_id()); EXPECT_EQ(0u, propertySet->session_sharing_id());
EXPECT_STREQ("", propertySet->app_id().c_str()); EXPECT_STREQ("", propertySet->app_id().c_str());
} }
TEST_F(WVDrmPluginTest, CanSetAppId) { TEST_F(WVDrmPluginTest, CanSetAppId) {
StrictMock<MockCDM> cdm; StrictMock<MockCDM> cdm;
StrictMock<MockCrypto> crypto; StrictMock<MockCrypto> crypto;
@@ -1337,14 +1372,22 @@ TEST_F(WVDrmPluginTest, CanSetAppId) {
const CdmClientPropertySet* propertySet = NULL; const CdmClientPropertySet* propertySet = NULL;
CdmQueryMap l3Map;
l3Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3;
// Provide expected mock behavior // Provide expected mock behavior
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin queries for the security level
EXPECT_CALL(cdm, QueryStatus(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(l3Map),
Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1361,7 +1404,6 @@ TEST_F(WVDrmPluginTest, CanSetAppId) {
ASSERT_EQ(OK, res); ASSERT_EQ(OK, res);
// Test setting an application id before a session is opened. // Test setting an application id before a session is opened.
const String8 kAppId("com.unittest.mock.app.id");
res = plugin.setPropertyString(String8("appId"), kAppId); res = plugin.setPropertyString(String8("appId"), kAppId);
ASSERT_EQ(OK, res); ASSERT_EQ(OK, res);
@@ -1376,6 +1418,42 @@ TEST_F(WVDrmPluginTest, CanSetAppId) {
ASSERT_EQ(kErrorSessionIsOpen, res); ASSERT_EQ(kErrorSessionIsOpen, res);
} }
TEST_P(WVDrmPluginOriginTest, CanSetOrigin) {
StrictMock<MockCDM> cdm;
StrictMock<MockCrypto> crypto;
WVDrmPlugin plugin(&cdm, &crypto);
OriginTestVariant params = GetParam();
// Provide expected mock behavior
{
// Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
// Provide expected behavior when plugin closes a session
EXPECT_CALL(cdm, CloseSession(_))
.Times(AtLeast(0));
}
// Note which mock calls we expect
EXPECT_CALL(cdm, OpenSession(_, _, StrEq(params.expectedOrigin), _, _))
.WillOnce(DoAll(SetArgPointee<4>(cdmSessionId),
Return(wvcdm::NO_ERROR)));
// Set the properties & run the test
if (!params.origin.isEmpty()) {
ASSERT_EQ(OK, plugin.setPropertyString(String8("origin"), params.origin));
}
EXPECT_EQ(OK, plugin.openSession(sessionId));
// Test setting an origin while sessions are opened. This should fail.
EXPECT_NE(OK, plugin.setPropertyString(String8("origin"), kOrigin));
EXPECT_EQ(OK, plugin.closeSession(sessionId));
}
INSTANTIATE_TEST_CASE_P(OriginTests, WVDrmPluginOriginTest, Values(
OriginTestVariant("No Origin", kEmptyString, EMPTY_ORIGIN),
OriginTestVariant("With an Origin", kOrigin, kOrigin.string())));
TEST_F(WVDrmPluginTest, CanSetSecurityLevel) { TEST_F(WVDrmPluginTest, CanSetSecurityLevel) {
StrictMock<MockCDM> cdm; StrictMock<MockCDM> cdm;
StrictMock<MockCrypto> crypto; StrictMock<MockCrypto> crypto;
@@ -1399,10 +1477,10 @@ TEST_F(WVDrmPluginTest, CanSetSecurityLevel) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1484,10 +1562,10 @@ TEST_F(WVDrmPluginTest, CanSetPrivacyMode) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1539,10 +1617,10 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1580,10 +1658,10 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))
@@ -1639,10 +1717,10 @@ TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) {
{ {
// Provide expected behavior in response to OpenSession and store the // Provide expected behavior in response to OpenSession and store the
// property set // property set
EXPECT_CALL(cdm, OpenSession(_, _, _, _)) EXPECT_CALL(cdm, OpenSession(_, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(cdmSessionId), .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
SaveArg<1>(&propertySet), SaveArg<1>(&propertySet),
Return(wvcdm::NO_ERROR))); Return(wvcdm::NO_ERROR)));
// Provide expected behavior when plugin requests session control info // Provide expected behavior when plugin requests session control info
EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _)) EXPECT_CALL(cdm, QueryKeyControlInfo(cdmSessionId, _))