// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. #ifndef WVCDM_CORE_LICENSE_H_ #define WVCDM_CORE_LICENSE_H_ #include #include #include "initialization_data.h" #include "license_protocol.pb.h" #include "service_certificate.h" #include "wv_cdm_types.h" #include "wv_class_utils.h" namespace wvutil { class Clock; } // namespace wvutil namespace wvcdm { class CdmSession; class CryptoKey; class CryptoSession; class InitializationData; class PolicyEngine; class CdmLicense { public: using PsshEntitledKey = video_widevine::WidevinePsshData::EntitledKey; CdmLicense() = delete; WVCDM_DISALLOW_COPY_AND_MOVE(CdmLicense); explicit CdmLicense(const CdmSessionId& session_id); virtual ~CdmLicense(); virtual bool Init(bool use_privacy_mode, const std::string& signed_service_certificate, CryptoSession* session, PolicyEngine* policy_engine); // == Accessors == virtual bool is_offline() const { return is_offline_; } virtual std::string provider_session_token() { return provider_session_token_; } virtual bool HasInitData() { return static_cast(stored_init_data_); } virtual const video_widevine::VersionInfo& GetServiceVersion() { return latest_service_version_; } virtual bool IsKeyLoaded(const KeyId& key_id); // == Service Certificate API == // Override the currently-installed service certificate with a new service // certificate. virtual CdmResponseType SetServiceCertificate( const std::string& signed_service_certificate); // == License Restoring API == virtual CdmResponseType RestoreOfflineLicense( const std::string& client_token, const CdmKeyMessage& license_request, const CdmKeyResponse& license_response, const CdmKeyResponse& license_renewal_response, int64_t playback_start_time, int64_t last_playback_time, int64_t grace_period_end_time, CdmSession* cdm_session); virtual CdmResponseType RestoreLicenseForRelease( const std::string& client_token, const CdmKeyMessage& license_request, const CdmKeyResponse& license_response); // == Request/Response API == virtual CdmResponseType PrepareKeyRequest( const InitializationData& init_data, const std::string& client_token, CdmLicenseType license_type, const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request, std::string* server_url); virtual CdmResponseType PrepareKeyUpdateRequest( bool is_renewal, const CdmAppParameterMap& app_parameters, CdmSession* cdm_session, CdmKeyMessage* signed_request, std::string* server_url); virtual CdmResponseType HandleKeyResponse( bool is_restore, const CdmKeyResponse& license_response); virtual CdmResponseType HandleKeyUpdateResponse( bool is_renewal, bool is_restore, const CdmKeyResponse& license_response); virtual CdmResponseType HandleEmbeddedKeyData( const InitializationData& init_data); // == Utilities == static bool ExtractProviderSessionToken( const CdmKeyResponse& license_response, std::string* provider_session_token); // == Test Accessors == // Testing only. Caller retains ownership of pointers. void set_crypto_session(CryptoSession* crypto_session) { crypto_session_ = crypto_session; } void set_policy_engine(PolicyEngine* policy_engine) { policy_engine_ = policy_engine; } private: // Test Constructor. // CdmLicense takes ownership of the clock. CdmLicense(const CdmSessionId& session_id, wvutil::Clock* clock); // == Internal Request/Response API == // Prepare to reload a key update message. Some special code is needed to work // around b/166010609. // TODO(b/166007195): Remove this. CdmResponseType PrepareKeyUpdateReload(CdmSession* cdm_session); CdmResponseType HandleKeyErrorResponse( const video_widevine::SignedMessage& signed_message); CdmResponseType HandleContentKeyResponse( bool is_restore, const std::string& session_key, const std::string& msg, const std::string& core_message, const std::string& signature, const std::vector& license_keys, const video_widevine::License& license); // Loads the entitlement keys in |license_keys| into // the crypto session. // // In addition, it also extracts content keys from // |request_entitled_keys_| and loads them for use. CdmResponseType HandleEntitlementKeyResponse( bool is_restore, const std::string& session_key, const std::string& msg, const std::string& core_message, const std::string& signature, const std::vector& license_keys, const video_widevine::License& license); CdmResponseType HandleNewEntitledKeys( const std::vector& packaged_entitled_keys); // == Internal Utilities == CdmResponseType PrepareClientId( const CdmAppParameterMap& app_parameters, const std::string& provider_client_token, video_widevine::LicenseRequest* license_request); CdmResponseType PrepareContentId( const InitializationData& init_data, CdmLicenseType license_type, const std::string& request_id, video_widevine::LicenseRequest* license_request); template bool SetTypeAndId(CdmLicenseType license_type, const std::string& request_id, T* content_id); // == Creation-time Variables == const CdmSessionId session_id_; std::unique_ptr clock_; // == Initialization-time Variables == bool initialized_ = false; CryptoSession* crypto_session_ = nullptr; PolicyEngine* policy_engine_ = nullptr; // Associated with ClientIdentification encryption bool use_privacy_mode_ = false; ServiceCertificate service_certificate_; video_widevine::ProtocolVersion protocol_version_ = video_widevine::VERSION_2_2; // == License Request/Response variables == std::string client_token_; std::unique_ptr stored_init_data_; // The nonce used in the original license request. uint32_t license_nonce_ = 0; CdmKeyMessage license_request_; // For entitlement key licensing. This holds the keys from the init_data. // These keys are extracted from the PSSH when we generate a license request. // It is used to load content keys after we have received a license and // entitlement keys. It is also used in updating the key status info. std::vector request_entitled_keys_; std::string provider_client_token_; std::string provider_session_token_; bool renew_with_client_id_ = false; std::string renewal_server_url_; // This is the latest version info extracted from the SignedMessage in // HandleKeyResponse video_widevine::VersionInfo latest_service_version_; // == License Life-Time Variables == CdmLicenseKeyType license_key_type_ = kLicenseKeyTypeContent; bool is_offline_ = false; std::set content_key_ids_; std::set entitlement_key_ids_; #if defined(UNIT_TEST) friend class CdmLicenseTestPeer; #endif }; // class CdmLicense } // namespace wvcdm #endif // WVCDM_CORE_LICENSE_H_