Files
ce_cdm/core/include/license.h
2024-09-05 07:02:36 +00:00

223 lines
7.1 KiB
C++

// 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 <memory>
#include <set>
#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<bool>(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<CryptoKey>& 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<CryptoKey>& license_keys,
const video_widevine::License& license);
CdmResponseType HandleNewEntitledKeys(
const std::vector<PsshEntitledKey>& 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 <typename T>
bool SetTypeAndId(CdmLicenseType license_type, const std::string& request_id,
T* content_id);
// == Creation-time Variables ==
const CdmSessionId session_id_;
std::unique_ptr<wvutil::Clock> 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<InitializationData> 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<PsshEntitledKey> 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<KeyId> content_key_ids_;
std::set<KeyId> entitlement_key_ids_;
#if defined(UNIT_TEST)
friend class CdmLicenseTestPeer;
#endif
}; // class CdmLicense
} // namespace wvcdm
#endif // WVCDM_CORE_LICENSE_H_