Files
media_cas_client/plugin/include/cas_license.h
Lu Chen 41829ca1e5 Add Provisioning 4 support
Widevine provisioning 4 support is added in this patch.
2025-02-25 13:49:37 -08:00

209 lines
8.8 KiB
C++

// 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 <memory>
#include <string>
#include "cas_status.h"
#include "crypto_session.h"
#include "crypto_wrapped_key.h"
#include "file_store.h"
#include "policy_engine.h"
#include "service_certificate.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<CryptoSession> 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(
wvutil::FileSystem& file_system, std::string* provisioning_request);
// 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_private_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(
wvutil::FileSystem* file_system,
const std::string& signed_provisioning_response,
std::string* device_certificate,
CryptoWrappedKey* wrapped_private_key) 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.
// |private_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 CryptoWrappedKey& private_key, LicenseType license_type,
std::string* signed_license_request);
// Restores a stored license making the keys available for use.
virtual CasStatus HandleStoredLicense(const CryptoWrappedKey& private_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,
CryptoWrappedKey* private_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;
// Returns the group id specified in the license. Group id is expected to be
// non-empty if the license is MULTI_CONTENT_LICENSE or GROUP_LICENSE; and
// empty if the license is SINGLE_CONTENT_LICENSE_DEFAULT.
virtual std::string GetGroupId() const;
// If the license is MULTI_CONTENT_LICENSE, the returned vector contains all
// content ids that the license is for. Returns empty if the license if not
// MULTI_CONTENT_LICENSE.
virtual std::vector<std::string> GetContentIdList() const;
// Returns true if the license is MULTI_CONTENT_LICENSE, and false otherwise.
virtual bool IsMultiContentLicense() const;
// Returns true if the license is GROUP_LICENSE, and false otherwise.
virtual bool IsGroupLicense() 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;
void OnFingerprintingUpdated(const CasData& fingerprinting) override;
void OnServiceBlockingUpdated(const CasData& service_blocking) override;
void OnSessionFingerprintingUpdated(const WvCasSessionId& sessionId,
const CasData& fingerprinting) override;
void OnSessionServiceBlockingUpdated(
const WvCasSessionId& sessionId,
const CasData& service_blocking) override;
void OnEntitlementPeriodUpdateNeeded(
const std::string& signed_license_request) override;
// Query to see if the license is expired.
virtual bool IsExpired() const;
// Notify the license that playback decryption has begun.
virtual void BeginDecryption();
// Returns NoError if a valid entitlement period index exists in
// |license_file|. The index will be assigned to |entitlement_period_index|.
static CasStatus GetEntitlementPeriodIndexFromStoredLicense(
const std::string& license_file, uint32_t& entitlement_period_index);
CasLicense(const CasLicense&) = delete;
CasLicense& operator=(const CasLicense&) = delete;
private:
CasStatus GenerateDeviceProvisioningRequestWithKeybox(
std::string* provisioning_request) const;
CasStatus GetProvisioning40RequestInternal(
wvutil::FileSystem& file_system,
std::string* serialized_provisioning_request);
CasStatus FillEncryptedClientId(
const std::string& client_token,
video_widevine::ProvisioningRequest& provisioning_request,
const ServiceCertificate& service_certificate) const;
void FillClientProperties(
video_widevine::ClientIdentification& client_id) const;
CasStatus HandleProvisioning40Response(
wvutil::FileSystem* file_system,
const video_widevine::SignedProvisioningMessage& signed_response,
std::string* cert, CryptoWrappedKey* wrapped_key) 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<PolicyEngine> GetPolicyEngine();
std::unique_ptr<PolicyEngine> policy_engine_;
std::shared_ptr<CryptoSession> 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_ = false;
std::unique_ptr<ServiceCertificate> wv_service_cert_;
// The wrapped private key in provisioning 4 generated by calling
// GenerateCertificateKeyPair. It will be saved to file system if a valid
// response is received.
std::string provisioning_40_wrapped_private_key_;
// Key type of the generated key pair in provisioning 4.
CryptoWrappedKey::Type provisioning_40_key_type_;
};
} // namespace wvcas
#endif // CAS_LICENSE_H