Source release 17.1.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_BUFFER_READER_H_
|
||||
#define WVCDM_CORE_BUFFER_READER_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_CLIENT_PROPERTY_SET_H_
|
||||
#define WVCDM_CORE_CDM_CLIENT_PROPERTY_SET_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_ENGINE_H_
|
||||
#define WVCDM_CORE_CDM_ENGINE_H_
|
||||
@@ -24,11 +24,11 @@
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CdmClientPropertySet;
|
||||
class CdmEngineFactory;
|
||||
class CdmSession;
|
||||
class CryptoEngine;
|
||||
class OtaKeyboxProvisioner;
|
||||
class UsagePropertySet;
|
||||
class WvCdmEventListener;
|
||||
|
||||
@@ -75,6 +75,10 @@ class CdmEngine {
|
||||
// app_parameters: Additional, application-specific parameters that factor
|
||||
// into the request generation. This is ignored for release
|
||||
// and renewal requests.
|
||||
// Certain app parameter keys are reserved for CDM
|
||||
// device identification on the license server. These
|
||||
// parameters will be overwritten by the CDM request
|
||||
// generator.
|
||||
// key_request: This must be non-null and point to a CdmKeyRequest. The
|
||||
// message field will be filled with the key request, the
|
||||
// type field will be filled with the key request type,
|
||||
@@ -92,14 +96,14 @@ class CdmEngine {
|
||||
// (c) accept a release response and release an offline license or secure
|
||||
// stop.
|
||||
// (d) accept a service certificate and cache that information for the
|
||||
// the lifetime of the session.
|
||||
// lifetime of the session.
|
||||
//
|
||||
// |session_id| identifies the session that generated the request and can
|
||||
// process the response. Should be empty if a release response.
|
||||
// |key_data| is the license, renewal, release response or service
|
||||
// certificate response.
|
||||
// |license_type| must not be null. If the result is KEY_ADDED, this out
|
||||
// parameter indicates the type of license containd in
|
||||
// parameter indicates the type of license contained in
|
||||
// key_data. For any other return code, no value is provided.
|
||||
// |key_set_id| should be non-null and specified if license release.
|
||||
// If offline license or streaming license associated with
|
||||
@@ -142,7 +146,7 @@ class CdmEngine {
|
||||
const CdmSessionId& session_id, const std::string& service_certificate);
|
||||
|
||||
// Query system information
|
||||
virtual CdmResponseType QueryStatus(SecurityLevel security_level,
|
||||
virtual CdmResponseType QueryStatus(RequestedSecurityLevel security_level,
|
||||
const std::string& query_token,
|
||||
std::string* query_response);
|
||||
|
||||
@@ -180,19 +184,25 @@ class CdmEngine {
|
||||
virtual CdmResponseType GetProvisioningRequest(
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& service_certificate,
|
||||
SecurityLevel requested_security_level, CdmProvisioningRequest* request,
|
||||
std::string* default_url);
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmProvisioningRequest* request, std::string* default_url);
|
||||
|
||||
// Verify and process a provisioning response.
|
||||
virtual CdmResponseType HandleProvisioningResponse(
|
||||
const CdmProvisioningResponse& response,
|
||||
SecurityLevel requested_security_level, std::string* cert,
|
||||
RequestedSecurityLevel requested_security_level, std::string* cert,
|
||||
std::string* wrapped_key);
|
||||
|
||||
// Return true if there is a device certificate on the current
|
||||
// (origin-specific) file system.
|
||||
virtual bool IsProvisioned(CdmSecurityLevel security_level);
|
||||
|
||||
// Retrieves the current provisioning status based on whether a DRM
|
||||
// certificate or an OEM certificate (in provisioning 4) exists the current
|
||||
// (origin-specific) file system.
|
||||
virtual CdmProvisioningStatus GetProvisioningStatus(
|
||||
CdmSecurityLevel security_level);
|
||||
|
||||
// Remove device DRM certificate from the current (origin-specific) file
|
||||
// system. This will force the device to reprovision itself.
|
||||
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level);
|
||||
@@ -233,15 +243,24 @@ class CdmEngine {
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info);
|
||||
|
||||
// Retrieve the usage info for the specified pst.
|
||||
// Returns UNKNOWN_ERROR if no usage info was found.
|
||||
// id. If |error_detail| is not null, an additional error code may be provided
|
||||
// Retrieve usage info whose PST is specified by |ssid|
|
||||
// If |error_detail| is not null, an additional error code may be provided
|
||||
// in the event of an error.
|
||||
virtual CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info);
|
||||
|
||||
// Retrieve usage info for a given security level and whose
|
||||
// PST is specified by |ssid|.
|
||||
// If |error_detail| is not null, an additional error code may be provided
|
||||
// in the event of an error.
|
||||
virtual CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
RequestedSecurityLevel security_level,
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info);
|
||||
|
||||
// Remove all usage records for the current origin.
|
||||
virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id,
|
||||
CdmSecurityLevel security_level);
|
||||
@@ -299,6 +318,18 @@ class CdmEngine {
|
||||
|
||||
virtual size_t SessionSize() const { return session_map_.Size(); }
|
||||
|
||||
// This tells the OEMCrypto adapter to ignore the next |count| keyboxes and
|
||||
// report that it needs provisioning instead.
|
||||
static CdmResponseType SetDebugIgnoreKeyboxCount(uint32_t count) {
|
||||
return CryptoSession::SetDebugIgnoreKeyboxCount(count);
|
||||
}
|
||||
|
||||
// This tells the OEMCrypto adapter to allow the device to continue with a
|
||||
// test keybox. Otherwise, the keybox is reported as invalid.
|
||||
static CdmResponseType SetAllowTestKeybox(bool allow) {
|
||||
return CryptoSession::SetAllowTestKeybox(allow);
|
||||
}
|
||||
|
||||
static CdmResponseType ParseDecryptHashString(const std::string& hash_string,
|
||||
CdmSessionId* id,
|
||||
uint32_t* frame_number,
|
||||
@@ -344,11 +375,26 @@ class CdmEngine {
|
||||
}
|
||||
virtual const std::string& GetAppPackageName() { return app_package_name_; }
|
||||
virtual void SetSpoid(const std::string& spoid) { spoid_ = spoid; }
|
||||
virtual CdmResponseType SetPlaybackId(const CdmSessionId& session_id,
|
||||
const std::string& playback_id);
|
||||
|
||||
virtual void SetUserId(uint32_t user_id) { user_id_ = user_id; }
|
||||
virtual uint32_t GetUserId() const { return user_id_; }
|
||||
|
||||
// Changes the rules used for calculating the fallback duration
|
||||
// when OTA keybox provisioning fails.
|
||||
// Default rules use fallback duration measured in days, with exponential
|
||||
// backoff.
|
||||
// Fast rules use fallback durations of a few seconds, without exponential
|
||||
// backoff.
|
||||
// This method has no effect if OTA keybox is not required.
|
||||
virtual void SetDefaultOtaKeyboxFallbackDurationRules();
|
||||
virtual void SetFastOtaKeyboxFallbackDurationRules();
|
||||
|
||||
protected:
|
||||
friend class CdmEngineFactory;
|
||||
|
||||
CdmEngine(FileSystem* file_system,
|
||||
CdmEngine(wvutil::FileSystem* file_system,
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics);
|
||||
|
||||
private:
|
||||
@@ -361,7 +407,7 @@ class CdmEngine {
|
||||
|
||||
bool ValidateKeySystem(const CdmKeySystem& key_system);
|
||||
CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
SecurityLevel requested_security_level,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
int* error_detail, CdmUsageInfo* usage_info);
|
||||
|
||||
void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
|
||||
@@ -370,6 +416,13 @@ class CdmEngine {
|
||||
|
||||
void CloseExpiredReleaseSessions();
|
||||
|
||||
// Returns "true" if |okp_provisioner_| should be checked.
|
||||
bool OkpCheck();
|
||||
// Returns "true" if CdmEngine should always fallback to L3.
|
||||
bool OkpIsInFallbackMode();
|
||||
void OkpTriggerFallback();
|
||||
void OkpCleanUp();
|
||||
|
||||
// instance variables
|
||||
|
||||
/*
|
||||
@@ -385,9 +438,10 @@ class CdmEngine {
|
||||
CdmSessionMap session_map_;
|
||||
CdmReleaseKeySetMap release_key_sets_;
|
||||
std::unique_ptr<CertificateProvisioning> cert_provisioning_;
|
||||
FileSystem* file_system_;
|
||||
Clock clock_;
|
||||
wvutil::FileSystem* file_system_;
|
||||
wvutil::Clock clock_;
|
||||
std::string spoid_;
|
||||
uint32_t user_id_;
|
||||
|
||||
// Usage related variables
|
||||
// Used to isolate a single active usage information license. Loading,
|
||||
@@ -413,6 +467,23 @@ class CdmEngine {
|
||||
// occur that may subsequently call back into CdmEngine.
|
||||
std::recursive_mutex session_map_lock_;
|
||||
|
||||
// OTA Keybox Provisioning (OKP)
|
||||
// Engine should check for the OKP status of the device before opening
|
||||
// sessions or generating DRM cert provisioning requests.
|
||||
bool okp_initialized_ = false;
|
||||
// If OKP is required, then the engine should create an instance
|
||||
// of |okp_provisioner_|. If the instance exists, it should be used
|
||||
// for GetProvisionRequest, ProvideProvisionRequest, and
|
||||
// OpenSession when requested with default security level.
|
||||
std::unique_ptr<OtaKeyboxProvisioner> okp_provisioner_;
|
||||
// Should the engine need to fallback, this flag should be set to
|
||||
// true and |okp_provisioner_| should be cleared. All follow-up
|
||||
// requests from the app with security level default should use L3.
|
||||
bool okp_fallback_ = false;
|
||||
// To prevent race conditions around the engine's OKP state, this mutex
|
||||
// should be locked before the use of any of the |okp_*| variables.
|
||||
std::mutex okp_mutex_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_ENGINE_FACTORY_H_
|
||||
#define WVCDM_CORE_CDM_ENGINE_FACTORY_H_
|
||||
@@ -17,7 +17,7 @@ class CdmEngineFactory {
|
||||
public:
|
||||
// Creates a new instance of a CdmEngine. Caller retains ownership of the
|
||||
// |files_system| which cannot be null.
|
||||
static CdmEngine* CreateCdmEngine(FileSystem* file_system);
|
||||
static CdmEngine* CreateCdmEngine(wvutil::FileSystem* file_system);
|
||||
|
||||
private:
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngineFactory);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#ifndef WVCDM_CORE_CDM_ENGINE_METRICS_DECORATOR_H_
|
||||
#define WVCDM_CORE_CDM_ENGINE_METRICS_DECORATOR_H_
|
||||
|
||||
@@ -47,7 +47,7 @@ class CdmEngineMetricsImpl : public T {
|
||||
// |file_system| and |metrics| must not be null.
|
||||
// |metrics| is used within the base class constructor. So, it must be
|
||||
// passed in as a dependency and provided to the base constructor.
|
||||
CdmEngineMetricsImpl(FileSystem* file_system,
|
||||
CdmEngineMetricsImpl(wvutil::FileSystem* file_system,
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics)
|
||||
: T(file_system, metrics), metrics_(metrics) {
|
||||
metrics_->cdm_engine_creation_time_millis_.Record(clock_.GetCurrentTime());
|
||||
@@ -153,12 +153,11 @@ class CdmEngineMetricsImpl : public T {
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType GetProvisioningRequest(CdmCertificateType cert_type,
|
||||
const std::string& cert_authority,
|
||||
const std::string& service_certificate,
|
||||
SecurityLevel requested_security_level,
|
||||
CdmProvisioningRequest* request,
|
||||
std::string* default_url) override {
|
||||
CdmResponseType GetProvisioningRequest(
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& service_certificate,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmProvisioningRequest* request, std::string* default_url) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::GetProvisioningRequest(
|
||||
cert_type, cert_authority, service_certificate,
|
||||
@@ -169,7 +168,7 @@ class CdmEngineMetricsImpl : public T {
|
||||
|
||||
CdmResponseType HandleProvisioningResponse(
|
||||
const CdmProvisioningResponse& response,
|
||||
SecurityLevel requested_security_level, std::string* cert,
|
||||
RequestedSecurityLevel requested_security_level, std::string* cert,
|
||||
std::string* wrapped_key) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::HandleProvisioningResponse(
|
||||
@@ -270,7 +269,7 @@ class CdmEngineMetricsImpl : public T {
|
||||
|
||||
private:
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics_;
|
||||
Clock clock_;
|
||||
wvutil::Clock clock_;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_SESSION_H_
|
||||
#define WVCDM_CORE_CDM_SESSION_H_
|
||||
@@ -33,9 +33,9 @@ class CdmSession {
|
||||
public:
|
||||
// Creates a new instance of the CdmSession with the given |file_system|
|
||||
// and |metrics| parameters. Both parameters are owned by the caller and
|
||||
// must remain in scope througout the scope of the new instance. |metrics|
|
||||
// must remain in scope throughout the scope of the new instance. |metrics|
|
||||
// must not be null.
|
||||
CdmSession(FileSystem* file_system,
|
||||
CdmSession(wvutil::FileSystem* file_system,
|
||||
std::shared_ptr<metrics::SessionMetrics> metrics);
|
||||
virtual ~CdmSession();
|
||||
|
||||
@@ -49,7 +49,7 @@ class CdmSession {
|
||||
// cached at the time Init() is called.
|
||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
|
||||
|
||||
// Initializes this instance of CdmSession with the given parmeters.
|
||||
// Initializes this instance of CdmSession with the given parameters.
|
||||
// All parameters are owned by the caller.
|
||||
//
|
||||
// |cdm_client_property_set| is caller owned, may be null, but must be in
|
||||
@@ -60,9 +60,13 @@ class CdmSession {
|
||||
//
|
||||
// |event_listener| is caller owned, may be null, but must be in scope as long
|
||||
// as the session is in scope.
|
||||
//
|
||||
// |forced_level3|_is used to specify whether the "default" security level
|
||||
// should always use L3 even if L1 is available.
|
||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
const CdmSessionId* forced_session_id,
|
||||
WvCdmEventListener* event_listener);
|
||||
WvCdmEventListener* event_listener,
|
||||
bool forced_level3);
|
||||
|
||||
// Restores an offline session identified by the |key_set_id| and
|
||||
// |license_type|. The |error_detail| will be filled with an internal error
|
||||
@@ -137,7 +141,7 @@ class CdmSession {
|
||||
virtual void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
|
||||
|
||||
virtual void GetApplicationId(std::string* app_id);
|
||||
virtual SecurityLevel GetRequestedSecurityLevel() {
|
||||
virtual RequestedSecurityLevel GetRequestedSecurityLevel() {
|
||||
return requested_security_level_;
|
||||
}
|
||||
virtual CdmSecurityLevel GetSecurityLevel() { return security_level_; }
|
||||
@@ -160,8 +164,8 @@ class CdmSession {
|
||||
license_parser_->provider_session_token().size() > 0);
|
||||
}
|
||||
|
||||
virtual CdmUsageSupportType get_usage_support_type() {
|
||||
return usage_support_type_;
|
||||
virtual bool supports_usage_info() const {
|
||||
return usage_table_header_ != nullptr;
|
||||
}
|
||||
|
||||
// This method will remove keys by resetting crypto resources and
|
||||
@@ -219,11 +223,25 @@ class CdmSession {
|
||||
private:
|
||||
friend class CdmSessionTest;
|
||||
|
||||
// Both these methods will attempt to load wrapped key material and
|
||||
// cache values in |drm_certificate_| and |wrapped_private_key_|
|
||||
// if successful.
|
||||
// This method will load the key from persistent storage.
|
||||
CdmResponseType LoadPrivateKey();
|
||||
// This method will load the specified key if valid or otherwise load
|
||||
// the information from the legacy certificate.
|
||||
CdmResponseType LoadPrivateOrLegacyKey(
|
||||
const std::string& certificate,
|
||||
const CryptoWrappedKey& wrapped_private_key);
|
||||
|
||||
CdmResponseType LoadPrivateKey(const std::string& certificate,
|
||||
const CryptoWrappedKey& wrapped_private_key);
|
||||
|
||||
bool GenerateKeySetId(bool atsc_mode_enabled, CdmKeySetId* key_set_id);
|
||||
|
||||
CdmResponseType StoreLicense();
|
||||
|
||||
bool StoreLicense(DeviceFiles::LicenseState state, int* error_detail);
|
||||
bool StoreLicense(CdmOfflineLicenseState state, int* error_detail);
|
||||
|
||||
bool UpdateUsageInfo();
|
||||
|
||||
@@ -239,12 +257,6 @@ class CdmSession {
|
||||
// true otherwise.
|
||||
bool VerifyOfflineUsageEntry();
|
||||
|
||||
// On android, we previously permitted a license to be loaded and restored
|
||||
// in the same session. This method releases resources so that
|
||||
// CdmSession::Init can safely be invoked before a new license is restored.
|
||||
// TODO(b/161865160): Investigate whether we can dispense with this scenario.
|
||||
virtual CdmResponseType ReleaseOfflineResources();
|
||||
|
||||
// These setters are for testing only. Takes ownership of the pointers.
|
||||
void set_license_parser(CdmLicense* license_parser);
|
||||
void set_crypto_session(CryptoSession* crypto_session);
|
||||
@@ -254,14 +266,14 @@ class CdmSession {
|
||||
// instance variables
|
||||
std::shared_ptr<metrics::SessionMetrics> metrics_;
|
||||
metrics::CryptoMetrics* crypto_metrics_;
|
||||
metrics::TimerMetric life_span_;
|
||||
metrics::TimerMetric license_request_latency_;
|
||||
metrics::Timer life_span_;
|
||||
metrics::Timer license_request_latency_;
|
||||
CdmKeyRequestType key_request_type_;
|
||||
|
||||
bool initialized_;
|
||||
bool closed_; // Session closed, but final shared_ptr has not been released.
|
||||
CdmSessionId session_id_;
|
||||
FileSystem* file_system_;
|
||||
wvutil::FileSystem* file_system_;
|
||||
std::unique_ptr<CdmLicense> license_parser_;
|
||||
std::unique_ptr<CryptoSession> crypto_session_;
|
||||
std::unique_ptr<PolicyEngine> policy_engine_;
|
||||
@@ -271,18 +283,33 @@ class CdmSession {
|
||||
bool is_release_;
|
||||
bool is_temporary_;
|
||||
CdmSecurityLevel security_level_;
|
||||
SecurityLevel requested_security_level_;
|
||||
RequestedSecurityLevel requested_security_level_;
|
||||
// If |forced_level3_|, |security_level_| and |requested_security_level_|
|
||||
// MUST be set to kSecurityLevelL3 and kLevel3, respectively.
|
||||
bool forced_level3_ = false;
|
||||
CdmAppParameterMap app_parameters_;
|
||||
bool atsc_mode_enabled_ = false;
|
||||
std::string drm_certificate_;
|
||||
CryptoWrappedKey wrapped_private_key_;
|
||||
|
||||
// decryption flags
|
||||
bool is_initial_decryption_;
|
||||
bool has_decrypted_since_last_report_; // ... last report to policy engine.
|
||||
// Decryption flags.
|
||||
// Indiates that the next call to Decrypt will be the first for this
|
||||
// license.
|
||||
bool is_initial_decryption_ = true;
|
||||
// Set to true if a successful call to Decrypt has occurred. Cleared
|
||||
// when the policy engine has been notified about successful
|
||||
// decryption.
|
||||
bool has_decrypted_since_last_report_ = false;
|
||||
// Set to true if the last call to Decrypt resulted in a failure.
|
||||
// Cleared when the call to decrypt has succeeded.
|
||||
bool last_decrypt_failed_ = false;
|
||||
|
||||
// Usage related flags and data
|
||||
bool is_initial_usage_update_;
|
||||
bool is_usage_update_needed_;
|
||||
CdmUsageSupportType usage_support_type_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
// Only assign |usage_table_header_| if capable of supporting usage
|
||||
// information.
|
||||
UsageTableHeader* usage_table_header_ = nullptr;
|
||||
uint32_t usage_entry_number_;
|
||||
CdmUsageEntry usage_entry_;
|
||||
std::string usage_provider_session_token_;
|
||||
@@ -300,18 +327,6 @@ class CdmSession {
|
||||
// license type release and offline related information
|
||||
CdmKeySetId key_set_id_;
|
||||
|
||||
// TODO(b/161865160): Use these variables to cache Init parameters. Remove
|
||||
// when b/ has been addressed.
|
||||
// |cdm_client_property_set_| and |event_listener_| point to a data
|
||||
// member of WVDrmPlugin or WVDrmPlugin itself. It is safe for CdmSession
|
||||
// to make use of these objects without taking ownership since WVDrmPlugin
|
||||
// lifetime exceeds CdmSession (WVDrmPlugin indirectly owns CdmSession
|
||||
// objects). These pointers if set, should be valid till CdmSession
|
||||
// destruction.
|
||||
CdmClientPropertySet* cdm_client_property_set_ = nullptr;
|
||||
CdmSessionId* forced_session_id_ = nullptr;
|
||||
CdmSessionId forced_session_id_value_;
|
||||
WvCdmEventListener* event_listener_ = nullptr;
|
||||
bool has_license_been_loaded_ = false;
|
||||
bool has_license_been_restored_ = false;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_SESSION_MAP_H_
|
||||
#define WVCDM_CORE_CDM_SESSION_MAP_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CERTIFICATE_PROVISIONING_H_
|
||||
#define WVCDM_CORE_CERTIFICATE_PROVISIONING_H_
|
||||
@@ -16,11 +16,14 @@
|
||||
#include "service_certificate.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvutil {
|
||||
class FileSystem;
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CdmClientPropertySet;
|
||||
class CdmSession;
|
||||
class FileSystem;
|
||||
class ServiceCertificate;
|
||||
|
||||
class CertificateProvisioning {
|
||||
@@ -35,17 +38,16 @@ class CertificateProvisioning {
|
||||
|
||||
// Construct a valid provisioning request.
|
||||
// The request will be sent to the provisioning server.
|
||||
CdmResponseType GetProvisioningRequest(SecurityLevel requested_security_level,
|
||||
CdmCertificateType cert_type,
|
||||
const std::string& cert_authority,
|
||||
const std::string& origin,
|
||||
const std::string& spoid,
|
||||
CdmProvisioningRequest* request,
|
||||
std::string* default_url);
|
||||
CdmResponseType GetProvisioningRequest(
|
||||
wvutil::FileSystem* file_system,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& origin, const std::string& spoid,
|
||||
CdmProvisioningRequest* request, std::string* default_url);
|
||||
|
||||
// Process the provisioning response.
|
||||
CdmResponseType HandleProvisioningResponse(
|
||||
FileSystem* file_system, const CdmProvisioningResponse& response,
|
||||
wvutil::FileSystem* file_system, const CdmProvisioningResponse& response,
|
||||
std::string* cert, std::string* wrapped_key);
|
||||
|
||||
bool supports_core_messages() const { return supports_core_messages_; }
|
||||
@@ -54,26 +56,72 @@ class CertificateProvisioning {
|
||||
|
||||
// Extract serial number and system ID from a DRM Device certificate.
|
||||
// Either |serial_number| or |system_id| may be null, but not both.
|
||||
// Both |creation_time_seconds| and |expiration_time_seconds| may be null.
|
||||
// |creation_time_seconds| and |expiration_time_seconds| will be set to -1
|
||||
// if not present, 0 if unlimited and a valid time otherwise
|
||||
static bool ExtractDeviceInfo(const std::string& device_certificate,
|
||||
std::string* serial_number,
|
||||
uint32_t* system_id);
|
||||
std::string* serial_number, uint32_t* system_id,
|
||||
int64_t* creation_time_seconds,
|
||||
int64_t* expiration_time_seconds);
|
||||
|
||||
// Removes json wrapping if applicable to extract the
|
||||
// SignedProvisioningMessage
|
||||
static bool ExtractAndDecodeSignedMessageForTesting(
|
||||
static bool ExtractAndDecodeSignedMessage(
|
||||
const std::string& provisioning_response, std::string* result);
|
||||
|
||||
// Retrieve the provisioning server URL used for certificate
|
||||
// provisioning. This will be the same value as returned in
|
||||
// |default_url| by GetProvisioningRequest().
|
||||
static void GetProvisioningServerUrl(std::string* default_url);
|
||||
|
||||
private:
|
||||
CdmResponseType GetProvisioningRequestInternal(
|
||||
wvutil::FileSystem* file_system,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& origin, const std::string& spoid,
|
||||
CdmProvisioningRequest* request, std::string* default_url);
|
||||
CdmResponseType GetProvisioning40RequestInternal(
|
||||
wvutil::FileSystem* file_system, const std::string& origin,
|
||||
const std::string& spoid, CdmProvisioningRequest* request,
|
||||
std::string* default_url);
|
||||
CdmResponseType FillEncryptedClientId(
|
||||
const std::string& client_token,
|
||||
video_widevine::ProvisioningRequest& provisioning_request,
|
||||
const ServiceCertificate& service_certificate);
|
||||
CdmResponseType FillEncryptedClientIdWithAdditionalParameter(
|
||||
const std::string& client_token,
|
||||
const CdmAppParameterMap& additional_parameter,
|
||||
video_widevine::ProvisioningRequest& provisioning_request,
|
||||
const ServiceCertificate& service_certificate);
|
||||
CdmResponseType HandleProvisioning40Response(
|
||||
wvutil::FileSystem* file_system, const std::string& response_message);
|
||||
|
||||
CdmResponseType SetSpoidParameter(
|
||||
const std::string& origin, const std::string& spoid,
|
||||
video_widevine::ProvisioningRequest* request);
|
||||
|
||||
video_widevine::SignedProvisioningMessage::ProtocolVersion
|
||||
GetProtocolVersion();
|
||||
video_widevine::SignedProvisioningMessage::ProvisioningType
|
||||
GetProvisioningType();
|
||||
|
||||
// Closes crypto session if one is open. Avoid calling this method when
|
||||
// processing a response. Multiple provisioning responses might be
|
||||
// simultaneously in flight. Only the response associated with the last
|
||||
// provisioning request can be processed. All the other responses will
|
||||
// fail. If the session is closed when these responses fail, even the one
|
||||
// associated with the last provisioning request may fail.
|
||||
CdmResponseType CloseSessionOnError(CdmResponseType status);
|
||||
void CloseSession();
|
||||
|
||||
std::unique_ptr<CryptoSession> crypto_session_;
|
||||
CdmCertificateType cert_type_;
|
||||
std::unique_ptr<ServiceCertificate> service_certificate_;
|
||||
// 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_;
|
||||
|
||||
// Indicates whether OEMCrypto supports core messages, and whether the
|
||||
// CDM should expect a core message in the response. This is primarily
|
||||
|
||||
@@ -1,39 +1,43 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CLIENT_IDENTIFICATION_H_
|
||||
#define WVCDM_CORE_CLIENT_IDENTIFICATION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
// ClientIdentification fills in the ClientIdentification portion
|
||||
// of the License or Provisioning request messages.
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CryptoSession;
|
||||
|
||||
class ClientIdentification {
|
||||
public:
|
||||
ClientIdentification() : is_license_request_(true) {}
|
||||
ClientIdentification() {}
|
||||
virtual ~ClientIdentification() {}
|
||||
|
||||
// Call this method when used with provisioning requests
|
||||
CdmResponseType Init(CryptoSession* crypto_session);
|
||||
// Call this method when used with provisioning requests. |client_token| may
|
||||
// be empty and the token will be retrieved from OEMCrypto. In case of the
|
||||
// second stage of provisioning 4, an OEM cert must be provided via
|
||||
// |client_token|. |crypto_session| must not be nullptr.
|
||||
CdmResponseType InitForProvisioningRequest(const std::string& client_token,
|
||||
CryptoSession* crypto_session);
|
||||
|
||||
// Use in conjunction with license requests
|
||||
// |client_token| must be provided
|
||||
// |device_id| optional
|
||||
// |crypto_session| input parameter, mandatory
|
||||
CdmResponseType Init(const std::string& client_token,
|
||||
const std::string& device_id,
|
||||
CryptoSession* crypto_session);
|
||||
CdmResponseType InitForLicenseRequest(const std::string& client_token,
|
||||
CryptoSession* crypto_session);
|
||||
|
||||
// Fill the ClientIdentification portion of the license or provisioning
|
||||
// request
|
||||
CdmResponseType InitForOtaKeyboxProvisioning(CryptoSession* crypto_session);
|
||||
|
||||
// Fill the ClientIdentification portion of the license, DRM cert
|
||||
// provisioning or OTA keybox provisioning request.
|
||||
// |app_parameters| parameters provided by client/app to be included in
|
||||
// provisioning/license request. optional, only used
|
||||
// if |is_license_request| is true
|
||||
@@ -51,14 +55,13 @@ class ClientIdentification {
|
||||
bool GetProvisioningTokenType(
|
||||
video_widevine::ClientIdentification::TokenType* token_type);
|
||||
|
||||
bool is_license_request_;
|
||||
bool is_license_request_ = false;
|
||||
bool is_okp_request_ = false;
|
||||
std::string client_token_;
|
||||
std::string device_id_;
|
||||
CryptoSession* crypto_session_;
|
||||
CryptoSession* crypto_session_ = nullptr;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(ClientIdentification);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_CLIENT_IDENTIFICATION_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CONTENT_KEY_SESSION_H_
|
||||
#define WVCDM_CORE_CONTENT_KEY_SESSION_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CRYPTO_KEY_H_
|
||||
#define WVCDM_CORE_CRYPTO_KEY_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CRYPTO_SESSION_H_
|
||||
#define WVCDM_CORE_CRYPTO_SESSION_H_
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "crypto_wrapped_key.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "key_session.h"
|
||||
#include "metrics_collections.h"
|
||||
@@ -22,10 +23,15 @@
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CryptoKey;
|
||||
class CryptoSessionFactory;
|
||||
class OtaKeyboxProvisioner;
|
||||
class UsageTableHeader;
|
||||
|
||||
namespace okp {
|
||||
class SystemFallbackPolicy;
|
||||
} // namespace okp
|
||||
|
||||
using CryptoKeyMap = std::map<std::string, CryptoKey*>;
|
||||
|
||||
// Crypto session utility functions used by KeySession implementations.
|
||||
@@ -39,8 +45,6 @@ OEMCrypto_Substring GetSubstring(const std::string& message = "",
|
||||
bool set_zero = false);
|
||||
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode);
|
||||
|
||||
class CryptoSessionFactory;
|
||||
|
||||
class CryptoSession {
|
||||
public:
|
||||
using HdcpCapability = OEMCrypto_HDCP_Capability;
|
||||
@@ -54,6 +58,9 @@ class CryptoSession {
|
||||
bool rsa_2048_bit;
|
||||
bool rsa_3072_bit;
|
||||
bool rsa_cast;
|
||||
bool ecc_secp256r1;
|
||||
bool ecc_secp384r1;
|
||||
bool ecc_secp521r1;
|
||||
};
|
||||
|
||||
// Creates an instance of CryptoSession with the given |crypto_metrics|.
|
||||
@@ -75,18 +82,37 @@ class CryptoSession {
|
||||
|
||||
static void DisableDelayedTermination();
|
||||
|
||||
virtual CdmResponseType GetProvisioningToken(std::string* client_token);
|
||||
virtual CdmResponseType GetProvisioningToken(
|
||||
RequestedSecurityLevel requested_security_level, std::string* token,
|
||||
std::string* additional_token);
|
||||
// Must be called after session is open.
|
||||
virtual CdmResponseType GetProvisioningToken(std::string* token,
|
||||
std::string* additional_token);
|
||||
|
||||
virtual CdmClientTokenType GetPreProvisionTokenType() {
|
||||
return pre_provision_token_type_;
|
||||
}
|
||||
|
||||
// Retrieves the key data portion of the OEMCrypto keybox.
|
||||
// Only valid for keybox-based based devices.
|
||||
// May return NEED_PROVISIONING if the device is keybox-based, but
|
||||
// OTA keybox provisioning is required.
|
||||
virtual CdmResponseType GetTokenFromKeybox(
|
||||
RequestedSecurityLevel requested_security_level, std::string* key_data);
|
||||
// Retrieves the public OEM certificate chain from OEMCrypto.
|
||||
// Only valid for OEM certificate-based based devices.
|
||||
virtual CdmResponseType GetTokenFromOemCert(
|
||||
RequestedSecurityLevel requested_security_level, std::string* oem_cert);
|
||||
|
||||
// The overloaded methods with |requested_level| may be called
|
||||
// without a preceding call to Open. The other method must call Open first.
|
||||
virtual CdmSecurityLevel GetSecurityLevel();
|
||||
virtual CdmSecurityLevel GetSecurityLevel(SecurityLevel requested_level);
|
||||
virtual CdmSecurityLevel GetSecurityLevel(
|
||||
RequestedSecurityLevel requested_level);
|
||||
virtual bool GetApiVersion(uint32_t* version);
|
||||
virtual bool GetApiVersion(SecurityLevel requested_level, uint32_t* version);
|
||||
virtual bool GetApiMinorVersion(SecurityLevel requested_level,
|
||||
virtual bool GetApiVersion(RequestedSecurityLevel requested_level,
|
||||
uint32_t* version);
|
||||
virtual bool GetApiMinorVersion(RequestedSecurityLevel requested_level,
|
||||
uint32_t* minor_version);
|
||||
|
||||
// This method will return, for devices with a
|
||||
@@ -104,12 +130,17 @@ class CryptoSession {
|
||||
// - that does not implement |OEMCrypto_GetDeviceID|: the 32 byte hash
|
||||
// of the OEM public certificate.
|
||||
virtual CdmResponseType GetExternalDeviceUniqueId(std::string* device_id);
|
||||
virtual bool GetSystemId(uint32_t* system_id);
|
||||
virtual CdmResponseType GetProvisioningId(std::string* provisioning_id);
|
||||
virtual uint8_t GetSecurityPatchLevel();
|
||||
|
||||
virtual bool GetCachedSystemId(uint32_t* system_id);
|
||||
// With provisioning 4.0, the system ID cannot reliably be found within
|
||||
// OEMCrypto. The system ID can be assigned to the CryptoSession instance
|
||||
// after the ID has been determined.
|
||||
virtual void SetSystemId(uint32_t system_id);
|
||||
|
||||
virtual CdmResponseType Open() { return Open(kLevelDefault); }
|
||||
virtual CdmResponseType Open(SecurityLevel requested_security_level);
|
||||
virtual CdmResponseType Open(RequestedSecurityLevel requested_security_level);
|
||||
virtual void Close();
|
||||
|
||||
virtual bool IsOpen() { return open_; }
|
||||
@@ -123,6 +154,7 @@ class CryptoSession {
|
||||
virtual CdmResponseType PrepareAndSignLicenseRequest(
|
||||
const std::string& message, std::string* core_message,
|
||||
std::string* signature);
|
||||
virtual CdmResponseType UseSecondaryKey(bool dual_key);
|
||||
// V15 licenses.
|
||||
virtual CdmResponseType LoadKeys(const std::string& message,
|
||||
const std::string& signature,
|
||||
@@ -167,7 +199,17 @@ class CryptoSession {
|
||||
const std::string& signature,
|
||||
std::string* wrapped_private_key);
|
||||
virtual CdmResponseType LoadCertificatePrivateKey(
|
||||
const std::string& wrapped_key);
|
||||
const CryptoWrappedKey& private_key);
|
||||
virtual CdmResponseType GetBootCertificateChain(
|
||||
RequestedSecurityLevel requested_security_level, std::string* bcc,
|
||||
std::string* additional_signature);
|
||||
virtual CdmResponseType GetBootCertificateChain(
|
||||
std::string* bcc, std::string* additional_signature);
|
||||
virtual CdmResponseType GenerateCertificateKeyPair(
|
||||
std::string* public_key, std::string* public_key_signature,
|
||||
std::string* wrapped_private_key, CryptoWrappedKey::Type* key_type);
|
||||
virtual CdmResponseType LoadOemCertificatePrivateKey(
|
||||
const CryptoWrappedKey& private_key);
|
||||
|
||||
// Media data path
|
||||
virtual CdmResponseType Decrypt(const CdmDecryptionParametersV16& params);
|
||||
@@ -178,32 +220,40 @@ class CryptoSession {
|
||||
// preceding call to Open. The other methods must call Open first.
|
||||
virtual CdmResponseType GetHdcpCapabilities(HdcpCapability* current,
|
||||
HdcpCapability* max);
|
||||
virtual CdmResponseType GetHdcpCapabilities(SecurityLevel security_level,
|
||||
HdcpCapability* current,
|
||||
HdcpCapability* max);
|
||||
virtual CdmResponseType GetHdcpCapabilities(
|
||||
RequestedSecurityLevel security_level, HdcpCapability* current,
|
||||
HdcpCapability* max);
|
||||
virtual bool GetResourceRatingTier(uint32_t* tier);
|
||||
virtual bool GetResourceRatingTier(SecurityLevel security_level,
|
||||
virtual bool GetResourceRatingTier(RequestedSecurityLevel security_level,
|
||||
uint32_t* tier);
|
||||
|
||||
virtual bool GetSupportedCertificateTypes(SupportedCertificateTypes* support);
|
||||
virtual CdmResponseType GetRandom(size_t data_length, uint8_t* random_data);
|
||||
virtual CdmResponseType GetNumberOfOpenSessions(SecurityLevel security_level,
|
||||
size_t* count);
|
||||
virtual CdmResponseType GetMaxNumberOfSessions(SecurityLevel security_level,
|
||||
size_t* max);
|
||||
virtual CdmResponseType GetNumberOfOpenSessions(
|
||||
RequestedSecurityLevel security_level, size_t* count);
|
||||
virtual CdmResponseType GetMaxNumberOfSessions(
|
||||
RequestedSecurityLevel security_level, size_t* max);
|
||||
|
||||
virtual CdmResponseType GetSrmVersion(uint16_t* srm_version);
|
||||
virtual bool IsSrmUpdateSupported();
|
||||
virtual CdmResponseType LoadSrm(const std::string& srm);
|
||||
|
||||
virtual bool GetBuildInformation(SecurityLevel security_level,
|
||||
virtual bool GetBuildInformation(RequestedSecurityLevel security_level,
|
||||
std::string* info);
|
||||
virtual bool GetBuildInformation(std::string* info);
|
||||
|
||||
virtual bool GetMaximumUsageTableEntries(SecurityLevel security_level,
|
||||
size_t* number_of_entries);
|
||||
virtual bool GetWatermarkingSupport(CdmWatermarkingSupport* support);
|
||||
virtual bool GetWatermarkingSupport(
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmWatermarkingSupport* support);
|
||||
|
||||
virtual bool GetDecryptHashSupport(SecurityLevel security_level,
|
||||
virtual bool GetProductionReadiness(CdmProductionReadiness* readiness);
|
||||
virtual bool GetProductionReadiness(
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmProductionReadiness* readiness);
|
||||
|
||||
virtual bool GetMaximumUsageTableEntries(
|
||||
RequestedSecurityLevel security_level, size_t* number_of_entries);
|
||||
|
||||
virtual bool GetDecryptHashSupport(RequestedSecurityLevel security_level,
|
||||
uint32_t* hash_support);
|
||||
|
||||
virtual CdmResponseType SetDecryptHash(uint32_t frame_number,
|
||||
@@ -234,14 +284,13 @@ class CryptoSession {
|
||||
// Used to manipulate the CDM managed usage table header & entries,
|
||||
// delegating calls to OEMCrypto.
|
||||
|
||||
// Usage support.
|
||||
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
||||
|
||||
// The overloaded method with |security_level| may be called without a
|
||||
// preceding call to Open. The other method must call Open first.
|
||||
virtual bool UsageInformationSupport(bool* has_support);
|
||||
virtual bool UsageInformationSupport(SecurityLevel security_level,
|
||||
bool* has_support);
|
||||
// Determines whether the OEMCrypto library supports usage info.
|
||||
// As of V16, the only valid type of support is usage table header +
|
||||
// usage entries.
|
||||
// The first method will use a cached value if present.
|
||||
virtual bool HasUsageInfoSupport(bool* has_support);
|
||||
virtual bool HasUsageInfoSupport(RequestedSecurityLevel security_level,
|
||||
bool* has_support);
|
||||
|
||||
// Usage report.
|
||||
virtual CdmResponseType DeactivateUsageInformation(
|
||||
@@ -258,13 +307,13 @@ class CryptoSession {
|
||||
// The following crypto methods do not require an open session to
|
||||
// complete the operations.
|
||||
virtual CdmResponseType CreateUsageTableHeader(
|
||||
SecurityLevel requested_security_level,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmUsageTableHeader* usage_table_header);
|
||||
virtual CdmResponseType LoadUsageTableHeader(
|
||||
SecurityLevel requested_security_level,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
const CdmUsageTableHeader& usage_table_header);
|
||||
virtual CdmResponseType ShrinkUsageTableHeader(
|
||||
SecurityLevel requested_security_level, uint32_t new_entry_count,
|
||||
RequestedSecurityLevel requested_security_level, uint32_t new_entry_count,
|
||||
CdmUsageTableHeader* usage_table_header);
|
||||
|
||||
// Usage entry.
|
||||
@@ -283,7 +332,36 @@ class CryptoSession {
|
||||
virtual metrics::CryptoMetrics* GetCryptoMetrics() { return metrics_; }
|
||||
|
||||
virtual CdmResponseType GetProvisioningMethod(
|
||||
SecurityLevel requested_security_level, CdmClientTokenType* token_type);
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
CdmClientTokenType* token_type);
|
||||
|
||||
// OTA Provisioning
|
||||
|
||||
static bool needs_keybox_provisioning() { return needs_keybox_provisioning_; }
|
||||
|
||||
// This tells the OEMCrypto adapter to ignore the next |count| keyboxes and
|
||||
// report that it needs provisioning instead.
|
||||
static CdmResponseType SetDebugIgnoreKeyboxCount(uint32_t count);
|
||||
|
||||
// This tells the OEMCrypto adapter to allow the device to continue with a
|
||||
// test keybox. Otherwise, the keybox is reported as invalid.
|
||||
static CdmResponseType SetAllowTestKeybox(bool allow);
|
||||
|
||||
// Returns a system-wide singleton instance of SystemFallbackPolicy
|
||||
// to be used for communicating OTA keybox provisioning state between
|
||||
// apps. Returns a null pointer if OTA provisioning is not supported,
|
||||
// or not required.
|
||||
static okp::SystemFallbackPolicy* GetOkpFallbackPolicy();
|
||||
|
||||
// Generates an OTA provisioning request.
|
||||
// This should only be called by an instance of OtaKeyboxProvisioner.
|
||||
virtual CdmResponseType PrepareOtaProvisioningRequest(bool use_test_key,
|
||||
std::string* request);
|
||||
|
||||
// Loads an OTA provisioning response.
|
||||
// This should only be called by an instance of OtaKeyboxProvisioner.
|
||||
virtual CdmResponseType LoadOtaProvisioning(bool use_test_key,
|
||||
const std::string& response);
|
||||
|
||||
protected:
|
||||
// Creates an instance of CryptoSession with the given |crypto_metrics|.
|
||||
@@ -291,7 +369,11 @@ class CryptoSession {
|
||||
// exist as long as the new CryptoSession exists.
|
||||
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
|
||||
|
||||
int session_count() { return session_count_; }
|
||||
int session_count() const { return session_count_; }
|
||||
// Cache api version and fallback policy. Call this once at initialization.
|
||||
void CacheVersion();
|
||||
// Re-initialize for running tests with a test keybox.
|
||||
void ReinitializeForTest();
|
||||
|
||||
private:
|
||||
friend class CryptoSessionForTest;
|
||||
@@ -299,23 +381,26 @@ class CryptoSession {
|
||||
#if defined(UNIT_TEST)
|
||||
friend class CertificateProvisioningTest;
|
||||
friend class WvCdmTestBase;
|
||||
friend class CdmOtaKeyboxTest;
|
||||
#endif
|
||||
|
||||
// The global factory method can be set to generate special crypto sessions
|
||||
// just for testing. These sessions will avoid nonce floods and will ask
|
||||
// OEMCrypto to use a test keybox.
|
||||
// Ownership of the object is transfered to CryptoSession.
|
||||
// Ownership of the object is transferred to CryptoSession.
|
||||
static void SetCryptoSessionFactory(CryptoSessionFactory* factory) {
|
||||
std::unique_lock<std::mutex> auto_lock(factory_mutex_);
|
||||
factory_.reset(factory);
|
||||
}
|
||||
|
||||
void Init();
|
||||
CdmResponseType GetTokenFromKeybox(std::string* token);
|
||||
CdmResponseType GetTokenFromOemCert(std::string* token);
|
||||
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
||||
uint32_t* system_id);
|
||||
CdmResponseType GetSystemIdInternal(uint32_t* system_id);
|
||||
|
||||
// Will set up the UsageTableHeader for this session. This may require
|
||||
// creating a new UsageTableHeader if the global instance has not
|
||||
// been initialized.
|
||||
// Note: This function will lock the global static field lock in write mode.
|
||||
bool SetUpUsageTableHeader(RequestedSecurityLevel requested_security_level);
|
||||
|
||||
CdmResponseType GenerateRsaSignature(const std::string& message,
|
||||
std::string* signature);
|
||||
size_t GetMaxSubsampleRegionSize();
|
||||
@@ -325,13 +410,11 @@ class CryptoSession {
|
||||
CdmResponseType SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode);
|
||||
|
||||
static const OEMCrypto_Algorithm kInvalidAlgorithm =
|
||||
static_cast<OEMCrypto_Algorithm>(-1);
|
||||
|
||||
OEMCrypto_Algorithm GenericSigningAlgorithm(CdmSigningAlgorithm algorithm);
|
||||
OEMCrypto_Algorithm GenericEncryptionAlgorithm(
|
||||
CdmEncryptionAlgorithm algorithm);
|
||||
size_t GenericEncryptionBlockSize(CdmEncryptionAlgorithm algorithm);
|
||||
// Retrieves the OEMCrypto usage info support for the specified
|
||||
// |requested_security_level|.
|
||||
// Caller should acquire the OEMCrypto read lock before calling.
|
||||
bool HasUsageInfoSupportInternal(
|
||||
RequestedSecurityLevel requested_security_level, bool* has_support);
|
||||
|
||||
// These methods fall back into each other in the order given, depending on
|
||||
// how much data they were given and how much data OEMCrypto can accept in one
|
||||
@@ -355,9 +438,15 @@ class CryptoSession {
|
||||
// These methods should be used to take the various CryptoSession mutexes in
|
||||
// preference to taking the mutexes directly.
|
||||
//
|
||||
// A lock should be taken on the Static Field Mutex before accessing any of
|
||||
// CryptoSession's non-atomic static fields. It can be taken as a reader or as
|
||||
// a writer, depending on how you will be accessing the static fields.
|
||||
// A lock should be taken on the Static Field Mutex before accessing
|
||||
// any of CryptoSession's non-atomic static fields with the exception
|
||||
// of the Usage Table Mutex. The Static Field Mutex can be taken as
|
||||
// a reader or as a writer, depending on how you will be accessing
|
||||
// the static fields. The Usage Table Mutex should be taken when
|
||||
// reading and writing to the static usage table fields (creating,
|
||||
// destroying or taking a pointer of the handles). The purpose of
|
||||
// having a separate mutex for usage table is due to the recursive
|
||||
// nature of initializing the global usage table.
|
||||
//
|
||||
// Before calling into OEMCrypto, code must take locks on the OEMCrypto Mutex
|
||||
// and/or the OEMCrypto Session Mutex. Which of them should be taken and how
|
||||
@@ -408,23 +497,32 @@ class CryptoSession {
|
||||
|
||||
static bool IsInitialized();
|
||||
|
||||
// Constants
|
||||
static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128
|
||||
static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature
|
||||
|
||||
// The locking methods above should be used in preference to taking these
|
||||
// mutexes directly. If code takes these manually and needs to take more
|
||||
// than one, it must *always* take them in the order they are defined here.
|
||||
static shared_mutex static_field_mutex_;
|
||||
static shared_mutex oem_crypto_mutex_;
|
||||
static wvutil::shared_mutex static_field_mutex_;
|
||||
static wvutil::shared_mutex oem_crypto_mutex_;
|
||||
std::mutex oem_crypto_session_mutex_;
|
||||
// Usage table mutex used only when performing write operations on
|
||||
// the static usage table pointers.
|
||||
static std::recursive_mutex usage_table_mutex_;
|
||||
|
||||
static bool initialized_;
|
||||
static int session_count_;
|
||||
static int termination_counter_;
|
||||
static bool needs_keybox_provisioning_;
|
||||
|
||||
enum CachedBooleanProperty {
|
||||
// Property has not yet been checked/cached.
|
||||
kBooleanUnset,
|
||||
// Property has been cached as false.
|
||||
kBooleanFalse,
|
||||
// Property has been cached as true.
|
||||
kBooleanTrue
|
||||
};
|
||||
|
||||
metrics::CryptoMetrics* metrics_;
|
||||
metrics::TimerMetric life_span_;
|
||||
metrics::Timer life_span_;
|
||||
uint32_t system_id_;
|
||||
|
||||
bool open_;
|
||||
@@ -436,12 +534,15 @@ class CryptoSession {
|
||||
|
||||
OEMCryptoBufferType destination_buffer_type_;
|
||||
bool is_destination_buffer_type_valid_;
|
||||
SecurityLevel requested_security_level_;
|
||||
RequestedSecurityLevel requested_security_level_;
|
||||
|
||||
CdmUsageSupportType usage_support_type_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
static UsageTableHeader* usage_table_header_l1_;
|
||||
static UsageTableHeader* usage_table_header_l3_;
|
||||
// Open session-cached result of OEMCrypto_SupportsUsageTable().
|
||||
CachedBooleanProperty has_usage_info_support_ = kBooleanUnset;
|
||||
UsageTableHeader* usage_table_header_ = nullptr;
|
||||
// These fields are protected by |usage_table_mutex_| and not
|
||||
// |static_field_mutex_|.
|
||||
static std::unique_ptr<UsageTableHeader> usage_table_header_l1_;
|
||||
static std::unique_ptr<UsageTableHeader> usage_table_header_l3_;
|
||||
|
||||
std::string request_id_;
|
||||
static std::atomic<uint64_t> request_id_index_source_;
|
||||
@@ -458,10 +559,15 @@ class CryptoSession {
|
||||
|
||||
// In order to avoid creating a deadlock if instantiation needs to take any
|
||||
// of the CryptoSession static mutexes, |factory_| is protected by its own
|
||||
// mutex that is only used in the two funtions that interact with it.
|
||||
// mutex that is only used in the two functions that interact with it.
|
||||
static std::mutex factory_mutex_;
|
||||
static std::unique_ptr<CryptoSessionFactory> factory_;
|
||||
|
||||
// A singleton instance of SystemFallbackPolicy. Only one will
|
||||
// be created for the system if OTA keybox provisioning is both
|
||||
// required and supported by L1.
|
||||
static std::unique_ptr<okp::SystemFallbackPolicy> okp_fallback_policy_l1_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);
|
||||
}; // class CryptoSession
|
||||
|
||||
|
||||
52
core/include/crypto_wrapped_key.h
Normal file
52
core/include/crypto_wrapped_key.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2020 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_CRYPTO_WRAPPED_KEY_H_
|
||||
#define WVCDM_CORE_CRYPTO_WRAPPED_KEY_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
// Represents OEMCrypto's wrapped private DRM key. As of v16, it is
|
||||
// possible for OEMCrypto to support ECC-based DRM certificates. The
|
||||
// format of the wrapped key is vendor specific; however, the API
|
||||
// requires that the CDM track whether the wrapped key is RSA or ECC.
|
||||
class CryptoWrappedKey {
|
||||
public:
|
||||
enum Type : int32_t { kUninitialized = 0, kRsa = 1, kEcc = 2 };
|
||||
CryptoWrappedKey() {}
|
||||
CryptoWrappedKey(Type type, const std::string& key)
|
||||
: type_(type), key_(key) {}
|
||||
|
||||
Type type() const { return type_; }
|
||||
void set_type(Type type) { type_ = type; }
|
||||
|
||||
const std::string& key() const { return key_; }
|
||||
// Mutable reference getter for passing to OMECrypto.
|
||||
std::string& key() { return key_; }
|
||||
void set_key(const std::string& key) { key_ = key; }
|
||||
|
||||
void Clear() {
|
||||
type_ = kUninitialized;
|
||||
key_.clear();
|
||||
}
|
||||
// A valid key must have a known key type and have key data.
|
||||
bool IsValid() const { return type_ != kUninitialized && !key_.empty(); }
|
||||
// Equality operator is for testing only. Real keys may have
|
||||
// different meta data but the same logical key.
|
||||
bool operator==(const CryptoWrappedKey& other) const {
|
||||
return type_ == other.type_ && key_ == other.key_;
|
||||
}
|
||||
|
||||
private:
|
||||
// DRM key type of the wrapped key. For wrapped keys which the type
|
||||
// of key is unknown, assume it to be RSA.
|
||||
Type type_ = kUninitialized;
|
||||
// Vendor-specific wrapped DRM key.
|
||||
std::string key_;
|
||||
}; // class CryptoWrappedKey
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_CRYPTO_WRAPPED_KEY_H_
|
||||
@@ -1,16 +1,19 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
#ifndef WVCDM_CORE_DEVICE_FILES_H_
|
||||
#define WVCDM_CORE_DEVICE_FILES_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "crypto_wrapped_key.h"
|
||||
#include "device_files.pb.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "okp_info.h"
|
||||
#include "platform.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
@@ -18,17 +21,31 @@
|
||||
# include <gtest/gtest_prod.h>
|
||||
#endif
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace wvutil {
|
||||
class FileSystem;
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class DeviceFiles {
|
||||
public:
|
||||
typedef enum {
|
||||
kLicenseStateActive,
|
||||
kLicenseStateReleasing,
|
||||
kLicenseStateUnknown,
|
||||
} LicenseState;
|
||||
kCertificateValid,
|
||||
kCertificateExpired,
|
||||
kCertificateNotFound,
|
||||
kCertificateInvalid,
|
||||
kCannotHandle,
|
||||
} CertificateState;
|
||||
|
||||
// |kCertificateDefault| includes an expiration time set by the provisioning
|
||||
// service. This will replace any legacy certificates, if a forced
|
||||
// reprovisioning happens at the client or by the license service.
|
||||
// ATSC certificates are unaffected and have an unlimited lifetime.
|
||||
typedef enum {
|
||||
kCertificateDefault,
|
||||
kCertificateLegacy,
|
||||
kCertificateAtsc,
|
||||
} CertificateType;
|
||||
|
||||
// All error response codes start with 5000 to avoid overlap with other error
|
||||
// spaces.
|
||||
@@ -53,11 +70,17 @@ class DeviceFiles {
|
||||
kLicenseNotPresent = kResponseTypeBase + 16,
|
||||
};
|
||||
|
||||
// Converts the different enum types to a human readable C-string for
|
||||
// logging.
|
||||
static const char* CertificateStateToString(CertificateState state);
|
||||
static const char* CertificateTypeToString(CertificateType type);
|
||||
static const char* ResponseTypeToString(ResponseType type);
|
||||
|
||||
// CdmLicenseData represents all of the data that is stored in CDM
|
||||
// license file. License data is uniquely keyed using |key_set_id|.
|
||||
struct CdmLicenseData {
|
||||
std::string key_set_id;
|
||||
LicenseState state;
|
||||
CdmOfflineLicenseState state;
|
||||
CdmInitData pssh_data;
|
||||
// License request / response.
|
||||
CdmKeyMessage license_request;
|
||||
@@ -76,6 +99,8 @@ class DeviceFiles {
|
||||
// Usage entry and index.
|
||||
CdmUsageEntry usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
};
|
||||
|
||||
struct CdmUsageData {
|
||||
@@ -85,9 +110,11 @@ class DeviceFiles {
|
||||
std::string key_set_id;
|
||||
CdmUsageEntry usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
};
|
||||
|
||||
DeviceFiles(FileSystem*);
|
||||
DeviceFiles(wvutil::FileSystem*);
|
||||
virtual ~DeviceFiles();
|
||||
|
||||
virtual bool Init(CdmSecurityLevel security_level);
|
||||
@@ -98,15 +125,30 @@ class DeviceFiles {
|
||||
// ATSC certificates are installed by the ATSC service. They can be read
|
||||
// and used but not written or removed.
|
||||
virtual bool StoreCertificate(const std::string& certificate,
|
||||
const std::string& wrapped_private_key);
|
||||
virtual bool RetrieveCertificate(bool atsc_mode_enabled,
|
||||
std::string* certificate,
|
||||
std::string* wrapped_private_key,
|
||||
std::string* serial_number,
|
||||
uint32_t* system_id);
|
||||
const CryptoWrappedKey& private_key);
|
||||
virtual CertificateState RetrieveCertificate(bool atsc_mode_enabled,
|
||||
std::string* certificate,
|
||||
CryptoWrappedKey* private_key,
|
||||
std::string* serial_number,
|
||||
uint32_t* system_id);
|
||||
// Returns true if a DRM certificate is available.
|
||||
virtual bool HasCertificate(bool atsc_mode_enabled);
|
||||
// Retrieves the legacy DRM certificate without performing expiry
|
||||
// related validation. Use this only when restoring/releasing
|
||||
// licenses/usage entries
|
||||
virtual bool RetrieveLegacyCertificate(std::string* certificate,
|
||||
CryptoWrappedKey* private_key,
|
||||
std::string* serial_number,
|
||||
uint32_t* system_id);
|
||||
virtual bool RemoveCertificate();
|
||||
|
||||
virtual bool StoreOemCertificate(const std::string& certificate,
|
||||
const CryptoWrappedKey& private_key);
|
||||
virtual DeviceFiles::CertificateState RetrieveOemCertificate(
|
||||
std::string* certificate, CryptoWrappedKey* wrapped_private_key);
|
||||
virtual bool HasOemCertificate();
|
||||
virtual bool RemoveOemCertificate();
|
||||
|
||||
virtual bool StoreLicense(const CdmLicenseData& license_data,
|
||||
ResponseType* result);
|
||||
|
||||
@@ -134,13 +176,12 @@ class DeviceFiles {
|
||||
// required creation of reverse lookup tables (CdmUsageEntryInfo).
|
||||
// |app_id| however was hashed and unextractable, and necessitated the
|
||||
// switch to |usage_info_file_name|
|
||||
virtual bool StoreUsageInfo(const std::string& provider_session_token,
|
||||
const CdmKeyMessage& key_request,
|
||||
const CdmKeyResponse& key_response,
|
||||
const std::string& usage_info_file_name,
|
||||
const std::string& key_set_id,
|
||||
const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number);
|
||||
virtual bool StoreUsageInfo(
|
||||
const std::string& provider_session_token,
|
||||
const CdmKeyMessage& key_request, const CdmKeyResponse& key_response,
|
||||
const std::string& usage_info_file_name, const std::string& key_set_id,
|
||||
const CdmUsageEntry& usage_entry, uint32_t usage_entry_number,
|
||||
const std::string& drm_certificate, const CryptoWrappedKey& wrapped_key);
|
||||
|
||||
// Retrieve usage identifying information stored on the file system.
|
||||
// The caller needs to specify at least one of |ksids| or
|
||||
@@ -186,12 +227,6 @@ class DeviceFiles {
|
||||
|
||||
virtual bool DeleteAllUsageInfo();
|
||||
|
||||
// Retrieve one usage info from the file. Subsequent calls will retrieve
|
||||
// subsequent entries in the table for this app_id.
|
||||
virtual bool RetrieveUsageInfo(
|
||||
const std::string& usage_info_file_name,
|
||||
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info);
|
||||
|
||||
// Retrieve the usage info entry specified by |provider_session_token|.
|
||||
// Returns false if the entry could not be found.
|
||||
virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name,
|
||||
@@ -199,14 +234,17 @@ class DeviceFiles {
|
||||
CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_response,
|
||||
CdmUsageEntry* usage_entry,
|
||||
uint32_t* usage_entry_number);
|
||||
uint32_t* usage_entry_number,
|
||||
std::string* drm_certificate,
|
||||
CryptoWrappedKey* wrapped_key);
|
||||
// Retrieve the usage info entry specified by |key_set_id|.
|
||||
// Returns false if the entry could not be found.
|
||||
virtual bool RetrieveUsageInfoByKeySetId(
|
||||
const std::string& usage_info_file_name, const std::string& key_set_id,
|
||||
std::string* provider_session_token, CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_response, CdmUsageEntry* usage_entry,
|
||||
uint32_t* usage_entry_number);
|
||||
uint32_t* usage_entry_number, std::string* drm_certificate,
|
||||
CryptoWrappedKey* wrapped_key);
|
||||
|
||||
// These APIs support upgrading from usage tables to usage tabler header +
|
||||
// entries introduced in OEMCrypto V13.
|
||||
@@ -245,9 +283,23 @@ class DeviceFiles {
|
||||
|
||||
virtual bool DeleteUsageTableInfo();
|
||||
|
||||
// OTA Keybox Provisioning (OKP) information.
|
||||
virtual bool StoreOkpInfo(const okp::SystemFallbackInfo& info);
|
||||
virtual bool RetrieveOkpInfo(okp::SystemFallbackInfo* info);
|
||||
virtual bool DeleteOkpInfo();
|
||||
|
||||
private:
|
||||
// This method will retrieve the certificate and perform expiry validation
|
||||
// appropriate for a given certificate type
|
||||
CertificateState RetrieveCertificate(CertificateType certificate_type,
|
||||
std::string* certificate,
|
||||
CryptoWrappedKey* private_key,
|
||||
std::string* serial_number,
|
||||
uint32_t* system_id);
|
||||
bool HasCertificate(CertificateType certificate_type);
|
||||
|
||||
// Helpers that wrap the File interface and automatically handle hashing, as
|
||||
// well as adding the device files base path to to the file name.
|
||||
// well as adding the device files base path to the file name.
|
||||
ResponseType StoreFileWithHash(const std::string& name,
|
||||
const std::string& serialized_file);
|
||||
ResponseType StoreFileRaw(const std::string& name,
|
||||
@@ -259,27 +311,45 @@ class DeviceFiles {
|
||||
bool RemoveFile(const std::string& name);
|
||||
ssize_t GetFileSize(const std::string& name);
|
||||
|
||||
static std::string GetCertificateFileName(bool atsc_mode_enabled);
|
||||
static bool GetCertificateFileName(CertificateType certificate_type,
|
||||
std::string* certificate_file_name);
|
||||
static bool GetOemCertificateFileName(std::string* certificate_file_name);
|
||||
|
||||
static std::string GetHlsAttributesFileNameExtension();
|
||||
static std::string GetLicenseFileNameExtension();
|
||||
static std::string GetUsageTableFileName();
|
||||
static std::string GetOkpInfoFileName();
|
||||
static std::string GetFileNameSafeHash(const std::string& input);
|
||||
|
||||
#if defined(UNIT_TEST)
|
||||
FRIEND_TEST(DeviceFilesSecurityLevelTest, SecurityLevel);
|
||||
FRIEND_TEST(DeviceCertificateTest, StoreCertificate);
|
||||
FRIEND_TEST(DeviceFilesSecurityLevelTest, RequestedSecurityLevel);
|
||||
FRIEND_TEST(DeviceCertificateTest, ReadCertificate);
|
||||
FRIEND_TEST(DeviceCertificateTest, HasCertificate);
|
||||
FRIEND_TEST(DeviceFilesStoreTest, StoreLicense);
|
||||
FRIEND_TEST(DeviceFilesHlsAttributesTest, Delete);
|
||||
FRIEND_TEST(DeviceFilesHlsAttributesTest, Read);
|
||||
FRIEND_TEST(DeviceFilesHlsAttributesTest, Store);
|
||||
FRIEND_TEST(DeviceFilesTest, DeleteLicense);
|
||||
FRIEND_TEST(DeviceFilesTest, ReserveLicenseIdsDoesNotUseFileSystem);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveLicenses);
|
||||
FRIEND_TEST(DeviceFilesTest, AppParametersBackwardCompatibility);
|
||||
FRIEND_TEST(DeviceFilesTest, DeleteLicense);
|
||||
FRIEND_TEST(DeviceFilesTest, HasCertificateAtsc);
|
||||
FRIEND_TEST(DeviceFilesTest, HasCertificateDefault);
|
||||
FRIEND_TEST(DeviceFilesTest, HasCertificateLegacy);
|
||||
FRIEND_TEST(DeviceFilesTest, HasCertificateNone);
|
||||
FRIEND_TEST(DeviceFilesTest, ReserveLicenseIdsDoesNotUseFileSystem);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveAtscCertificate);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveAtscCertificateNotFound);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveCertificateWithoutKeyType);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveDefaultCertificate);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveDefaultCertificateNeverExpires);
|
||||
FRIEND_TEST(DeviceFilesTest,
|
||||
RetrieveLegacyCertificateWithClientExpirationTime);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveLegacyCertificateWithoutExpirationTime);
|
||||
FRIEND_TEST(DeviceFilesTest, RetrieveLicenses);
|
||||
FRIEND_TEST(DeviceFilesTest, StoreCertificateInvalidParams);
|
||||
FRIEND_TEST(DeviceFilesTest, StoreLicenses);
|
||||
FRIEND_TEST(DeviceFilesTest, UpdateLicenseState);
|
||||
FRIEND_TEST(DeviceFilesTest, OkpInfo_FileDoesNotExist);
|
||||
FRIEND_TEST(DeviceFilesTest, OkpInfo_DeleteFile);
|
||||
FRIEND_TEST(DeviceFilesTest, OkpInfo_StoreAndRetrieve);
|
||||
FRIEND_TEST(DeviceFilesUsageInfoTest, Delete);
|
||||
FRIEND_TEST(DeviceFilesUsageInfoTest, DeleteAll);
|
||||
FRIEND_TEST(DeviceFilesUsageInfoTest, Read);
|
||||
@@ -287,6 +357,9 @@ class DeviceFiles {
|
||||
FRIEND_TEST(DeviceFilesUsageTableTest, Read);
|
||||
FRIEND_TEST(DeviceFilesUsageTableTest, Store);
|
||||
FRIEND_TEST(DeviceFilesUsageTableTest, ReadWithoutLruData);
|
||||
FRIEND_TEST(RetrieveDefaultCertificateTest, ErrorScenarios);
|
||||
FRIEND_TEST(RetrieveLegacyCertificateTest, ErrorScenarios);
|
||||
FRIEND_TEST(StoreCertificateTest, DefaultAndLegacy);
|
||||
FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest);
|
||||
FRIEND_TEST(WvCdmRequestLicenseTest, ForceL3Test);
|
||||
FRIEND_TEST(WvCdmRequestLicenseTest, UsageInfoRetryTest);
|
||||
@@ -297,8 +370,9 @@ class DeviceFiles {
|
||||
#endif
|
||||
|
||||
static std::set<std::string> reserved_license_ids_;
|
||||
static std::mutex reserved_license_ids_mutex_;
|
||||
|
||||
FileSystem* file_system_;
|
||||
wvutil::FileSystem* file_system_;
|
||||
CdmSecurityLevel security_level_;
|
||||
bool initialized_;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_ENTITLEMENT_KEY_SESSION_H_
|
||||
#define WVCDM_CORE_ENTITLEMENT_KEY_SESSION_H_
|
||||
@@ -19,7 +19,7 @@ class EntitlementKeySession : public ContentKeySession {
|
||||
public:
|
||||
EntitlementKeySession(CryptoSessionId oec_session_id,
|
||||
metrics::CryptoMetrics* metrics);
|
||||
~EntitlementKeySession() override {}
|
||||
~EntitlementKeySession() override;
|
||||
|
||||
KeySessionType Type() override { return kEntitlement; }
|
||||
|
||||
@@ -35,6 +35,9 @@ class EntitlementKeySession : public ContentKeySession {
|
||||
const std::vector<CryptoKey>& keys) override;
|
||||
OEMCryptoResult SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode) override;
|
||||
OEMCryptoResult Decrypt(
|
||||
const OEMCrypto_SampleDescription* samples, size_t samples_length,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) override;
|
||||
|
||||
private:
|
||||
// The message is populated with the fields of the provided CryptoKey and the
|
||||
@@ -47,6 +50,7 @@ class EntitlementKeySession : public ContentKeySession {
|
||||
std::map<KeyId, CryptoKey> entitled_keys_;
|
||||
// Find the current entitled content key id for the given entitlement key id.
|
||||
std::map<KeyId, KeyId> current_loaded_content_keys_;
|
||||
EntitledKeySessionId key_session_id_;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef CORE_INCLUDE_INITIALIZATION_DATA_H_
|
||||
#define CORE_INCLUDE_INITIALIZATION_DATA_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_KEY_SESSION_H_
|
||||
#define WVCDM_CORE_KEY_SESSION_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_LICENSE_H_
|
||||
#define WVCDM_CORE_LICENSE_H_
|
||||
@@ -20,9 +20,11 @@ class LicenseRequest;
|
||||
class VersionInfo;
|
||||
} // namespace video_widevine
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace wvutil {
|
||||
class Clock;
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
class CryptoSession;
|
||||
class PolicyEngine;
|
||||
class CdmSession;
|
||||
@@ -38,9 +40,7 @@ class CdmLicense {
|
||||
CdmLicense(const CdmSessionId& session_id);
|
||||
virtual ~CdmLicense();
|
||||
|
||||
virtual bool Init(const std::string& client_token,
|
||||
CdmClientTokenType client_token_type,
|
||||
const std::string& device_id, bool use_privacy_mode,
|
||||
virtual bool Init(bool use_privacy_mode,
|
||||
const std::string& signed_service_certificate,
|
||||
CryptoSession* session, PolicyEngine* policy_engine);
|
||||
|
||||
@@ -50,9 +50,9 @@ class CdmLicense {
|
||||
const std::string& signed_service_certificate);
|
||||
|
||||
virtual CdmResponseType PrepareKeyRequest(
|
||||
const InitializationData& init_data, CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
||||
std::string* server_url);
|
||||
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,
|
||||
@@ -65,13 +65,13 @@ class CdmLicense {
|
||||
const InitializationData& init_data);
|
||||
|
||||
virtual CdmResponseType RestoreOfflineLicense(
|
||||
const CdmKeyMessage& license_request,
|
||||
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 CdmKeyMessage& license_request,
|
||||
const std::string& client_token, const CdmKeyMessage& license_request,
|
||||
const CdmKeyResponse& license_response);
|
||||
virtual bool HasInitData() { return static_cast<bool>(stored_init_data_); }
|
||||
virtual bool IsKeyLoaded(const KeyId& key_id);
|
||||
@@ -139,8 +139,6 @@ class CdmLicense {
|
||||
PolicyEngine* policy_engine_;
|
||||
std::string server_url_;
|
||||
std::string client_token_;
|
||||
CdmClientTokenType client_token_type_;
|
||||
std::string device_id_;
|
||||
const CdmSessionId session_id_;
|
||||
std::unique_ptr<InitializationData> stored_init_data_;
|
||||
bool initialized_;
|
||||
@@ -161,16 +159,16 @@ class CdmLicense {
|
||||
// Used for certificate based licensing
|
||||
CdmKeyMessage key_request_;
|
||||
|
||||
std::unique_ptr<Clock> clock_;
|
||||
std::unique_ptr<wvutil::Clock> clock_;
|
||||
|
||||
// For testing
|
||||
// CdmLicense takes ownership of the clock.
|
||||
CdmLicense(const CdmSessionId& session_id, Clock* 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.
|
||||
// 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
|
||||
// entitelement keys. It is also used in updating the key status info.
|
||||
// entitlement keys. It is also used in updating the key status info.
|
||||
std::vector<WidevinePsshData_EntitledKey> wrapped_keys_;
|
||||
|
||||
CdmLicenseKeyType license_key_type_;
|
||||
@@ -190,7 +188,6 @@ class CdmLicense {
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmLicense);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_LICENSE_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_LICENSE_KEY_STATUS_H_
|
||||
#define WVCDM_CORE_LICENSE_KEY_STATUS_H_
|
||||
@@ -59,7 +59,7 @@ class LicenseKeys {
|
||||
virtual bool MeetsSecurityLevelConstraints(const KeyId& key_id);
|
||||
|
||||
// Applies a resolution and/or hdcp change to each key, updating their
|
||||
// useability under their constraints.
|
||||
// usability under their constraints.
|
||||
virtual void ApplyConstraints(uint32_t new_resolution,
|
||||
CryptoSession::HdcpCapability new_hdcp_level);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
#ifndef WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
||||
#define WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
||||
@@ -9,53 +9,70 @@
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
// Initialize OEMCrypto, then check the keybox and see if it is valid. If not,
|
||||
// and OTA provisioning is supported, set needs_keybox_provisioning to true.
|
||||
// If the keybox is not valid and OTA provisioning is not supported, set
|
||||
// needs_keybox_provisioning to false and use L3 only.
|
||||
OEMCryptoResult OEMCrypto_InitializeAndCheckKeybox(
|
||||
bool* needs_keybox_provisioning);
|
||||
|
||||
// This tells the OEMCrypto adapter to ignore the next |count| keyboxes and
|
||||
// report that it needs provisioning instead.
|
||||
OEMCryptoResult OEMCrypto_SetDebugIgnoreKeyboxCount(uint32_t count);
|
||||
|
||||
// This tells the OEMCrypto adapter to allow the device to continue with a
|
||||
// test keybox. Otherwise, the keybox is reported as invalid.
|
||||
OEMCryptoResult OEMCrypto_SetAllowTestKeybox(bool allow);
|
||||
|
||||
// This attempts to open a session at the desired security level.
|
||||
// If one level is not available, the other will be used instead.
|
||||
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session,
|
||||
SecurityLevel level);
|
||||
RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
||||
size_t keyBoxLength,
|
||||
SecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(SecurityLevel level);
|
||||
RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength,
|
||||
SecurityLevel level);
|
||||
RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength,
|
||||
SecurityLevel level);
|
||||
uint32_t OEMCrypto_APIVersion(SecurityLevel level);
|
||||
uint32_t OEMCrypto_MinorAPIVersion(SecurityLevel level);
|
||||
const char* OEMCrypto_SecurityLevel(SecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetHDCPCapability(SecurityLevel level,
|
||||
RequestedSecurityLevel level);
|
||||
uint32_t OEMCrypto_APIVersion(RequestedSecurityLevel level);
|
||||
uint32_t OEMCrypto_MinorAPIVersion(RequestedSecurityLevel level);
|
||||
OEMCrypto_Security_Level OEMCrypto_SecurityLevel(RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetHDCPCapability(RequestedSecurityLevel level,
|
||||
OEMCrypto_HDCP_Capability* current,
|
||||
OEMCrypto_HDCP_Capability* maximum);
|
||||
bool OEMCrypto_SupportsUsageTable(SecurityLevel level);
|
||||
bool OEMCrypto_IsAntiRollbackHwPresent(SecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(SecurityLevel level,
|
||||
bool OEMCrypto_SupportsUsageTable(RequestedSecurityLevel level);
|
||||
bool OEMCrypto_IsAntiRollbackHwPresent(RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(RequestedSecurityLevel level,
|
||||
size_t* count);
|
||||
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
|
||||
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(RequestedSecurityLevel level,
|
||||
size_t* maximum);
|
||||
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level);
|
||||
uint8_t OEMCrypto_Security_Patch_Level(RequestedSecurityLevel level);
|
||||
OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(
|
||||
SecurityLevel level);
|
||||
uint32_t OEMCrypto_SupportedCertificates(SecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_CreateUsageTableHeader(SecurityLevel level,
|
||||
RequestedSecurityLevel level);
|
||||
uint32_t OEMCrypto_SupportedCertificates(RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_CreateUsageTableHeader(RequestedSecurityLevel level,
|
||||
uint8_t* header_buffer,
|
||||
size_t* header_buffer_length);
|
||||
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(SecurityLevel level,
|
||||
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(RequestedSecurityLevel level,
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(SecurityLevel level,
|
||||
OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(RequestedSecurityLevel level,
|
||||
uint32_t new_table_size,
|
||||
uint8_t* header_buffer,
|
||||
size_t* header_buffer_length);
|
||||
uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level);
|
||||
const char* OEMCrypto_BuildInformation(SecurityLevel level);
|
||||
uint32_t OEMCrypto_ResourceRatingTier(SecurityLevel level);
|
||||
uint32_t OEMCrypto_SupportsDecryptHash(SecurityLevel level);
|
||||
size_t OEMCrypto_MaximumUsageTableHeaderSize(SecurityLevel level);
|
||||
uint32_t OEMCrypto_GetAnalogOutputFlags(RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_BuildInformation(char* buffer, size_t* buffer_length,
|
||||
RequestedSecurityLevel level);
|
||||
uint32_t OEMCrypto_ResourceRatingTier(RequestedSecurityLevel level);
|
||||
uint32_t OEMCrypto_SupportsDecryptHash(RequestedSecurityLevel level);
|
||||
size_t OEMCrypto_MaximumUsageTableHeaderSize(RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert,
|
||||
size_t* public_cert_length,
|
||||
SecurityLevel level);
|
||||
RequestedSecurityLevel level);
|
||||
OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(
|
||||
RequestedSecurityLevel level);
|
||||
OEMCryptoResult OEMCrypto_ProductionReady(RequestedSecurityLevel level);
|
||||
} // namespace wvcdm
|
||||
|
||||
/* The following functions are deprecated in OEMCrypto v13. They are defined
|
||||
@@ -95,7 +112,7 @@ typedef struct {
|
||||
const uint8_t* key_control;
|
||||
} OEMCrypto_KeyObject_V14;
|
||||
|
||||
// Backwards compitiblity between v14 and v13.
|
||||
// Backwards compatibility between v14 and v13.
|
||||
OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
|
||||
123
core/include/okp_fallback_policy.h
Normal file
123
core/include/okp_fallback_policy.h
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright 2021 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_OKP_FALLBACK_POLICY_H_
|
||||
#define WVCDM_CORE_OKP_FALLBACK_POLICY_H_
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "clock.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "file_store.h"
|
||||
#include "okp_info.h"
|
||||
|
||||
namespace wvcdm {
|
||||
class DeviceFiles;
|
||||
// OTA Keybox Provisioning (OKP)
|
||||
namespace okp {
|
||||
static constexpr int64_t kSecondsPerHour = 60 * 60;
|
||||
static constexpr int64_t kSecondsPerDay = kSecondsPerHour * 24;
|
||||
// Initial backoff duration. Subsequent backoff durations for the
|
||||
// same engine will double its previous duration.
|
||||
static constexpr int64_t kAverageInitialBackoffDuration = kSecondsPerDay;
|
||||
static constexpr int64_t kFastBackoffDuration = 30; // 30 seconds.
|
||||
static constexpr int64_t kInitialBackoffDurationDelta = kSecondsPerHour * 12;
|
||||
// Minimum backoff duration which an device will be required to
|
||||
// backoff the first time.
|
||||
static constexpr int64_t kMinInitialBackoffDuration =
|
||||
kAverageInitialBackoffDuration - kInitialBackoffDurationDelta;
|
||||
static constexpr int64_t kMaxInitialBackoffDuration =
|
||||
kAverageInitialBackoffDuration + kInitialBackoffDurationDelta;
|
||||
|
||||
// SystemFallbackPolicy is a centralized OKP state manager which allows
|
||||
// multiple CDM engines to communicate between each other. In a production
|
||||
// build, there should only be at most one SystemFallbackPolicy instance.
|
||||
class SystemFallbackPolicy {
|
||||
public:
|
||||
// Creates a new instance of SystemFallbackPolicy. If there exists
|
||||
// OKP information for the device in storage, it will be loaded and
|
||||
// the system policy will resume from its previous state. If no
|
||||
// OKP information exists, then the policy begins new.
|
||||
// Caller should immediately mark the fallback policy as requiring
|
||||
// provisioning.
|
||||
static std::unique_ptr<SystemFallbackPolicy> Create();
|
||||
// Creates a new instance of SystemFallbackPolicy for testing.
|
||||
// The testing instance of SystemFallbackPolicy behaves similar to a
|
||||
// production instance, except that it will not use device storage.
|
||||
// Optionally, a fake clock may be used for timestamp operations
|
||||
// and/or fake data may be used to initialize the policy.
|
||||
// Params:
|
||||
// - |info| (optional)
|
||||
// Fake device OKP info to use as a resume point. If not
|
||||
// specified, then policy begins the same as if no OKP
|
||||
// device info exists.
|
||||
// - |clock| (optional)
|
||||
// Fake/mock clock to be used instead of the CDM's default
|
||||
// Clock.
|
||||
static std::unique_ptr<SystemFallbackPolicy> CreateForTesting(
|
||||
wvutil::Clock* clock = nullptr);
|
||||
static std::unique_ptr<SystemFallbackPolicy> CreateForTesting(
|
||||
const SystemFallbackInfo& info, wvutil::Clock* clock = nullptr);
|
||||
|
||||
// == System Info ==
|
||||
const SystemFallbackInfo& info() const { return info_; }
|
||||
SystemState state() const { return info_.state(); }
|
||||
void MarkNeedsProvisioning();
|
||||
void TriggerFallback();
|
||||
void MarkProvisioned();
|
||||
|
||||
bool IsProvisioned();
|
||||
bool IsInFallbackMode();
|
||||
|
||||
void SetDefaultBackoffDurationRules();
|
||||
void SetFastBackoffDurationRules();
|
||||
|
||||
~SystemFallbackPolicy();
|
||||
|
||||
private:
|
||||
SystemFallbackPolicy();
|
||||
|
||||
// Checks the device's file system for OKP info and loads it.
|
||||
// If the info does not exist, policy begins fresh.
|
||||
void TryRestore();
|
||||
|
||||
void StoreInfo();
|
||||
|
||||
int64_t GenerateInitialBackoffDuration();
|
||||
|
||||
int64_t GetSecondsSinceBackoffStart() const;
|
||||
void EndBackoffPeriod();
|
||||
|
||||
void SetClockForTesting(wvutil::Clock* clock) {
|
||||
clock_ref_ = (clock == nullptr) ? &clock_ : clock;
|
||||
}
|
||||
int64_t GetCurrentTime() const { return clock_ref_->GetCurrentTime(); }
|
||||
|
||||
bool IsTestMode() const;
|
||||
|
||||
SystemFallbackInfo info_;
|
||||
|
||||
// When |fast_fallback_| is true, falling back only lasts a few
|
||||
// seconds, and exponential backoff is disabled.
|
||||
bool fast_fallback_ = false;
|
||||
|
||||
// Handle for the DeviceFiles instance used to store the OKP
|
||||
// information.
|
||||
// Not set for test instances.
|
||||
std::unique_ptr<wvutil::FileSystem> fs_;
|
||||
std::unique_ptr<DeviceFiles> device_files_;
|
||||
|
||||
wvutil::Clock clock_; // System clock
|
||||
wvutil::Clock* clock_ref_ = nullptr; // Pointer to clock to be used.
|
||||
|
||||
// All public methods must lock to protect from simultaneous
|
||||
// engine access.
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(SystemFallbackPolicy);
|
||||
}; // class SystemFallbackPolicy
|
||||
} // namespace okp
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_CORE_OKP_FALLBACK_POLICY_H_
|
||||
79
core/include/okp_info.h
Normal file
79
core/include/okp_info.h
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2021 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_OKP_SYSTEM_INFO_H_
|
||||
#define WVCDM_CORE_OKP_SYSTEM_INFO_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace wvcdm {
|
||||
// OTA Keybox Provisioning (OKP)
|
||||
namespace okp {
|
||||
enum class SystemState {
|
||||
kUnknown = 0,
|
||||
kNeedsProvisioning = 1,
|
||||
kFallbackMode = 2, // Fallback indicates provisioning is needed.
|
||||
kProvisioned = 3
|
||||
// Note: "Not needed" is represented by an absence of info.
|
||||
};
|
||||
// Converts a SystemState value to a human readable string. Intended
|
||||
// to be used for debug logging.
|
||||
const char* SystemStateToString(SystemState state);
|
||||
|
||||
// Container for all the device information related to OKP.
|
||||
class SystemFallbackInfo {
|
||||
public:
|
||||
SystemState state() const { return state_; }
|
||||
void SetState(SystemState state) { state_ = state; }
|
||||
|
||||
bool HasFirstCheckedTime() const { return first_checked_time_ != 0; }
|
||||
int64_t first_checked_time() const { return first_checked_time_; }
|
||||
void SetFirstCheckedTime(int64_t time) {
|
||||
first_checked_time_ = (time > 0 ? time : 0);
|
||||
}
|
||||
|
||||
bool HasBackoffStartTime() const { return backoff_start_time_ > 0; }
|
||||
int64_t backoff_start_time() const { return backoff_start_time_; }
|
||||
void SetBackoffStartTime(int64_t time) {
|
||||
backoff_start_time_ = (time > 0 ? time : 0);
|
||||
}
|
||||
void ClearBackoffStartTime() { backoff_start_time_ = 0; }
|
||||
|
||||
bool HasBackoffDuration() const { return backoff_duration_ > 0; }
|
||||
int64_t backoff_duration() const { return backoff_duration_; }
|
||||
void SetBackoffDuration(int64_t duration) {
|
||||
backoff_duration_ = (duration > 0 ? duration : 0);
|
||||
}
|
||||
void DoubleBackoffDuration() { backoff_duration_ *= 2; }
|
||||
void ClearBackoffDuration() { backoff_duration_ = 0; }
|
||||
|
||||
bool HasProvisioningTime() const { return provisioning_time_ != 0; }
|
||||
int64_t provisioning_time() const { return provisioning_time_; }
|
||||
void SetProvisioningTime(int64_t time) {
|
||||
provisioning_time_ = (time > 0 ? time : 0);
|
||||
}
|
||||
void ClearProvisioningTime() { provisioning_time_ = 0; }
|
||||
|
||||
void Clear() {
|
||||
state_ = SystemState::kUnknown;
|
||||
first_checked_time_ = 0;
|
||||
backoff_start_time_ = 0;
|
||||
backoff_duration_ = 0;
|
||||
provisioning_time_ = 0;
|
||||
}
|
||||
|
||||
bool operator==(const SystemFallbackInfo& other) const;
|
||||
bool operator!=(const SystemFallbackInfo& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
SystemState state_ = SystemState::kUnknown;
|
||||
int64_t first_checked_time_ = 0;
|
||||
int64_t backoff_start_time_ = 0;
|
||||
int64_t backoff_duration_ = 0;
|
||||
int64_t provisioning_time_ = 0;
|
||||
}; // class SystemFallbackInfo
|
||||
} // namespace okp
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_CORE_OKP_SYSTEM_INFO_H_
|
||||
85
core/include/ota_keybox_provisioner.h
Normal file
85
core/include/ota_keybox_provisioner.h
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright 2021 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_OTA_KEYBOX_PROVISIONER_H_
|
||||
#define WVCDM_CORE_OTA_KEYBOX_PROVISIONER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "client_identification.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "metrics_collections.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
class CryptoSession;
|
||||
namespace okp {
|
||||
class SystemFallbackPolicy;
|
||||
} // namespace okp
|
||||
|
||||
// A CdmEngine-specific OTA keybox provisioning context.
|
||||
class OtaKeyboxProvisioner {
|
||||
public:
|
||||
// Creates a new OtaKeyboxProvisioner.
|
||||
// Checks for the system fallback policy and if the device
|
||||
// requires provisioning.
|
||||
// |crypto_metrics| - CryptoMetrics instance that is used in the
|
||||
// the calling EngineMetrics.
|
||||
static std::unique_ptr<OtaKeyboxProvisioner> Create(
|
||||
metrics::CryptoMetrics* crypto_metrics);
|
||||
static std::unique_ptr<OtaKeyboxProvisioner> CreateForTesting(
|
||||
std::unique_ptr<CryptoSession>&& crypto_session,
|
||||
okp::SystemFallbackPolicy* fallback_policy);
|
||||
|
||||
~OtaKeyboxProvisioner();
|
||||
|
||||
// Returns true if the underlying SystemFallbackPolicy is
|
||||
// provisioned.
|
||||
// Note: This may change without a call to HandleProvisioningResponse()
|
||||
// on this instance as provisioning is a system-wide responsibility.
|
||||
bool IsProvisioned() const;
|
||||
bool IsInFallbackMode() const;
|
||||
|
||||
// Indicates that a request has been successfully generated.
|
||||
uint32_t request_generated() const { return request_generated_; }
|
||||
// Indicates that a response has been successfully received by
|
||||
// this provisioner.
|
||||
bool response_received() const { return response_received_; }
|
||||
|
||||
// === Request/response API ===
|
||||
|
||||
// Generates and prepares a OTA Keybox Provisioning request, packing
|
||||
// it into a SignedProvisioningMessage.
|
||||
// |default_url| will be populated with the URL of the provisioning
|
||||
// server used for OTA keybox provisioning.
|
||||
CdmResponseType GetProvisioningRequest(std::string* request,
|
||||
std::string* default_url);
|
||||
// Receives, unwraps and loads the OTA Keybox Provisioning response.
|
||||
// |response| must be a SignedProvisioningMessage containing an
|
||||
// OTA keybox provisioning response.
|
||||
CdmResponseType HandleProvisioningResponse(const std::string& response);
|
||||
|
||||
private:
|
||||
OtaKeyboxProvisioner(std::unique_ptr<CryptoSession>&& crypto_session,
|
||||
okp::SystemFallbackPolicy* fallback_policy);
|
||||
|
||||
bool Init();
|
||||
|
||||
void CleanUp();
|
||||
|
||||
std::unique_ptr<CryptoSession> crypto_session_;
|
||||
ClientIdentification client_id_;
|
||||
|
||||
// Pointer to the system-wide okp::SystemFallbackPolicy. This class
|
||||
// does not take ownership of this pointer.
|
||||
okp::SystemFallbackPolicy* fallback_policy_ = nullptr;
|
||||
|
||||
// These flags are for debugging purposes.
|
||||
bool request_generated_ = false;
|
||||
bool response_received_ = false;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(OtaKeyboxProvisioner);
|
||||
}; // class OtaKeyboxProvisioner
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_CORE_OTA_KEYBOX_PROVISIONER_H_
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_POLICY_ENGINE_H_
|
||||
#define WVCDM_CORE_POLICY_ENGINE_H_
|
||||
@@ -15,12 +15,15 @@
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvutil {
|
||||
class Clock;
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
using video_widevine::LicenseIdentification;
|
||||
using video_widevine::WidevinePsshData_EntitledKey;
|
||||
|
||||
class Clock;
|
||||
class CryptoSession;
|
||||
class PolicyTimers;
|
||||
class WvCdmEventListener;
|
||||
@@ -162,7 +165,7 @@ class PolicyEngine {
|
||||
|
||||
// Test only methods
|
||||
// set_clock alters ownership of the passed-in pointer.
|
||||
void set_clock(Clock* clock);
|
||||
void set_clock(wvutil::Clock* clock);
|
||||
|
||||
void SetSecurityLevelForTest(CdmSecurityLevel security_level);
|
||||
|
||||
@@ -195,7 +198,7 @@ class PolicyEngine {
|
||||
CryptoSession* crypto_session_;
|
||||
|
||||
std::unique_ptr<PolicyTimers> policy_timers_;
|
||||
std::unique_ptr<Clock> clock_;
|
||||
std::unique_ptr<wvutil::Clock> clock_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(PolicyEngine);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_POLICY_TIMERS_H_
|
||||
#define WVCDM_CORE_POLICY_TIMERS_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_POLICY_TIMERS_V15_H_
|
||||
#define WVCDM_CORE_POLICY_TIMERS_V15_H_
|
||||
@@ -29,7 +29,7 @@ class PolicyTimersV15 : public PolicyTimers {
|
||||
public:
|
||||
PolicyTimersV15() : grace_period_end_time_(0) {}
|
||||
|
||||
virtual ~PolicyTimersV15() {}
|
||||
~PolicyTimersV15() override {}
|
||||
|
||||
// UpdateLicense is used in handling a license response, a renewal response,
|
||||
// or when restoring or releasing a persistent license.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_POLICY_TIMERS_V16_H_
|
||||
#define WVCDM_CORE_POLICY_TIMERS_V16_H_
|
||||
@@ -26,7 +26,7 @@ class PolicyTimersV16 : public PolicyTimers {
|
||||
public:
|
||||
PolicyTimersV16() {}
|
||||
|
||||
virtual ~PolicyTimersV16() {}
|
||||
~PolicyTimersV16() override {}
|
||||
|
||||
// UpdateLicense is used in handling a license response, a renewal response,
|
||||
// or when restoring or releasing a persistent license.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Description:
|
||||
// Declaration of classes representing AES and RSA public keys used
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_PROPERTIES_H_
|
||||
#define WVCDM_CORE_PROPERTIES_H_
|
||||
@@ -66,6 +66,7 @@ class Properties {
|
||||
}
|
||||
static bool GetCompanyName(std::string* company_name);
|
||||
static bool GetModelName(std::string* model_name);
|
||||
static bool GetModelYear(std::string* model_year);
|
||||
static bool GetArchitectureName(std::string* arch_name);
|
||||
static bool GetDeviceName(std::string* device_name);
|
||||
static bool GetProductName(std::string* product_name);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
#ifndef WVCDM_CORE_SERVICE_CERTIFICATE_H_
|
||||
#define WVCDM_CORE_SERVICE_CERTIFICATE_H_
|
||||
@@ -38,8 +38,8 @@ class ServiceCertificate {
|
||||
const std::string& provider_id() const { return provider_id_; }
|
||||
|
||||
// Verify the signature for a message.
|
||||
virtual CdmResponseType VerifySignedMessage(const std::string& message,
|
||||
const std::string& signature);
|
||||
virtual CdmResponseType VerifySignedMessage(
|
||||
const std::string& message, const std::string& signature) const;
|
||||
|
||||
// Encrypt the ClientIdentification message for a provisioning or
|
||||
// licensing request. Encryption is performed using the current
|
||||
@@ -50,7 +50,7 @@ class ServiceCertificate {
|
||||
virtual CdmResponseType EncryptClientId(
|
||||
CryptoSession* crypto_session,
|
||||
const video_widevine::ClientIdentification* clear_client_id,
|
||||
video_widevine::EncryptedClientIdentification* encrypted_client_id);
|
||||
video_widevine::EncryptedClientIdentification* encrypted_client_id) const;
|
||||
|
||||
// Helper methods
|
||||
static bool GetRequest(CdmKeyMessage* request);
|
||||
@@ -63,7 +63,7 @@ class ServiceCertificate {
|
||||
// string to contain the decrypted data on return, and may not be null.
|
||||
// returns NO_ERROR if successful or an appropriate error code otherwise.
|
||||
virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext,
|
||||
std::string* ciphertext);
|
||||
std::string* ciphertext) const;
|
||||
|
||||
// Track whether object holds valid certificate
|
||||
bool has_certificate_;
|
||||
|
||||
68
core/include/system_id_extractor.h
Normal file
68
core/include/system_id_extractor.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2022 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_SYSTEM_ID_EXTRACTOR_H_
|
||||
#define WVCDM_CORE_SYSTEM_ID_EXTRACTOR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvutil {
|
||||
class FileSystem;
|
||||
} // namespace wvutil
|
||||
namespace wvcdm {
|
||||
class CryptoSession;
|
||||
class DeviceFiles;
|
||||
|
||||
// System ID extractor will find and extract the system ID of the device.
|
||||
// Handles the different cases where the system ID may be found in
|
||||
// different place.
|
||||
class SystemIdExtractor {
|
||||
public:
|
||||
SystemIdExtractor(RequestedSecurityLevel security_level,
|
||||
CryptoSession* crypto_session, wvutil::FileSystem* fs);
|
||||
virtual ~SystemIdExtractor() {}
|
||||
|
||||
// Disallow copy and move.
|
||||
SystemIdExtractor(const SystemIdExtractor&) = delete;
|
||||
SystemIdExtractor(SystemIdExtractor&&) = delete;
|
||||
SystemIdExtractor& operator=(const SystemIdExtractor&) = delete;
|
||||
SystemIdExtractor& operator=(SystemIdExtractor&&) = delete;
|
||||
|
||||
virtual bool ExtractSystemId(uint32_t* system_id);
|
||||
|
||||
// Extracts the system ID from a keybox key data (aka CA token).
|
||||
static bool ExtractSystemIdFromKeyboxData(const std::string& key_data,
|
||||
uint32_t* system_id);
|
||||
// Extracts the system ID from a serialized OEM certificate.
|
||||
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
||||
uint32_t* system_id);
|
||||
|
||||
void SetDeviceFilesForTesting(DeviceFiles* device_files) {
|
||||
test_device_files_ = device_files;
|
||||
}
|
||||
|
||||
private:
|
||||
// Extracts the system ID from keybox-based OEMCrypto implementations.
|
||||
// System ID is expected to be found in the keybox data. Devices
|
||||
// which require OTA keybox provisioning will return a null system ID.
|
||||
bool ExtractSystemIdProv20(uint32_t* system_id);
|
||||
// Extracts the system ID from OEM certificate-based OEMCrypto
|
||||
// implementations. System ID is expected to be in the manufacturers
|
||||
// intermediate X.509 certificate.
|
||||
bool ExtractSystemIdProv30(uint32_t* system_id);
|
||||
// Extracts the system ID from BCC-based OEMCrypto implementations.
|
||||
// System ID is expected to be found in the stored OEM certificate
|
||||
// for the provided origin-identifier, after BCC provisioning.
|
||||
// Clients which have not performed BCC provisioning will return
|
||||
// a null system ID.
|
||||
bool ExtractSystemIdProv40(uint32_t* system_id);
|
||||
|
||||
RequestedSecurityLevel security_level_ = kLevelDefault;
|
||||
CryptoSession* crypto_session_ = nullptr;
|
||||
wvutil::FileSystem* fs_ = nullptr;
|
||||
DeviceFiles* test_device_files_ = nullptr;
|
||||
};
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_CORE_SYSTEM_ID_EXTRACTOR_H_
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_USAGE_TABLE_HEADER_H_
|
||||
#define WVCDM_CORE_USAGE_TABLE_HEADER_H_
|
||||
@@ -41,7 +41,7 @@ namespace wvcdm {
|
||||
// initialized/terminated.
|
||||
//
|
||||
// Sessions and licenses are however handled by CdmSession and so most
|
||||
// calls to maniplate the usage table header related to usage entries
|
||||
// calls to manipulate the usage table header related to usage entries
|
||||
// are by CdmSession.
|
||||
//
|
||||
// Upgrades from a fixed size usage table (supported by previous
|
||||
@@ -53,20 +53,36 @@ class UsageTableHeader {
|
||||
UsageTableHeader();
|
||||
virtual ~UsageTableHeader() {}
|
||||
|
||||
// |crypto_session| is used to create or load a usage master table and
|
||||
// not cached beyound this call.
|
||||
// |crypto_session| is used to create or load a usage master table
|
||||
// and not cached beyound this call.
|
||||
// First attempts to restore the usage table from the device files.
|
||||
// If restoring fails, then a new usage table is created.
|
||||
// Note: No OEMCrypto session for the same security level should be
|
||||
// opened before calling.
|
||||
// Threading: Method requires care of caller for exclusive access
|
||||
// (ie. test setup or CryptoSession).
|
||||
bool Init(CdmSecurityLevel security_level, CryptoSession* crypto_session);
|
||||
|
||||
// |persistent_license| false indicates usage info record
|
||||
// Adds a new entry to the OEMCrypto usage table header, and associates
|
||||
// the entry with the provided |crypto_session|. The index of the new
|
||||
// usage entry will be returned by |usage_entry_number|.
|
||||
//
|
||||
// Type of entry depends on the value of |persistent_license|:
|
||||
// false - usage info / secure stop record
|
||||
// true - offline license
|
||||
//
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType AddEntry(CryptoSession* crypto_session,
|
||||
bool persistent_license,
|
||||
const CdmKeySetId& key_set_id,
|
||||
const std::string& usage_info_filename,
|
||||
const CdmKeyResponse& license_message,
|
||||
uint32_t* usage_entry_number);
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType LoadEntry(CryptoSession* crypto_session,
|
||||
const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number);
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType UpdateEntry(uint32_t usage_entry_number,
|
||||
CryptoSession* crypto_session,
|
||||
CdmUsageEntry* usage_entry);
|
||||
@@ -76,6 +92,8 @@ class UsageTableHeader {
|
||||
// to InvalidateEntry and MoveEntry are made.
|
||||
// If |defrag_table| is true, the table will be defragmented after
|
||||
// the entry has been invalidated.
|
||||
//
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType InvalidateEntry(uint32_t usage_entry_number,
|
||||
bool defrag_table,
|
||||
DeviceFiles* device_files,
|
||||
@@ -87,8 +105,14 @@ class UsageTableHeader {
|
||||
// when InvalidateEntry is mocked. This allows one to test methods that are
|
||||
// dependent on InvalidateEntry without having to set expectations
|
||||
// for the objects that InvalidateEntry depends on.
|
||||
//
|
||||
// Threading: Method requires care of caller for exclusive access.
|
||||
void InvalidateEntryForTest(uint32_t usage_entry_number);
|
||||
|
||||
// == Table information methods ==
|
||||
// Threading: None of the following are thread safe. Intended for
|
||||
// testing or internal use.
|
||||
|
||||
size_t size() { return usage_entry_info_.size(); }
|
||||
|
||||
size_t potential_table_capacity() const { return potential_table_capacity_; }
|
||||
@@ -109,7 +133,7 @@ class UsageTableHeader {
|
||||
}
|
||||
|
||||
// Set the reference clock used for the method GetCurrentTime().
|
||||
void SetClock(Clock* clock) {
|
||||
void SetClock(wvutil::Clock* clock) {
|
||||
if (clock != nullptr)
|
||||
clock_ref_ = clock;
|
||||
else
|
||||
@@ -125,6 +149,81 @@ class UsageTableHeader {
|
||||
}
|
||||
|
||||
private:
|
||||
// == Initialization methods ==
|
||||
// These should only be called during table initialization.
|
||||
// All parameters are assumed valid.
|
||||
|
||||
// Creates a new, empty usage table. Any existing usage table files
|
||||
// will be deleted.
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|
|
||||
// when required.
|
||||
bool CreateNewTable(CryptoSession* const crypto_session);
|
||||
// Attempts to restore the usage table from persistent storage, and
|
||||
// loads the usage table header into OEMCrypto.
|
||||
// Note: No other OEMCrypto session should be opened before calling.
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|
|
||||
// when required.
|
||||
bool RestoreTable(CryptoSession* const crypto_session);
|
||||
|
||||
// Performs a check that there are no open OEMCrypto sessions for
|
||||
// the current security level of the usage table.
|
||||
// Threading: No special threading requirements.
|
||||
bool OpenSessionCheck(CryptoSession* const crypto_session);
|
||||
// Performs a check that the OEMCrypto table can support at least
|
||||
// one more entry if the table is at or near the reported capacity.
|
||||
// If this check fails, a new usage table SHOULD be created.
|
||||
// Threading: Method requires caller to take exclusive use of
|
||||
// |usage_table_header_lock_|.
|
||||
bool CapacityCheck(CryptoSession* const crypto_session);
|
||||
|
||||
// Attempts to determine the capacity of the OEMCrypto usage table.
|
||||
// Sets the result to |potential_table_capacity_|.
|
||||
// Threading: Method requires caller to take exclusive use of
|
||||
// |usage_table_header_lock_|.
|
||||
bool DetermineTableCapacity(CryptoSession* crypto_session);
|
||||
|
||||
// == Table operation methods ==
|
||||
// Threading: All of the following methods require caller to take
|
||||
// exclusive use of |usage_table_header_lock_|.
|
||||
|
||||
// Creates a new entry for the provided crypto session. If the
|
||||
// entry is created successfully in OEMCrypto, then a new entry
|
||||
// info is added to the table's vector of entry info.
|
||||
CdmResponseType CreateEntry(CryptoSession* const crypto_session,
|
||||
uint32_t* usage_entry_number);
|
||||
|
||||
// Attempts to relocate a newly created usage entry associated with
|
||||
// the provided |crypto_session| to the lowest unoccupied position in
|
||||
// the table.
|
||||
// |usage_entry_number| is treated as both an input and output.
|
||||
// Returns NO_ERROR so long as no internal operation fails,
|
||||
// regardless of whether the entry was moved or not.
|
||||
CdmResponseType RelocateNewEntry(CryptoSession* const crypto_session,
|
||||
uint32_t* usage_entry_number);
|
||||
|
||||
// Checks if the specified |usage_entry_number| is known to be
|
||||
// unoccupied (released).
|
||||
bool IsEntryUnoccupied(const uint32_t usage_entry_number) const;
|
||||
|
||||
// SetOfflineEntryInfo() and SetUsageInfoEntryInfo() populate the
|
||||
// entry meta-data with the required information based on the type
|
||||
// of entry.
|
||||
void SetOfflineEntryInfo(const uint32_t usage_entry_number,
|
||||
const std::string& key_set_id,
|
||||
const CdmKeyResponse& license_message);
|
||||
void SetUsageInfoEntryInfo(const uint32_t usage_entry_number,
|
||||
const std::string& key_set_id,
|
||||
const std::string& usage_info_file_name);
|
||||
|
||||
// Shrinks the table, removing all trailing unoccupied entries.
|
||||
// |usage_entry_info_| will be resized appropriately.
|
||||
// Caller must store the table after a successful call.
|
||||
CdmResponseType RefitTable(CryptoSession* const crypto_session);
|
||||
|
||||
virtual CdmResponseType InvalidateEntryInternal(
|
||||
uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics);
|
||||
|
||||
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
|
||||
const CdmUsageEntry& from_usage_entry,
|
||||
uint32_t to /* usage entry number */,
|
||||
@@ -140,7 +239,7 @@ class UsageTableHeader {
|
||||
|
||||
// Stores the usage table and it's info. This will increment
|
||||
// |store_table_counter_| if successful.
|
||||
bool StoreTable(DeviceFiles* device_files);
|
||||
bool StoreTable();
|
||||
|
||||
CdmResponseType Shrink(metrics::CryptoMetrics* metrics,
|
||||
uint32_t number_of_usage_entries_to_delete);
|
||||
@@ -153,8 +252,6 @@ class UsageTableHeader {
|
||||
// evicted.
|
||||
CdmResponseType ReleaseOldestEntry(metrics::CryptoMetrics* metrics);
|
||||
|
||||
virtual bool is_inited() { return is_inited_; }
|
||||
|
||||
// Performs and LRU upgrade on all loaded CdmUsageEntryInfo from a
|
||||
// device file that had not yet been upgraded to use the LRU data.
|
||||
virtual bool LruUpgradeAllUsageEntries();
|
||||
@@ -212,17 +309,16 @@ class UsageTableHeader {
|
||||
// usage_table_header. Usage entries should use the file system provided
|
||||
// by CdmSession.
|
||||
std::unique_ptr<DeviceFiles> device_files_;
|
||||
std::unique_ptr<FileSystem> file_system_;
|
||||
CdmSecurityLevel security_level_;
|
||||
SecurityLevel requested_security_level_;
|
||||
std::unique_ptr<wvutil::FileSystem> file_system_;
|
||||
CdmSecurityLevel security_level_ = kSecurityLevelUninitialized;
|
||||
RequestedSecurityLevel requested_security_level_ = kLevelDefault;
|
||||
|
||||
CdmUsageTableHeader usage_table_header_;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_;
|
||||
|
||||
// Lock to ensure that a single object is created for each security level
|
||||
// and data member to represent whether an object has been correctly
|
||||
// initialized.
|
||||
bool is_inited_;
|
||||
// Table is sync with persistent storage and can be used by the CDM
|
||||
// to interact with OEMCrypto.
|
||||
bool is_initialized_ = false;
|
||||
|
||||
// Synchonizes access to the Usage Table Header and bookkeeping
|
||||
// data-structures
|
||||
@@ -232,11 +328,11 @@ class UsageTableHeader {
|
||||
|
||||
// |clock_| represents the system's "wall clock". For the clock's purpose
|
||||
// we do not need a more secure clock.
|
||||
Clock clock_;
|
||||
wvutil::Clock clock_;
|
||||
// |clock_ref_| is a pointer to the clock which is to be used for
|
||||
// obtaining the current time. By default, this points to the internal
|
||||
// |clock_| variable, however, it can be overrided for testing purpose.
|
||||
Clock* clock_ref_;
|
||||
// |clock_| variable, however, it can be overridden for testing purpose.
|
||||
wvutil::Clock* clock_ref_;
|
||||
|
||||
// The maximum number of entries that the underlying OEMCrypto
|
||||
// implementation can support. Some implementations might not
|
||||
@@ -252,6 +348,7 @@ class UsageTableHeader {
|
||||
#if defined(UNIT_TEST)
|
||||
// Test related declarations
|
||||
friend class UsageTableHeaderTest;
|
||||
|
||||
FRIEND_TEST(UsageTableHeaderTest, Shrink_NoneOfTable);
|
||||
FRIEND_TEST(UsageTableHeaderTest, Shrink_PartOfTable);
|
||||
FRIEND_TEST(UsageTableHeaderTest, Shrink_AllOfTable);
|
||||
|
||||
@@ -1,54 +1,71 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_WV_CDM_CONSTANTS_H_
|
||||
#define WVCDM_CORE_WV_CDM_CONSTANTS_H_
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
namespace wvcdm {
|
||||
static const size_t KEY_CONTROL_SIZE = 16;
|
||||
static const size_t KEY_ID_SIZE = 16;
|
||||
static const size_t KEY_IV_SIZE = 16;
|
||||
static const size_t KEY_PAD_SIZE = 16;
|
||||
static const size_t CONTENT_KEY_SIZE = 16;
|
||||
static const size_t SERVICE_KEY_SIZE = 16;
|
||||
static const size_t MAC_KEY_SIZE = 32;
|
||||
static const size_t KEYBOX_KEY_DATA_SIZE = 72;
|
||||
static const size_t SRM_REQUIREMENT_SIZE = 12;
|
||||
constexpr size_t KEY_CONTROL_SIZE = 16;
|
||||
constexpr size_t KEY_ID_SIZE = 16;
|
||||
constexpr size_t KEY_IV_SIZE = 16;
|
||||
constexpr size_t KEY_PAD_SIZE = 16;
|
||||
constexpr size_t CONTENT_KEY_SIZE = 16;
|
||||
constexpr size_t SERVICE_KEY_SIZE = 16;
|
||||
constexpr size_t MAC_KEY_SIZE = 32;
|
||||
constexpr size_t ENTITLEMENT_KEY_SIZE = 32;
|
||||
constexpr size_t KEYBOX_KEY_DATA_SIZE = 72;
|
||||
constexpr size_t SRM_REQUIREMENT_SIZE = 12;
|
||||
|
||||
constexpr size_t LICENSE_PROTOCOL_2_1_PADDING = 16;
|
||||
|
||||
// Initial estimate of certificate size. Code that
|
||||
// uses this estimate should be able to adapt to a larger or smaller size.
|
||||
static const size_t CERTIFICATE_DATA_SIZE = 4 * 1024;
|
||||
constexpr size_t CERTIFICATE_DATA_SIZE = 4 * 1024;
|
||||
|
||||
// Use 0 to represent never expired license as specified in EME spec
|
||||
// (NaN in JS translates to 0 in unix timestamp).
|
||||
static const int64_t NEVER_EXPIRES = 0;
|
||||
static const int64_t UNLIMITED_DURATION = 0;
|
||||
constexpr int64_t NEVER_EXPIRES = 0;
|
||||
constexpr int64_t UNLIMITED_DURATION = 0;
|
||||
constexpr int64_t INVALID_TIME = -1;
|
||||
|
||||
// Not a valid system ID. Used as a placeholder for systems without an ID.
|
||||
// Will not be accepted for DRM provisioning requests or license requests.
|
||||
static constexpr uint32_t NULL_SYSTEM_ID =
|
||||
static_cast<uint32_t>(std::numeric_limits<int>::max());
|
||||
|
||||
// This is the lower limit. For OEMCrypto v16+ one can query and find how many
|
||||
// are supported
|
||||
static constexpr size_t kMinimumUsageTableEntriesSupported = 200;
|
||||
constexpr size_t kMinimumUsageTableEntriesSupported = 200;
|
||||
|
||||
// Resource rating tiers
|
||||
static const uint32_t RESOURCE_RATING_TIER_LOW = 1u;
|
||||
static const uint32_t RESOURCE_RATING_TIER_MEDIUM = 2u;
|
||||
static const uint32_t RESOURCE_RATING_TIER_HIGH = 3u;
|
||||
static const uint32_t RESOURCE_RATING_TIER_VERY_HIGH = 4u;
|
||||
static const uint32_t RESOURCE_RATING_TIER_MIN = RESOURCE_RATING_TIER_LOW;
|
||||
static const uint32_t RESOURCE_RATING_TIER_MAX = RESOURCE_RATING_TIER_VERY_HIGH;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_LOW = 1u;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_MEDIUM = 2u;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_HIGH = 3u;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_VERY_HIGH = 4u;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_MIN = RESOURCE_RATING_TIER_LOW;
|
||||
constexpr uint32_t RESOURCE_RATING_TIER_MAX = RESOURCE_RATING_TIER_VERY_HIGH;
|
||||
|
||||
// OEMCrypto features by version
|
||||
static const uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER = 15;
|
||||
constexpr uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER = 15;
|
||||
|
||||
static const char SESSION_ID_PREFIX[] = "sid";
|
||||
static const char ATSC_KEY_SET_ID_PREFIX[] = "atscksid";
|
||||
static const char KEY_SET_ID_PREFIX[] = "ksid";
|
||||
static const char KEY_SYSTEM[] = "com.widevine";
|
||||
static const char ATSC_APP_PACKAGE_NAME[] = "org.atsc";
|
||||
constexpr char SESSION_ID_PREFIX[] = "sid";
|
||||
constexpr char ATSC_KEY_SET_ID_PREFIX[] = "atscksid";
|
||||
constexpr char KEY_SET_ID_PREFIX[] = "ksid";
|
||||
constexpr char KEY_SYSTEM[] = "com.widevine";
|
||||
constexpr char ATSC_APP_PACKAGE_NAME[] = "org.atsc";
|
||||
|
||||
// define query keys, values here
|
||||
// Define query keys, values here.
|
||||
// To expose these query items to Android update:
|
||||
// android/mediadrm/src/WVDrmPlugin.cpp
|
||||
// android/mediadrm/src_hidl/WVDrmPlugin.cpp
|
||||
// Update test QueryStatus and QueryStatusL3 test for all possible outputs:
|
||||
// android/cdm/test/request_license_test.cpp
|
||||
// Update HIDL debug output:
|
||||
// android/src_hidl/WVDrmFactory.cpp
|
||||
static const std::string QUERY_KEY_LICENSE_TYPE =
|
||||
"LicenseType"; // "Streaming", "Offline"
|
||||
static const std::string QUERY_KEY_PLAY_ALLOWED =
|
||||
@@ -61,6 +78,8 @@ static const std::string QUERY_KEY_LICENSE_DURATION_REMAINING =
|
||||
"LicenseDurationRemaining"; // non-negative integer denoting seconds
|
||||
static const std::string QUERY_KEY_PLAYBACK_DURATION_REMAINING =
|
||||
"PlaybackDurationRemaining"; // non-negative integer denoting seconds
|
||||
static const std::string QUERY_KEY_RENTAL_DURATION_REMAINING =
|
||||
"RentalDurationRemaining"; // non-negative integer denoting seconds
|
||||
static const std::string QUERY_KEY_RENEWAL_SERVER_URL =
|
||||
"RenewalServerUrl"; // url
|
||||
static const std::string QUERY_KEY_OEMCRYPTO_SESSION_ID =
|
||||
@@ -93,13 +112,21 @@ static const std::string QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION =
|
||||
static const std::string QUERY_KEY_DECRYPT_HASH_SUPPORT = "DecryptHashSupport";
|
||||
static const std::string QUERY_KEY_PROVISIONING_MODEL = "ProvisioningModel";
|
||||
static const std::string QUERY_KEY_MAX_USAGE_TABLE_ENTRIES =
|
||||
"MaxNumberOfUsageTableEntries";
|
||||
"MaxUsageEntriesSupported";
|
||||
static const std::string QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION =
|
||||
"OemCryptoApiMinorVersion";
|
||||
static const std::string QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES =
|
||||
"AnalogOutputCapabilities";
|
||||
static const std::string QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT =
|
||||
"CanDisableAnalogOutput";
|
||||
static const std::string QUERY_KEY_WATERMARKING_SUPPORT = "WatermarkingSupport";
|
||||
static const std::string QUERY_KEY_PRODUCTION_READY = "ProductionReady";
|
||||
|
||||
static const std::string QUERY_VALUE_TRUE = "True";
|
||||
static const std::string QUERY_VALUE_FALSE = "False";
|
||||
static const std::string QUERY_VALUE_NONE = "None";
|
||||
static const std::string QUERY_VALUE_SUPPORTED = "Supported";
|
||||
static const std::string QUERY_VALUE_UNKNOWN = "Unknown";
|
||||
static const std::string QUERY_VALUE_STREAMING = "Streaming";
|
||||
static const std::string QUERY_VALUE_OFFLINE = "Offline";
|
||||
static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1";
|
||||
@@ -118,6 +145,12 @@ static const std::string QUERY_VALUE_HDCP_LEVEL_UNKNOWN = "HDCP-LevelUnknown";
|
||||
static const std::string QUERY_VALUE_DRM_CERTIFICATE = "DrmCertificate";
|
||||
static const std::string QUERY_VALUE_KEYBOX = "Keybox";
|
||||
static const std::string QUERY_VALUE_OEM_CERTIFICATE = "OEMCertificate";
|
||||
static const std::string QUERY_VALUE_CGMS_A = "CGMS-A";
|
||||
static const std::string QUERY_VALUE_BOOT_CERTIFICATE_CHAIN =
|
||||
"BootCertificateChain";
|
||||
static const std::string QUERY_VALUE_NOT_SUPPORTED = "NotSupported";
|
||||
static const std::string QUERY_VALUE_CONFIGURABLE = "Configurable";
|
||||
static const std::string QUERY_VALUE_ALWAYS_ON = "AlwaysOn";
|
||||
|
||||
static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4";
|
||||
static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4";
|
||||
@@ -137,13 +170,13 @@ static const std::string HLS_METHOD_SAMPLE_AES = "SAMPLE-AES";
|
||||
static const std::string HLS_IV_ATTRIBUTE = "IV";
|
||||
static const std::string HLS_URI_ATTRIBUTE = "URI";
|
||||
|
||||
static const char EMPTY_ORIGIN[] = "";
|
||||
static const char EMPTY_SPOID[] = "";
|
||||
constexpr char EMPTY_ORIGIN[] = "";
|
||||
constexpr char EMPTY_SPOID[] = "";
|
||||
|
||||
// Policy engine HDCP enforcement
|
||||
static const uint32_t HDCP_UNSPECIFIED_VIDEO_RESOLUTION = 0;
|
||||
static const int64_t HDCP_DEVICE_CHECK_INTERVAL = 10;
|
||||
static const char EMPTY_APP_PACKAGE_NAME[] = "";
|
||||
constexpr uint32_t HDCP_UNSPECIFIED_VIDEO_RESOLUTION = 0;
|
||||
constexpr int64_t HDCP_DEVICE_CHECK_INTERVAL = 10;
|
||||
constexpr char EMPTY_APP_PACKAGE_NAME[] = "";
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_WV_CDM_CONSTANTS_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_WV_CDM_EVENT_LISTENER_H_
|
||||
#define WVCDM_CORE_WV_CDM_EVENT_LISTENER_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_WV_CDM_TYPES_H_
|
||||
#define WVCDM_CORE_WV_CDM_TYPES_H_
|
||||
@@ -25,6 +25,7 @@ using CdmKeySetId = std::string;
|
||||
using RequestId = std::string;
|
||||
using CryptoResult = uint32_t;
|
||||
using CryptoSessionId = uint32_t;
|
||||
using EntitledKeySessionId = uint32_t;
|
||||
using CdmAppParameterMap = std::map<std::string, std::string>;
|
||||
using CdmQueryMap = std::map<std::string, std::string>;
|
||||
using CdmUsageInfo = std::vector<std::string>;
|
||||
@@ -416,6 +417,31 @@ enum CdmResponseType : int32_t {
|
||||
LOAD_USAGE_ENTRY_INVALID_SESSION = 361,
|
||||
RESTORE_OFFLINE_LICENSE_ERROR_3 = 362,
|
||||
NO_SRM_VERSION = 363,
|
||||
SESSION_NOT_FOUND_23 = 364,
|
||||
CERT_PROVISIONING_RESPONSE_ERROR_9 = 365,
|
||||
CERT_PROVISIONING_RESPONSE_ERROR_10 = 366,
|
||||
CLIENT_TOKEN_NOT_SET = 367,
|
||||
USAGE_ENTRY_ALREADY_LOADED = 368,
|
||||
PARSE_OKP_RESPONSE_ERROR = 369,
|
||||
OKP_ALREADY_PROVISIONED = 370,
|
||||
// The specific error code values below can be changed when merging master
|
||||
// branch if there are conflicts.
|
||||
PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR = 371,
|
||||
GET_BOOT_CERTIFICATE_CHAIN_ERROR = 372,
|
||||
GENERATE_CERTIFICATE_KEY_PAIR_ERROR = 373,
|
||||
GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR = 374,
|
||||
LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR = 375,
|
||||
PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN = 376,
|
||||
PROVISIONING_4_FILE_SYSTEM_IS_NULL = 377,
|
||||
PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES = 378,
|
||||
PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE = 379,
|
||||
PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS = 380,
|
||||
PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE = 381,
|
||||
PROVISIONING_4_NO_PRIVATE_KEY = 382,
|
||||
PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2 = 383,
|
||||
PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE = 384,
|
||||
PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE = 385,
|
||||
PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3 = 386,
|
||||
// Don't forget to add new values to
|
||||
// * core/test/test_printers.cpp.
|
||||
// * android/include/mapErrors-inl.h
|
||||
@@ -455,7 +481,7 @@ enum CdmLicenseKeyType : int32_t {
|
||||
kLicenseKeyTypeEntitlement,
|
||||
};
|
||||
|
||||
enum SecurityLevel : uint32_t { kLevelDefault, kLevel3 };
|
||||
enum RequestedSecurityLevel : uint32_t { kLevelDefault, kLevel3 };
|
||||
|
||||
enum CdmSecurityLevel : int32_t {
|
||||
kSecurityLevelUninitialized,
|
||||
@@ -496,6 +522,7 @@ enum CdmClientTokenType : int32_t {
|
||||
kClientTokenDrmCert,
|
||||
kClientTokenOemCert,
|
||||
kClientTokenUninitialized,
|
||||
kClientTokenBootCertChain,
|
||||
};
|
||||
|
||||
// kNonSecureUsageSupport - TEE does not provide any support for usage
|
||||
@@ -560,6 +587,25 @@ enum CdmKeySecurityLevel : int32_t {
|
||||
kKeySecurityLevelUnknown,
|
||||
};
|
||||
|
||||
enum CdmProvisioningStatus : int32_t {
|
||||
kProvisioned,
|
||||
kUnknownProvisionStatus,
|
||||
kNeedsDrmCertProvisioning,
|
||||
kNeedsOemCertProvisioning,
|
||||
};
|
||||
|
||||
enum CdmWatermarkingSupport : int32_t {
|
||||
kWatermarkingNotSupported,
|
||||
kWatermarkingConfigurable,
|
||||
kWatermarkingAlwaysOn
|
||||
};
|
||||
|
||||
enum CdmProductionReadiness : int32_t {
|
||||
kProductionReadinessUnknown,
|
||||
kProductionReadinessTrue,
|
||||
kProductionReadinessFalse,
|
||||
};
|
||||
|
||||
class CdmKeyAllowedUsage {
|
||||
public:
|
||||
CdmKeyAllowedUsage() { Clear(); }
|
||||
@@ -789,6 +835,33 @@ class KeyMessage;
|
||||
class Request;
|
||||
class Key;
|
||||
|
||||
// Logging utilities for types defined above.
|
||||
// Converts the different enum types to a human readable C-string for
|
||||
// logging. Query strings values are used if available for the enum.
|
||||
// These functions will fail silently to avoid double logging.
|
||||
const char* CdmCertificateTypeToString(CdmCertificateType type);
|
||||
const char* CdmClientTokenTypeToString(CdmClientTokenType type);
|
||||
const char* CdmLicenseTypeToString(CdmLicenseType license_type);
|
||||
const char* CdmOfflineLicenseStateToString(
|
||||
CdmOfflineLicenseState license_state);
|
||||
const char* CdmSecurityLevelToString(CdmSecurityLevel security_level);
|
||||
const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type);
|
||||
const char* RequestedSecurityLevelToString(
|
||||
RequestedSecurityLevel security_level);
|
||||
const char* CdmWatermarkingSupportToString(CdmWatermarkingSupport support);
|
||||
const char* CdmProductionReadinessToString(CdmProductionReadiness readiness);
|
||||
// Converts a generic, unknown enum value to a string representation
|
||||
// containing its numeric value.
|
||||
// The pointer returned from this function is thread_local.
|
||||
const char* UnknownEnumValueToString(int value);
|
||||
|
||||
// Both IdToString() and IdPtrToString() functions are used to convert
|
||||
// session IDs, key set IDs or other CDM specific identifiers to a
|
||||
// loggable format.
|
||||
const char* IdToString(const std::string& id);
|
||||
// Some CDM API function allow for optional string parameters to be
|
||||
// provided as string pointers.
|
||||
const char* IdPtrToString(const std::string* id);
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_WV_CDM_TYPES_H_
|
||||
|
||||
Reference in New Issue
Block a user