Note that this version does not have Widevine Provisioning 4.0 support. It is only suitable for device upgrades. A new patch with provisioning 4.0 support will be made later.
185 lines
7.7 KiB
C++
185 lines
7.7 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 "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<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(
|
|
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;
|
|
|
|
// 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 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;
|
|
};
|
|
|
|
} // namespace wvcas
|
|
|
|
#endif // CAS_LICENSE_H
|