// 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 "disallow_copy_and_assign.h" #include "initialization_data.h" #include "license_protocol.pb.h" #include "service_certificate.h" #include "wv_cdm_types.h" namespace video_widevine { class SignedMessage; class LicenseRequest; class VersionInfo; } // namespace video_widevine namespace wvutil { class Clock; } namespace wvcdm { class CryptoSession; class PolicyEngine; class CdmSession; class CryptoKey; using ::google::protobuf::RepeatedPtrField; using video_widevine::License_KeyContainer; using video_widevine::VersionInfo; using video_widevine::WidevinePsshData_EntitledKey; class CdmLicense { public: 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); // Override the currently-installed service certificate with a new service // certificate. virtual CdmResponseType SetServiceCertificate( const std::string& signed_service_certificate); 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); 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); virtual bool HasInitData() { return static_cast(stored_init_data_); } virtual bool IsKeyLoaded(const KeyId& key_id); virtual std::string provider_session_token() { return provider_session_token_; } virtual bool is_offline() const { return is_offline_; } virtual bool supports_core_messages() const { return supports_core_messages_; } virtual const VersionInfo& GetServiceVersion() { return latest_service_version_; } static bool ExtractProviderSessionToken( const CdmKeyResponse& license_response, std::string* provider_session_token); private: CdmResponseType HandleKeyErrorResponse( const video_widevine::SignedMessage& signed_message); 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); CdmResponseType HandleContentKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, const std::string& signature, const std::string& mac_key_iv, const std::string& mac_key, const std::vector& key_array, const video_widevine::License& license); // HandleEntitlementKeyResponse loads the entitlement keys in |key_array| into // the crypto session. In addition, it also extracts content keys from // |wrapped_keys_| and loads them for use. CdmResponseType HandleEntitlementKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, const std::string& signature, const std::string& mac_key_iv, const std::string& mac_key, const std::vector& key_array, const video_widevine::License& license); // 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 HandleNewEntitledKeys( const std::vector& wrapped_keys); template bool SetTypeAndId(CdmLicenseType license_type, const std::string& request_id, T* content_id); CryptoSession* crypto_session_; PolicyEngine* policy_engine_; std::string server_url_; std::string client_token_; const CdmSessionId session_id_; std::unique_ptr stored_init_data_; bool initialized_; std::set loaded_keys_; std::string provider_session_token_; bool renew_with_client_id_; bool is_offline_; // Indicates whether the license contains / supports OEMCrypto-level // support for core messages. If the original license was created before // upgrading from V15, or if the licensing server is still running V15, // then the license does not support core messages. bool supports_core_messages_; // Associated with ClientIdentification encryption bool use_privacy_mode_; ServiceCertificate service_certificate_; // Used for certificate based licensing CdmKeyMessage key_request_; std::unique_ptr clock_; // For testing // CdmLicense takes ownership of the clock. CdmLicense(const CdmSessionId& session_id, wvutil::Clock* clock); // 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 wrapped_keys_; CdmLicenseKeyType license_key_type_; RepeatedPtrField entitlement_keys_; std::string provider_client_token_; // This is the latest version info extracted from the SignedMessage in // HandleKeyResponse VersionInfo latest_service_version_; // The nonce used in the original license request. uint32_t license_nonce_; #if defined(UNIT_TEST) friend class CdmLicenseTestPeer; #endif CORE_DISALLOW_COPY_AND_ASSIGN(CdmLicense); }; } // namespace wvcdm #endif // WVCDM_CORE_LICENSE_H_