diff --git a/libwvdrmengine/cdm/core/include/cdm_client_property_set.h b/libwvdrmengine/cdm/core/include/cdm_client_property_set.h index 74d7421e..589a60cc 100644 --- a/libwvdrmengine/cdm/core/include/cdm_client_property_set.h +++ b/libwvdrmengine/cdm/core/include/cdm_client_property_set.h @@ -16,6 +16,7 @@ class CdmClientPropertySet { virtual const std::string& security_level() const = 0; virtual bool use_privacy_mode() const = 0; virtual const std::string& service_certificate() const = 0; + virtual void set_service_certificate(const std::string& cert) = 0; virtual bool is_session_sharing_enabled() const = 0; virtual uint32_t session_sharing_id() const = 0; virtual void set_session_sharing_id(uint32_t id) = 0; diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 1de4090d..ce6ec57e 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -31,7 +31,7 @@ class CdmEngine { // Session related methods virtual CdmResponseType OpenSession(const CdmKeySystem& key_system, - const CdmClientPropertySet* property_set, + CdmClientPropertySet* property_set, const std::string& origin, WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id, @@ -40,7 +40,7 @@ class CdmEngine { virtual bool IsOpenSession(const CdmSessionId& session_id); virtual CdmResponseType OpenKeySetSession( - const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set, + const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set, const std::string& origin, WvCdmEventListener* event_listener); virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id); diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index 0f7c50ec..24d61319 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -22,7 +22,7 @@ class WvCdmEventListener; class CdmSession { public: - CdmSession(const CdmClientPropertySet* cdm_client_property_set, + CdmSession(CdmClientPropertySet* cdm_client_property_set, const std::string& origin, WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id); virtual ~CdmSession(); @@ -37,7 +37,7 @@ class CdmSession { virtual const CdmSessionId& session_id() { return session_id_; } virtual CdmResponseType GenerateKeyRequest( - const InitializationData& init_data, const CdmLicenseType license_type, + const InitializationData& init_data, CdmLicenseType license_type, const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, CdmKeyRequestType* key_request_type, std::string* server_url, CdmKeySetId* key_set_id); diff --git a/libwvdrmengine/cdm/core/include/initialization_data.h b/libwvdrmengine/cdm/core/include/initialization_data.h index af33b6b4..80803c7b 100644 --- a/libwvdrmengine/cdm/core/include/initialization_data.h +++ b/libwvdrmengine/cdm/core/include/initialization_data.h @@ -34,7 +34,6 @@ class InitializationData { CdmInitData data_; bool is_cenc_; bool is_webm_; - CORE_DISALLOW_COPY_AND_ASSIGN(InitializationData); }; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/include/license.h b/libwvdrmengine/cdm/core/include/license.h index 7bf6b0aa..7e7912e6 100644 --- a/libwvdrmengine/cdm/core/include/license.h +++ b/libwvdrmengine/cdm/core/include/license.h @@ -24,7 +24,7 @@ class PolicyEngine; class CdmLicense { public: - CdmLicense(); + CdmLicense(const CdmSessionId& session_id); virtual ~CdmLicense(); virtual bool Init(const std::string& token, CryptoSession* session, @@ -32,12 +32,11 @@ class CdmLicense { virtual CdmResponseType PrepareKeyRequest( const InitializationData& init_data, const CdmLicenseType license_type, - const CdmAppParameterMap& app_parameters, const CdmSessionId& session_id, - CdmKeyMessage* signed_request, std::string* server_url); + const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request, + std::string* server_url); virtual CdmResponseType PrepareKeyUpdateRequest( bool is_renewal, const CdmAppParameterMap& app_parameters, - const CdmSessionId& session_id, CdmKeyMessage* signed_request, - std::string* server_url); + CdmKeyMessage* signed_request, std::string* server_url); virtual CdmResponseType HandleKeyResponse( const CdmKeyResponse& license_response); virtual CdmResponseType HandleKeyUpdateResponse( @@ -50,7 +49,7 @@ class CdmLicense { int64_t playback_start_time, int64_t last_playback_time); virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request, const CdmKeyResponse& license_response); - virtual bool HasInitData() { return !stored_init_data_.empty(); } + virtual bool HasInitData() { return stored_init_data_.get(); } virtual bool IsKeyLoaded(const KeyId& key_id); virtual std::string provider_session_token() { @@ -78,15 +77,14 @@ class CdmLicense { static CdmResponseType VerifyAndExtractSignedServiceCertificate( const std::string& signed_service_certificate, std::string* service_certificate); - bool GetServiceCertificate(const CdmSessionId& session_id, - std::string* service_certificate); + bool GetServiceCertificate(std::string* service_certificate); CryptoSession* session_; PolicyEngine* policy_engine_; std::string server_url_; std::string token_; - std::string service_certificate_; - std::string stored_init_data_; + const CdmSessionId session_id_; + scoped_ptr stored_init_data_; bool initialized_; std::set loaded_keys_; std::string provider_session_token_; @@ -98,7 +96,8 @@ class CdmLicense { scoped_ptr clock_; // For testing - CdmLicense(Clock* clock); // CdmLicense takes ownership of the clock. + // CdmLicense takes ownership of the clock. + CdmLicense(const CdmSessionId& session_id, Clock* clock); #if defined(UNIT_TEST) friend class CdmLicenseTest; #endif diff --git a/libwvdrmengine/cdm/core/include/properties.h b/libwvdrmengine/cdm/core/include/properties.h index cc8f7ee3..bf4da706 100644 --- a/libwvdrmengine/cdm/core/include/properties.h +++ b/libwvdrmengine/cdm/core/include/properties.h @@ -17,7 +17,7 @@ namespace wvcdm { -typedef std::map +typedef std::map CdmClientPropertySetMap; // This class saves information about features and properties enabled @@ -55,20 +55,23 @@ class Properties { static bool GetFactoryKeyboxPath(std::string* keybox); static bool GetOEMCryptoPath(std::string* library_name); static bool AlwaysUseKeySetIds(); + static bool GetSecurityLevelDirectories(std::vector* dirs); static bool GetApplicationId(const CdmSessionId& session_id, std::string* app_id); static bool GetServiceCertificate(const CdmSessionId& session_id, std::string* service_certificate); + static bool SetServiceCertificate(const CdmSessionId& session_id, + const std::string& service_certificate); static bool UsePrivacyMode(const CdmSessionId& session_id); static uint32_t GetSessionSharingId(const CdmSessionId& session_id); static bool AddSessionPropertySet(const CdmSessionId& session_id, - const CdmClientPropertySet* property_set); + CdmClientPropertySet* property_set); static bool RemoveSessionPropertySet(const CdmSessionId& session_id); private: - static const CdmClientPropertySet* GetCdmClientPropertySet( + static CdmClientPropertySet* GetCdmClientPropertySet( const CdmSessionId& session_id); static void set_oem_crypto_use_secure_buffers(bool flag) { oem_crypto_use_secure_buffers_ = flag; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 78001a6f..4de2d9c1 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -186,11 +186,12 @@ enum CdmResponseType { CLIENT_ID_RSA_INIT_ERROR, CLIENT_ID_RSA_ENCRYPT_ERROR, INVALID_QUERY_STATUS, - EMPTY_PROVISIONING_CERTIFICATE_2, + UNUSED_3, /* previously EMPTY_PROVISIONING_CERTIFICATE_2 on mnc-dev, */ + /* DUPLICATE_SESSION_ID_SPECIFIED on master */ LICENSE_PARSER_NOT_INITIALIZED_4, INVALID_PARAMETERS_LIC_3, INVALID_PARAMETERS_LIC_4, - INVALID_PARAMETERS_LIC_5, + UNUSED_2, /* previously INVALID_PARAMETERS_LIC_5 */ INVALID_PARAMETERS_LIC_6, INVALID_PARAMETERS_LIC_7, LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR, @@ -205,6 +206,7 @@ enum CdmResponseType { SECURE_BUFFER_REQUIRED, DUPLICATE_SESSION_ID_SPECIFIED, LICENSE_RENEWAL_PROHIBITED, + EMPTY_PROVISIONING_CERTIFICATE_2, }; enum CdmKeyStatus { @@ -223,7 +225,10 @@ typedef std::map CdmKeyStatusMap; enum CdmLicenseType { kLicenseTypeOffline, kLicenseTypeStreaming, - kLicenseTypeRelease + kLicenseTypeRelease, + // If the original request was saved to make a service certificate request, + // use Deferred for the license type in the subsequent request. + kLicenseTypeDeferred, }; enum SecurityLevel { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 14fb673e..85f307ce 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -38,6 +38,7 @@ class UsagePropertySet : public CdmClientPropertySet { virtual const std::string& security_level() const { return security_level_; } virtual bool use_privacy_mode() const { return false; } virtual const std::string& service_certificate() const { return empty_; } + virtual void set_service_certificate(const std::string&) {} virtual bool is_session_sharing_enabled() const { return false; } virtual uint32_t session_sharing_id() const { return 0; } virtual void set_session_sharing_id(uint32_t /* id */) {} @@ -75,7 +76,7 @@ CdmEngine::~CdmEngine() { } CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, - const CdmClientPropertySet* property_set, + CdmClientPropertySet* property_set, const std::string& origin, WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id, @@ -122,7 +123,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, } CdmResponseType CdmEngine::OpenKeySetSession( - const CdmKeySetId& key_set_id, const CdmClientPropertySet* property_set, + const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set, const std::string& origin, WvCdmEventListener* event_listener) { LOGI("CdmEngine::OpenKeySetSession"); @@ -630,7 +631,6 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( "missing."); return EMPTY_PROVISIONING_CERTIFICATE_1; } - return NO_ERROR; } CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( @@ -865,8 +865,8 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { : kLevelDefault; usage_property_set_->set_security_level(security_level); usage_session_.reset( - new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, - NULL)); + new CdmSession(usage_property_set_.get(), + EMPTY_ORIGIN, NULL, NULL)); CdmResponseType status2 = usage_session_-> DeleteMultipleUsageInformation(provider_session_tokens); if (status2 != NO_ERROR) { diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index e2aedd9a..a5b4da0e 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -2,7 +2,9 @@ #include "cdm_session.h" +#include #include + #include #include @@ -23,14 +25,13 @@ const size_t kKeySetIdLength = 14; namespace wvcdm { -CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set, +CdmSession::CdmSession(CdmClientPropertySet* cdm_client_property_set, const std::string& origin, WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id) : initialized_(false), session_id_(GenerateSessionId()), origin_(origin), - license_parser_(new CdmLicense), crypto_session_(new CryptoSession), file_handle_(new DeviceFiles), license_received_(false), @@ -51,6 +52,7 @@ CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set, } session_id_ = key_set_id_; } + license_parser_.reset(new CdmLicense(session_id_)); policy_engine_.reset(new PolicyEngine( session_id_, event_listener, crypto_session_.get())); if (cdm_client_property_set) { @@ -166,7 +168,7 @@ CdmResponseType CdmSession::RestoreUsageSession( } CdmResponseType CdmSession::GenerateKeyRequest( - const InitializationData& init_data, const CdmLicenseType license_type, + const InitializationData& init_data, CdmLicenseType license_type, const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, CdmKeyRequestType* key_request_type, std::string* server_url, CdmKeySetId* key_set_id) { @@ -190,6 +192,24 @@ CdmResponseType CdmSession::GenerateKeyRequest( case kLicenseTypeRelease: is_release_ = true; break; + case kLicenseTypeDeferred: + // If you're going to pass Deferred, you must have empty init data in + // this call and stored init data from the previous call. + if (!init_data.IsEmpty() || !license_parser_->HasInitData()) { + return INVALID_LICENSE_TYPE; + } + // The arguments check out. + // The is_release_ and is_offline_ flags were already set last time based + // on the original license type. Do not change them, and use them to + // re-derive the original license type. + if (is_release_) { + license_type = kLicenseTypeRelease; + } else if (is_offline_) { + license_type = kLicenseTypeOffline; + } else { + license_type = kLicenseTypeStreaming; + } + break; default: LOGE("CdmSession::GenerateKeyRequest: unrecognized license type: %ld", license_type); @@ -204,14 +224,16 @@ CdmResponseType CdmSession::GenerateKeyRequest( return GenerateRenewalRequest(key_request, server_url); } else { if (key_request_type) *key_request_type = kKeyRequestTypeInitial; - if (!init_data.is_supported()) { - LOGW("CdmSession::GenerateKeyRequest: unsupported init data type (%s)", - init_data.type().c_str()); - return UNSUPPORTED_INIT_DATA; - } - if (init_data.IsEmpty() && !license_parser_->HasInitData()) { - LOGW("CdmSession::GenerateKeyRequest: init data absent"); - return INIT_DATA_NOT_FOUND; + if (!license_parser_->HasInitData()) { + if (!init_data.is_supported()) { + LOGW("CdmSession::GenerateKeyRequest: unsupported init data type (%s)", + init_data.type().c_str()); + return UNSUPPORTED_INIT_DATA; + } + if (init_data.IsEmpty()) { + LOGW("CdmSession::GenerateKeyRequest: init data absent"); + return INIT_DATA_NOT_FOUND; + } } if (is_offline_ && key_set_id_.empty() && !GenerateKeySetId(&key_set_id_)) { @@ -222,8 +244,7 @@ CdmResponseType CdmSession::GenerateKeyRequest( app_parameters_ = app_parameters; CdmResponseType status = license_parser_->PrepareKeyRequest( init_data, license_type, - app_parameters, session_id_, - key_request, server_url); + app_parameters, key_request, server_url); if (KEY_MESSAGE != status) return status; @@ -374,7 +395,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) { CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyMessage* key_request, std::string* server_url) { CdmResponseType status = license_parser_->PrepareKeyUpdateRequest( - true, app_parameters_, session_id_, key_request, server_url); + true, app_parameters_, key_request, server_url); if (KEY_MESSAGE != status) return status; @@ -402,7 +423,7 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyMessage* key_request, std::string* server_url) { is_release_ = true; CdmResponseType status = license_parser_->PrepareKeyUpdateRequest( - false, app_parameters_, session_id_, key_request, server_url); + false, app_parameters_, key_request, server_url); if (KEY_MESSAGE != status) return status; diff --git a/libwvdrmengine/cdm/core/src/license.cpp b/libwvdrmengine/cdm/core/src/license.cpp index 54962d6b..a789a6e8 100644 --- a/libwvdrmengine/cdm/core/src/license.cpp +++ b/libwvdrmengine/cdm/core/src/license.cpp @@ -126,13 +126,20 @@ static std::vector ExtractContentKeys(const License& license) { return key_array; } -CdmLicense::CdmLicense() +CdmLicense::CdmLicense(const CdmSessionId& session_id) : session_(NULL), + policy_engine_(NULL), + session_id_(session_id), initialized_(false), renew_with_client_id_(false), clock_(new Clock()) {} -CdmLicense::CdmLicense(Clock* clock) : session_(NULL), initialized_(false) { +CdmLicense::CdmLicense(const CdmSessionId& session_id, Clock* clock) + : session_(NULL), + policy_engine_(NULL), + session_id_(session_id), + initialized_(false), + renew_with_client_id_(false) { if (NULL == clock) { LOGE("CdmLicense::CdmLicense: clock parameter not provided"); return; @@ -144,6 +151,14 @@ CdmLicense::~CdmLicense() {} bool CdmLicense::Init(const std::string& token, CryptoSession* session, PolicyEngine* policy_engine) { + if (clock_.get() == NULL) { + LOGE("CdmLicense::Init: clock parameter not provided"); + return false; + } + if (session_id_.empty()) { + LOGE("CdmLicense::Init: empty session id provided"); + return false; + } if (token.size() == 0) { LOGE("CdmLicense::Init: empty token provided"); return false; @@ -165,25 +180,27 @@ bool CdmLicense::Init(const std::string& token, CryptoSession* session, CdmResponseType CdmLicense::PrepareKeyRequest( const InitializationData& init_data, const CdmLicenseType license_type, - const CdmAppParameterMap& app_parameters, const CdmSessionId& session_id, - CdmKeyMessage* signed_request, std::string* server_url) { + const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request, + std::string* server_url) { if (!initialized_) { LOGE("CdmLicense::PrepareKeyRequest: not initialized"); return LICENSE_PARSER_NOT_INITIALIZED_4; } + if (init_data.IsEmpty() && stored_init_data_.get()) { + InitializationData restored_init_data = *stored_init_data_; + stored_init_data_.reset(); + return PrepareKeyRequest(restored_init_data, license_type, app_parameters, + signed_request, server_url); + } if (!init_data.is_supported()) { LOGE("CdmLicense::PrepareKeyRequest: unsupported init data type (%s)", init_data.type().c_str()); return INVALID_PARAMETERS_LIC_3; } - if (init_data.IsEmpty() && stored_init_data_.empty()) { + if (init_data.IsEmpty()) { LOGE("CdmLicense::PrepareKeyRequest: empty init data provided"); return INVALID_PARAMETERS_LIC_4; } - if (session_id.empty()) { - LOGE("CdmLicense::PrepareKeyRequest: empty session id provided"); - return INVALID_PARAMETERS_LIC_5; - } if (!signed_request) { LOGE("CdmLicense::PrepareKeyRequest: no signed request provided"); return INVALID_PARAMETERS_LIC_6; @@ -194,10 +211,10 @@ CdmResponseType CdmLicense::PrepareKeyRequest( } std::string service_certificate; - bool privacy_mode_enabled = Properties::UsePrivacyMode(session_id); + bool privacy_mode_enabled = Properties::UsePrivacyMode(session_id_); if (privacy_mode_enabled) { - if (!GetServiceCertificate(session_id, &service_certificate)) { - stored_init_data_ = init_data.data(); + if (!GetServiceCertificate(&service_certificate)) { + stored_init_data_.reset(new InitializationData(init_data)); return PrepareServiceCertificateRequest(signed_request, server_url) ? KEY_MESSAGE : LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR; @@ -223,8 +240,6 @@ CdmResponseType CdmLicense::PrepareKeyRequest( if (!init_data.IsEmpty()) { cenc_content_id->add_pssh(init_data.data()); - } else if (privacy_mode_enabled && !stored_init_data_.empty()) { - cenc_content_id->add_pssh(stored_init_data_); } else { LOGE("CdmLicense::PrepareKeyRequest: ISO-CENC init data not available"); return CENC_INIT_DATA_UNAVAILABLE; @@ -239,8 +254,6 @@ CdmResponseType CdmLicense::PrepareKeyRequest( if (!init_data.IsEmpty()) { webm_content_id->set_header(init_data.data()); - } else if (privacy_mode_enabled && !stored_init_data_.empty()) { - webm_content_id->set_header(stored_init_data_); } else { LOGE("CdmLicense::PrepareKeyRequest: WebM init data not available"); return WEBM_INIT_DATA_UNAVAILABLE; @@ -304,8 +317,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest( CdmResponseType CdmLicense::PrepareKeyUpdateRequest( bool is_renewal, const CdmAppParameterMap& app_parameters, - const CdmSessionId& session_id, CdmKeyMessage* signed_request, - std::string* server_url) { + CdmKeyMessage* signed_request, std::string* server_url) { if (!initialized_) { LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized"); return LICENSE_PARSER_NOT_INITIALIZED_1; @@ -334,9 +346,9 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( if (renew_with_client_id_) { std::string service_certificate; - bool privacy_mode_enabled = Properties::UsePrivacyMode(session_id); + bool privacy_mode_enabled = Properties::UsePrivacyMode(session_id_); if (privacy_mode_enabled) { - if (!GetServiceCertificate(session_id, &service_certificate)) { + if (!GetServiceCertificate(&service_certificate)) { return PrepareServiceCertificateRequest(signed_request, server_url) ? KEY_MESSAGE : LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR; @@ -447,9 +459,13 @@ CdmResponseType CdmLicense::HandleKeyResponse( case SignedMessage::LICENSE: break; case SignedMessage::SERVICE_CERTIFICATE: { - CdmResponseType status = VerifyAndExtractSignedServiceCertificate( - signed_response.msg(), &service_certificate_); - return status == NO_ERROR ? NEED_KEY : status; + CdmResponseType status = + VerifySignedServiceCertificate(signed_response.msg()); + if (status != NO_ERROR) { + return status; + } + Properties::SetServiceCertificate(session_id_, signed_response.msg()); + return NEED_KEY; } case SignedMessage::ERROR_RESPONSE: return HandleKeyErrorResponse(signed_response); @@ -558,9 +574,13 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( case SignedMessage::LICENSE: break; case SignedMessage::SERVICE_CERTIFICATE: { - CdmResponseType status = VerifyAndExtractSignedServiceCertificate( - signed_response.msg(), &service_certificate_); - return status == NO_ERROR ? NEED_KEY : status; + CdmResponseType status = + VerifySignedServiceCertificate(signed_response.msg()); + if (status != NO_ERROR) { + return status; + } + Properties::SetServiceCertificate(session_id_, signed_response.msg()); + return NEED_KEY; } case SignedMessage::ERROR_RESPONSE: return HandleKeyErrorResponse(signed_response); @@ -1067,19 +1087,14 @@ CdmResponseType CdmLicense::PrepareClientId( return NO_ERROR; } -bool CdmLicense::GetServiceCertificate(const CdmSessionId& session_id, - std::string* service_certificate) { +bool CdmLicense::GetServiceCertificate(std::string* service_certificate) { std::string signed_service_certificate; - if (!Properties::GetServiceCertificate(session_id, - &signed_service_certificate) || - signed_service_certificate.empty() || - NO_ERROR != VerifyAndExtractSignedServiceCertificate( - signed_service_certificate, service_certificate)) { - *service_certificate = service_certificate_; - } - - if (service_certificate->size() > 0) return true; - return false; + return Properties::GetServiceCertificate(session_id_, + &signed_service_certificate) && + !signed_service_certificate.empty() && + NO_ERROR == VerifyAndExtractSignedServiceCertificate( + signed_service_certificate, service_certificate) && + !service_certificate->empty(); } template diff --git a/libwvdrmengine/cdm/core/src/properties.cpp b/libwvdrmengine/cdm/core/src/properties.cpp index 3983bf16..0363b61e 100644 --- a/libwvdrmengine/cdm/core/src/properties.cpp +++ b/libwvdrmengine/cdm/core/src/properties.cpp @@ -17,13 +17,13 @@ bool Properties::security_level_path_backward_compatibility_support_; scoped_ptr Properties::session_property_set_; bool Properties::AddSessionPropertySet( - const CdmSessionId& session_id, const CdmClientPropertySet* property_set) { + const CdmSessionId& session_id, CdmClientPropertySet* property_set) { if (NULL == session_property_set_.get()) { return false; } std::pair result = session_property_set_->insert( - std::pair( + std::pair( session_id, property_set)); return result.second; } @@ -35,10 +35,10 @@ bool Properties::RemoveSessionPropertySet(const CdmSessionId& session_id) { return (1 == session_property_set_->erase(session_id)); } -const CdmClientPropertySet* Properties::GetCdmClientPropertySet( +CdmClientPropertySet* Properties::GetCdmClientPropertySet( const CdmSessionId& session_id) { if (NULL != session_property_set_.get()) { - CdmClientPropertySetMap::const_iterator it = + CdmClientPropertySetMap::iterator it = session_property_set_->find(session_id); if (it != session_property_set_->end()) { return it->second; @@ -69,6 +69,17 @@ bool Properties::GetServiceCertificate(const CdmSessionId& session_id, return true; } +bool Properties::SetServiceCertificate(const CdmSessionId& session_id, + const std::string& service_certificate) { + CdmClientPropertySet* property_set = + GetCdmClientPropertySet(session_id); + if (NULL == property_set) { + return false; + } + property_set->set_service_certificate(service_certificate); + return true; +} + bool Properties::UsePrivacyMode(const CdmSessionId& session_id) { const CdmClientPropertySet* property_set = GetCdmClientPropertySet(session_id); diff --git a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp index 58b97a14..785cb0d6 100644 --- a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp @@ -116,6 +116,9 @@ class MockPolicyEngine : public PolicyEngine { class MockCdmLicense : public CdmLicense { public: + MockCdmLicense(const CdmSessionId& session_id) + : CdmLicense(session_id) {} + MOCK_METHOD3(Init, bool(const std::string&, CryptoSession*, PolicyEngine*)); }; @@ -135,7 +138,7 @@ class CdmSessionTest : public ::testing::Test { virtual void SetUp() { cdm_session_.reset(new CdmSession(NULL, kTestOrigin, NULL, NULL)); // Inject testing mocks. - license_parser_ = new MockCdmLicense(); + license_parser_ = new MockCdmLicense(cdm_session_->session_id()); cdm_session_->set_license_parser(license_parser_); crypto_session_ = new MockCryptoSession(); cdm_session_->set_crypto_session(crypto_session_); diff --git a/libwvdrmengine/cdm/core/test/license_unittest.cpp b/libwvdrmengine/cdm/core/test/license_unittest.cpp index 0227a234..ababf2a5 100644 --- a/libwvdrmengine/cdm/core/test/license_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_unittest.cpp @@ -142,7 +142,7 @@ class CdmLicenseTest : public ::testing::Test { } void CreateCdmLicense() { - cdm_license_ = new CdmLicense(clock_); + cdm_license_ = new CdmLicense(kCdmSessionId, clock_); clock_ = NULL; } @@ -157,7 +157,7 @@ TEST_F(CdmLicenseTest, InitSuccess) { EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); CreateCdmLicense(); - ASSERT_TRUE(cdm_license_->Init(kToken, crypto_session_, policy_engine_)); + EXPECT_TRUE(cdm_license_->Init(kToken, crypto_session_, policy_engine_)); } TEST_F(CdmLicenseTest, InitFail_EmptyToken) { @@ -210,7 +210,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { Properties::set_use_certificates_as_identification(true); std::string server_url; EXPECT_TRUE(cdm_license_->PrepareKeyRequest( - *init_data_, kLicenseTypeStreaming, app_parameters, kCdmSessionId, + *init_data_, kLicenseTypeStreaming, app_parameters, &signed_request, &server_url)); EXPECT_TRUE(!signed_request.empty()); diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 3c573c99..d77d984a 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -314,8 +314,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case INVALID_PARAMETERS_LIC_4: *os << "INVALID_PARAMETERS_LIC_4"; break; - case INVALID_PARAMETERS_LIC_5: *os << "INVALID_PARAMETERS_LIC_5"; - break; case INVALID_PARAMETERS_LIC_6: *os << "INVALID_PARAMETERS_LIC_6"; break; case INVALID_PARAMETERS_LIC_7: *os << "INVALID_PARAMETERS_LIC_7"; @@ -339,6 +337,7 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case EMPTY_LICENSE_REQUEST: *os << "EMPTY_LICENSE_REQUEST"; break; + case DUPLICATE_SESSION_ID_SPECIFIED: *os << "DUPLICATE_SESSION_ID_SPECIFIED"; case LICENSE_RENEWAL_PROHIBITED: *os << "LICENSE_RENEWAL_PROHIBITED"; break; default: @@ -355,6 +354,8 @@ void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) { break; case kLicenseTypeRelease: *os << "kLicenseTypeRelease"; break; + case kLicenseTypeDeferred: *os << "kLicenseTypeDeferred"; + break; default: *os << "Unknown CdmLicenseType"; break; diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 968d8812..68993bb4 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -198,6 +198,9 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet { virtual const std::string& service_certificate() const { return service_certificate_; } + virtual void set_service_certificate(const std::string& cert) { + service_certificate_ = cert; + } virtual bool use_privacy_mode() const { return use_privacy_mode_; } virtual bool is_session_sharing_enabled() const { return is_session_sharing_enabled_; @@ -211,9 +214,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet { security_level_ = security_level; } } - void set_service_certificate(const std::string& service_certificate) { - service_certificate_ = service_certificate; - } void set_use_privacy_mode(bool use_privacy_mode) { use_privacy_mode_ = use_privacy_mode; } diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 844d635c..377bc082 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -457,6 +457,9 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet { virtual const std::string& service_certificate() const { return service_certificate_; } + virtual void set_service_certificate(const std::string& service_certificate) { + service_certificate_ = service_certificate; + } virtual bool use_privacy_mode() const { return use_privacy_mode_; } virtual bool is_session_sharing_enabled() const { return is_session_sharing_enabled_; @@ -470,9 +473,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet { security_level_ = security_level; } } - void set_service_certificate(const std::string& service_certificate) { - service_certificate_ = service_certificate; - } void set_use_privacy_mode(bool use_privacy_mode) { use_privacy_mode_ = use_privacy_mode; } diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index c13e1c55..ac1b3a7e 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -164,9 +164,8 @@ enum { kLicenseParserNotInitialized4 = ERROR_DRM_VENDOR_MIN + 149, kInvalidParametersLic3 = ERROR_DRM_VENDOR_MIN + 150, kInvalidParametersLic4 = ERROR_DRM_VENDOR_MIN + 151, - kInvalidParametersLic5 = ERROR_DRM_VENDOR_MIN + 152, - kInvalidParametersLic6 = ERROR_DRM_VENDOR_MIN + 153, - kInvalidParametersLic7 = ERROR_DRM_VENDOR_MIN + 154, + kInvalidParametersLic6 = ERROR_DRM_VENDOR_MIN + 152, + kInvalidParametersLic7 = ERROR_DRM_VENDOR_MIN + 153, kLicenseRequestServiceCertificateGenerationError = ERROR_DRM_VENDOR_MIN + 155, kCencInitDataUnavailable = ERROR_DRM_VENDOR_MIN + 156, kPrepareCencContentIdFailed = ERROR_DRM_VENDOR_MIN + 157, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index 546e2cce..8ef2d041 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -317,8 +317,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kInvalidParametersLic3; case wvcdm::INVALID_PARAMETERS_LIC_4: return kInvalidParametersLic4; - case wvcdm::INVALID_PARAMETERS_LIC_5: - return kInvalidParametersLic5; case wvcdm::INVALID_PARAMETERS_LIC_6: return kInvalidParametersLic6; case wvcdm::INVALID_PARAMETERS_LIC_7: @@ -347,10 +345,12 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kLicenseRenewalProhibited; case wvcdm::UNKNOWN_ERROR: return android::ERROR_DRM_UNKNOWN; - case wvcdm::UNUSED_1: - return android::UNKNOWN_ERROR; case wvcdm::SECURE_BUFFER_REQUIRED: return android::ERROR_DRM_CANNOT_HANDLE; + case wvcdm::UNUSED_1: + case wvcdm::UNUSED_2: + case wvcdm::UNUSED_3: + return android::UNKNOWN_ERROR; } // Return here instead of as a default case so that the compiler will warn diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index b880b442..bd56be53 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -210,7 +210,8 @@ class WVDrmPlugin : public android::DrmPlugin, return mServiceCertificate; } - void set_service_certificate(const std::string& serviceCertificate) { + virtual void set_service_certificate( + const std::string& serviceCertificate) { mServiceCertificate = serviceCertificate; }