// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine Master // License Agreement. #ifndef CAS_LICENSE_H #define CAS_LICENSE_H #include #include #include "cas_status.h" #include "crypto_session.h" #include "policy_engine.h" #include "timer.h" namespace wvcas { // CasLicense implements the core functionality needed to interact with service // to obtain and manage entitlements. class CasLicense : public wvutil::TimerHandler, public wvcas::CasEventListener { public: CasLicense() {} virtual ~CasLicense() {} // Initialize CasLicense with a |crypto_session|. |listener| may be null. virtual CasStatus initialize(std::shared_ptr crypto_session, CasEventListener* listener); // Generate a request to obtain a device certificate for requesting // entitlements. The generated message is set in |provisioning_request|. virtual CasStatus GenerateDeviceProvisioningRequest( std::string* provisioning_request) const; // Process a server response containing a device certificate for use in // requesting entitlements. The contained certificate data will be extracted // and wrapped for storage. The public key cert will be returned in // |device_certificate|. The private key information will be wrapped by the // crypto session and returned in |wrapped_rsa_key|. // A secure binary file image containing the device cert is returned in // |device_file| if not nullptr. This file is suitable for storage on a device virtual CasStatus HandleDeviceProvisioningResponse( const std::string& signed_provisioning_response, std::string* device_certificate, std::string* wrapped_rsa_key, std::string* device_file) const; // Generate a request to obtain an EMM (Entitlement Management Message) to // use to enable processing of ECM(s) (Encryption Management Message). // |init_data| is widevine metadata about the stream needed in the request. // |wrapped_rsa_key| and |signed_license_request| are the device certificate // obtained by HandleDeviceProvisioningResponse. virtual CasStatus GenerateEntitlementRequest( const std::string& init_data, const std::string& device_certificate, const std::string& wrapped_rsa_key, LicenseType license_type, std::string* signed_license_request); // Restores a stored license making the keys available for use. virtual CasStatus HandleStoredLicense(const std::string& wrapped_rsa_key, const std::string& license_file); // Process a server response containing a EMM for use in the // processing of ECM(s). If |device_file| is not nullptr and the license // policy allows a license to be stored |device_file| is populated with the // bytes of the license secured for storage. virtual CasStatus HandleEntitlementResponse( const std::string& entitlement_response, std::string* device_file); // Process a previously stored device |certificate| and make it available // for use in an EMM request. virtual CasStatus HandleStoredDrmCert(const std::string& certificate, std::string* device_certificate, std::string* wrapped_rsa_key); // Generate an entitlement renewal request message in // |signed_renewal_request|. virtual CasStatus GenerateEntitlementRenewalRequest( const std::string& device_certificate, std::string* signed_renewal_request); // Process a server response containing a EMM renewal. If |device_file| is not // nullptr and the license policy allows a license renewal to be stored // |device_file| is populated with the bytes of the license secured for // storage. virtual CasStatus HandleEntitlementRenewalResponse( const std::string& renewal_response, std::string* device_file); // Query the license to see if a key is usable. virtual bool CanDecryptContent(const KeyId& key_id) const; // Update the license after handling license remove. Plugin is disabled to // playback stream, store and renew license. virtual void UpdateLicenseForLicenseRemove(); // Query the license to see if storage is allowed. virtual bool CanStoreLicense() const; // Policy timer implentation. void OnTimerEvent() override; // Event listener implementation. void OnSessionRenewalNeeded() override; void OnSessionKeysChange(const KeyStatusMap& keys_status, bool has_new_usable_key) override; void OnExpirationUpdate(int64_t new_expiry_time_seconds) override; void OnLicenseExpiration() override; void OnNewRenewalServerUrl(const std::string& renewal_server_url) override; void OnAgeRestrictionUpdated(const WvCasSessionId& sessionId, uint8_t ecm_age_restriction) override; // Query to see if the license is expired. virtual bool IsExpired() const; // Notify the license that playback decryption has begun. virtual void BeginDecryption(); CasLicense(const CasLicense&) = delete; CasLicense& operator=(const CasLicense&) = delete; private: CasStatus GenerateDeviceProvisioningRequestWithKeybox( std::string* provisioning_request) const; CasStatus GenerateDeviceProvisioningRequestWithOEMCert() const; CasStatus InstallLicense(const std::string& session_key, const std::string& serialized_license, const std::string& core_message, const std::string& signature); CasStatus InstallLicenseRenewal(const std::string& serialized_license, const std::string& core_message, const std::string& signature); virtual std::unique_ptr GetPolicyEngine(); std::unique_ptr policy_engine_; std::shared_ptr crypto_session_; CasEventListener* event_listener_ = nullptr; video_widevine::License license_; std::string emm_request_; std::string emm_response_; std::string renewal_request_; std::string renewal_response_; std::string init_data_; bool is_renewal_in_license_file_; }; } // namespace wvcas #endif // CAS_LICENSE_H