Source release v3.1.0
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "certificate_provisioning.h"
|
||||
#include "crypto_session.h"
|
||||
#include "file_store.h"
|
||||
#include "initialization_data.h"
|
||||
#include "lock.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
@@ -26,22 +27,24 @@ typedef std::map<CdmKeySetId, CdmSessionId> CdmReleaseKeySetMap;
|
||||
|
||||
class CdmEngine {
|
||||
public:
|
||||
CdmEngine();
|
||||
CdmEngine(FileSystem* file_system);
|
||||
virtual ~CdmEngine();
|
||||
|
||||
// Session related methods
|
||||
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
||||
CdmClientPropertySet* property_set,
|
||||
const std::string& origin,
|
||||
const CdmSessionId& forced_session_id,
|
||||
WvCdmEventListener* event_listener);
|
||||
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
||||
CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener,
|
||||
const CdmSessionId* forced_session_id,
|
||||
CdmSessionId* session_id);
|
||||
virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
|
||||
virtual bool IsOpenSession(const CdmSessionId& session_id);
|
||||
|
||||
virtual CdmResponseType OpenKeySetSession(
|
||||
const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set,
|
||||
const std::string& origin, WvCdmEventListener* event_listener);
|
||||
virtual CdmResponseType OpenKeySetSession(const CdmKeySetId& key_set_id,
|
||||
CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener);
|
||||
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
|
||||
|
||||
// License related methods
|
||||
@@ -58,27 +61,17 @@ class CdmEngine {
|
||||
// app_parameters: Additional, application-specific parameters that factor
|
||||
// into the request generation. This is ignored for release
|
||||
// and renewal requests.
|
||||
// key_request: This must be non-null and point to a CdmKeyMessage. The buffer
|
||||
// will have its contents replaced with the key request.
|
||||
// key_request_type: May be null. If it is non-null, it will be filled with
|
||||
// key request type, whether it is an initial request,
|
||||
// renewal request or release request etc.
|
||||
// server_url: This must be non-null and point to a string. The string will
|
||||
// have its contents replaced with the default URL (if one is
|
||||
// known) to send this key request to.
|
||||
// key_set_id_out: May be null. If it is non-null, the CdmKeySetId pointed to
|
||||
// will have its contents replaced with the key set ID of the
|
||||
// session. Note that for non-offline license requests, the
|
||||
// key set ID is empty, so the CdmKeySetId will be cleared.
|
||||
// TODO(kqyang): Consider refactor GenerateKeyRequest to reduce the number of
|
||||
// parameters.
|
||||
// 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,
|
||||
// whether it is an initial request, renewal request,
|
||||
// release request, etc. The url field will be filled with
|
||||
// the default URL (if one is known) to send this key
|
||||
// request to.
|
||||
virtual CdmResponseType GenerateKeyRequest(
|
||||
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
|
||||
const InitializationData& init_data, const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
|
||||
CdmKeyRequestType* key_request_type, std::string* server_url,
|
||||
CdmKeySetId* key_set_id_out);
|
||||
|
||||
CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request);
|
||||
// Accept license response and extract key info.
|
||||
virtual CdmResponseType AddKey(const CdmSessionId& session_id,
|
||||
const CdmKeyResponse& key_data,
|
||||
@@ -90,9 +83,8 @@ class CdmEngine {
|
||||
virtual CdmResponseType RemoveKeys(const CdmSessionId& session_id);
|
||||
|
||||
// Construct valid renewal request for the current session keys.
|
||||
virtual CdmResponseType GenerateRenewalRequest(const CdmSessionId& session_id,
|
||||
CdmKeyMessage* key_request,
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType GenerateRenewalRequest(
|
||||
const CdmSessionId& session_id, CdmKeyRequest* key_request);
|
||||
|
||||
// Accept renewal response and update key info.
|
||||
virtual CdmResponseType RenewKey(const CdmSessionId& session_id,
|
||||
@@ -100,38 +92,48 @@ class CdmEngine {
|
||||
|
||||
// Query system information
|
||||
virtual CdmResponseType QueryStatus(SecurityLevel security_level,
|
||||
const std::string& key,
|
||||
std::string* value);
|
||||
const std::string& query_token,
|
||||
std::string* query_response);
|
||||
|
||||
// Query session information
|
||||
virtual CdmResponseType QuerySessionStatus(const CdmSessionId& session_id,
|
||||
CdmQueryMap* key_info);
|
||||
CdmQueryMap* query_response);
|
||||
virtual bool IsReleaseSession(const CdmSessionId& session_id);
|
||||
virtual bool IsOfflineSession(const CdmSessionId& session_id);
|
||||
|
||||
// Query license information
|
||||
virtual CdmResponseType QueryKeyStatus(const CdmSessionId& session_id,
|
||||
CdmQueryMap* key_info);
|
||||
CdmQueryMap* query_response);
|
||||
|
||||
// Query session control information
|
||||
virtual CdmResponseType QueryKeyControlInfo(const CdmSessionId& session_id,
|
||||
CdmQueryMap* key_info);
|
||||
// Query the types of usage permitted for the specified key.
|
||||
virtual CdmResponseType QueryKeyAllowedUsage(const CdmSessionId& session_id,
|
||||
const std::string& key_id,
|
||||
CdmKeyAllowedUsage* key_usage);
|
||||
|
||||
// Query the types of usage permitted for the specified key.
|
||||
// Apply the query across all sessions. If the key is found in more than
|
||||
// one session, return the allowed usage settings only if the usage settings
|
||||
// are identical for each instance of the key. Otherwise, clear the settings
|
||||
// and return KEY_CONFLICT_1.
|
||||
virtual CdmResponseType QueryKeyAllowedUsage(const std::string& key_id,
|
||||
CdmKeyAllowedUsage* key_usage);
|
||||
|
||||
// Query OEMCrypto session ID
|
||||
virtual CdmResponseType QueryOemCryptoSessionId(
|
||||
const CdmSessionId& session_id, CdmQueryMap* query_response);
|
||||
|
||||
// Provisioning related methods
|
||||
virtual CdmResponseType GetProvisioningRequest(
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& origin, CdmProvisioningRequest* request,
|
||||
std::string* default_url);
|
||||
CdmProvisioningRequest* request, std::string* default_url);
|
||||
|
||||
virtual CdmResponseType HandleProvisioningResponse(
|
||||
const std::string& origin, const CdmProvisioningResponse& response,
|
||||
std::string* cert, std::string* wrapped_key);
|
||||
const CdmProvisioningResponse& response, std::string* cert,
|
||||
std::string* wrapped_key);
|
||||
|
||||
virtual bool IsProvisioned(CdmSecurityLevel security_level,
|
||||
const std::string& origin);
|
||||
virtual bool IsProvisioned(CdmSecurityLevel security_level);
|
||||
|
||||
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level,
|
||||
const std::string& origin);
|
||||
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level);
|
||||
|
||||
// Usage related methods for streaming licenses
|
||||
// Retrieve a random usage info from the list of all usage infos for this app
|
||||
@@ -154,6 +156,35 @@ class CdmEngine {
|
||||
virtual CdmResponseType Decrypt(const CdmSessionId& session_id,
|
||||
const CdmDecryptionParameters& parameters);
|
||||
|
||||
// Generic crypto operations - provides basic crypto operations that an
|
||||
// application can use outside of content stream processing
|
||||
|
||||
// Encrypts a buffer of app-level data.
|
||||
virtual CdmResponseType GenericEncrypt(
|
||||
const std::string& session_id, const std::string& in_buffer,
|
||||
const std::string& key_id, const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm, std::string* out_buffer);
|
||||
|
||||
// Decrypts a buffer of app-level data.
|
||||
virtual CdmResponseType GenericDecrypt(
|
||||
const std::string& session_id, const std::string& in_buffer,
|
||||
const std::string& key_id, const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm, std::string* out_buffer);
|
||||
|
||||
// Computes the signature for a message.
|
||||
virtual CdmResponseType GenericSign(const std::string& session_id,
|
||||
const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
std::string* signature);
|
||||
|
||||
// Verifies the signature on a buffer of app-level data.
|
||||
virtual CdmResponseType GenericVerify(const std::string& session_id,
|
||||
const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
const std::string& signature);
|
||||
|
||||
virtual size_t SessionSize() const { return sessions_.size(); }
|
||||
|
||||
// Is the key known to any session?
|
||||
@@ -175,6 +206,12 @@ class CdmEngine {
|
||||
|
||||
private:
|
||||
// private methods
|
||||
CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
||||
CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener,
|
||||
const CdmSessionId* forced_session_id,
|
||||
CdmSessionId* session_id);
|
||||
|
||||
void DeleteAllUsageReportsUponFactoryReset();
|
||||
bool ValidateKeySystem(const CdmKeySystem& key_system);
|
||||
CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
@@ -190,6 +227,7 @@ class CdmEngine {
|
||||
CdmReleaseKeySetMap release_key_sets_;
|
||||
scoped_ptr<CertificateProvisioning> cert_provisioning_;
|
||||
SecurityLevel cert_provisioning_requested_security_level_;
|
||||
FileSystem* file_system_;
|
||||
|
||||
static bool seeded_;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "device_files.h"
|
||||
#include "file_store.h"
|
||||
#include "initialization_data.h"
|
||||
#include "license.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
@@ -22,12 +23,13 @@ class WvCdmEventListener;
|
||||
|
||||
class CdmSession {
|
||||
public:
|
||||
CdmSession(CdmClientPropertySet* cdm_client_property_set,
|
||||
const std::string& origin, WvCdmEventListener* event_listener,
|
||||
const CdmSessionId* forced_session_id);
|
||||
CdmSession(FileSystem* file_system);
|
||||
virtual ~CdmSession();
|
||||
|
||||
virtual CdmResponseType Init();
|
||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
|
||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
const CdmSessionId* forced_session_id,
|
||||
WvCdmEventListener* event_listener);
|
||||
|
||||
virtual CdmResponseType RestoreOfflineSession(
|
||||
const CdmKeySetId& key_set_id, const CdmLicenseType license_type);
|
||||
@@ -35,25 +37,27 @@ class CdmSession {
|
||||
const CdmKeyMessage& key_request, const CdmKeyResponse& key_response);
|
||||
|
||||
virtual const CdmSessionId& session_id() { return session_id_; }
|
||||
virtual const CdmKeySetId& key_set_id() { return key_set_id_; }
|
||||
|
||||
virtual CdmResponseType GenerateKeyRequest(
|
||||
const InitializationData& init_data, CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
|
||||
CdmKeyRequestType* key_request_type, std::string* server_url,
|
||||
CdmKeySetId* key_set_id);
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request);
|
||||
|
||||
// AddKey() - Accept license response and extract key info.
|
||||
virtual CdmResponseType AddKey(const CdmKeyResponse& key_response,
|
||||
CdmKeySetId* key_set_id);
|
||||
virtual CdmResponseType AddKey(const CdmKeyResponse& key_response);
|
||||
|
||||
// Query session status
|
||||
virtual CdmResponseType QueryStatus(CdmQueryMap* key_info);
|
||||
virtual CdmResponseType QueryStatus(CdmQueryMap* query_response);
|
||||
|
||||
// Query license information
|
||||
virtual CdmResponseType QueryKeyStatus(CdmQueryMap* key_info);
|
||||
virtual CdmResponseType QueryKeyStatus(CdmQueryMap* query_response);
|
||||
|
||||
// Query session control info
|
||||
virtual CdmResponseType QueryKeyControlInfo(CdmQueryMap* key_info);
|
||||
// Query allowed usages for key
|
||||
virtual CdmResponseType QueryKeyAllowedUsage(const std::string& key_id,
|
||||
CdmKeyAllowedUsage* key_usage);
|
||||
|
||||
// Query OEMCrypto session ID
|
||||
virtual CdmResponseType QueryOemCryptoSessionId(CdmQueryMap* query_response);
|
||||
|
||||
// Decrypt() - Accept encrypted buffer and return decrypted data.
|
||||
virtual CdmResponseType Decrypt(const CdmDecryptionParameters& parameters);
|
||||
@@ -61,8 +65,7 @@ class CdmSession {
|
||||
// License renewal
|
||||
// GenerateRenewalRequest() - Construct valid renewal request for the current
|
||||
// session keys.
|
||||
virtual CdmResponseType GenerateRenewalRequest(CdmKeyMessage* key_request,
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType GenerateRenewalRequest(CdmKeyRequest* key_request);
|
||||
|
||||
// RenewKey() - Accept renewal response and update key info.
|
||||
virtual CdmResponseType RenewKey(const CdmKeyResponse& key_response);
|
||||
@@ -70,13 +73,13 @@ class CdmSession {
|
||||
// License release
|
||||
// GenerateReleaseRequest() - Construct valid release request for the current
|
||||
// session keys.
|
||||
virtual CdmResponseType GenerateReleaseRequest(CdmKeyMessage* key_request,
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType GenerateReleaseRequest(CdmKeyRequest* key_request);
|
||||
|
||||
// ReleaseKey() - Accept response and release key.
|
||||
virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response);
|
||||
|
||||
virtual bool IsKeyLoaded(const KeyId& key_id);
|
||||
virtual int64_t GetDurationRemaining();
|
||||
|
||||
// Used for notifying the Policy Engine of resolution changes
|
||||
virtual void NotifyResolution(uint32_t width, uint32_t height);
|
||||
@@ -116,11 +119,41 @@ class CdmSession {
|
||||
|
||||
bool DeleteLicense();
|
||||
|
||||
// Generate unique ID for each new session.
|
||||
CdmSessionId GenerateSessionId();
|
||||
|
||||
// Generic crypto operations - provides basic crypto operations that an
|
||||
// application can use outside of content stream processing
|
||||
|
||||
// Encrypts a buffer of app-level data.
|
||||
virtual CdmResponseType GenericEncrypt(const std::string& in_buffer,
|
||||
const std::string& key_id,
|
||||
const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm,
|
||||
std::string* out_buffer);
|
||||
|
||||
// Decrypts a buffer of app-level data.
|
||||
virtual CdmResponseType GenericDecrypt(const std::string& in_buffer,
|
||||
const std::string& key_id,
|
||||
const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm,
|
||||
std::string* out_buffer);
|
||||
|
||||
// Computes the signature for a message.
|
||||
virtual CdmResponseType GenericSign(const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
std::string* signature);
|
||||
|
||||
// Verifies the signature on a buffer of app-level data.
|
||||
virtual CdmResponseType GenericVerify(const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
const std::string& signature);
|
||||
|
||||
private:
|
||||
friend class CdmSessionTest;
|
||||
|
||||
// Generate unique ID for each new session.
|
||||
CdmSessionId GenerateSessionId();
|
||||
bool GenerateKeySetId(CdmKeySetId* key_set_id);
|
||||
|
||||
CdmResponseType StoreLicense();
|
||||
@@ -135,7 +168,6 @@ class CdmSession {
|
||||
// instance variables
|
||||
bool initialized_;
|
||||
CdmSessionId session_id_;
|
||||
const std::string origin_;
|
||||
scoped_ptr<CdmLicense> license_parser_;
|
||||
scoped_ptr<CryptoSession> crypto_session_;
|
||||
scoped_ptr<PolicyEngine> policy_engine_;
|
||||
@@ -167,6 +199,9 @@ class CdmSession {
|
||||
// license type release and offline related information
|
||||
CdmKeySetId key_set_id_;
|
||||
|
||||
bool mock_license_parser_in_use_;
|
||||
bool mock_policy_engine_in_use_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmSession);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace wvcdm {
|
||||
|
||||
class CdmSession;
|
||||
class FileSystem;
|
||||
|
||||
class CertificateProvisioning {
|
||||
public:
|
||||
@@ -26,7 +27,7 @@ class CertificateProvisioning {
|
||||
CdmProvisioningRequest* request,
|
||||
std::string* default_url);
|
||||
CdmResponseType HandleProvisioningResponse(
|
||||
const std::string& origin,
|
||||
FileSystem* file_system,
|
||||
const CdmProvisioningResponse& response,
|
||||
std::string* cert,
|
||||
std::string* wrapped_key);
|
||||
|
||||
@@ -17,6 +17,7 @@ class CryptoKey {
|
||||
const std::string& key_data_iv() const { return key_data_iv_; }
|
||||
const std::string& key_control() const { return key_control_; }
|
||||
const std::string& key_control_iv() const { return key_control_iv_; }
|
||||
CdmCipherMode cipher_mode() const { return cipher_mode_; }
|
||||
void set_key_id(const std::string& key_id) { key_id_ = key_id; }
|
||||
void set_key_data(const std::string& key_data) { key_data_ = key_data; }
|
||||
void set_key_data_iv(const std::string& iv) { key_data_iv_ = iv; }
|
||||
@@ -24,6 +25,9 @@ class CryptoKey {
|
||||
void set_key_control_iv(const std::string& ctl_iv) {
|
||||
key_control_iv_ = ctl_iv;
|
||||
}
|
||||
void set_cipher_mode(CdmCipherMode cipher_mode) {
|
||||
cipher_mode_ = cipher_mode;
|
||||
}
|
||||
|
||||
bool HasKeyControl() const { return key_control_.size() >= 16; }
|
||||
|
||||
@@ -33,6 +37,7 @@ class CryptoKey {
|
||||
std::string key_data_;
|
||||
std::string key_control_;
|
||||
std::string key_control_iv_;
|
||||
CdmCipherMode cipher_mode_;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -35,6 +35,7 @@ class CryptoSession {
|
||||
virtual bool GetApiVersion(uint32_t* version);
|
||||
virtual bool GetSystemId(uint32_t* system_id);
|
||||
virtual bool GetProvisioningId(std::string* provisioning_id);
|
||||
virtual uint8_t GetSecurityPatchLevel();
|
||||
|
||||
virtual CdmResponseType Open() { return Open(kLevelDefault); }
|
||||
virtual CdmResponseType Open(SecurityLevel requested_security_level);
|
||||
@@ -102,6 +103,25 @@ class CryptoSession {
|
||||
virtual bool GetNumberOfOpenSessions(size_t* count);
|
||||
virtual bool GetMaxNumberOfSessions(size_t* max);
|
||||
|
||||
virtual CdmResponseType GenericEncrypt(const std::string& in_buffer,
|
||||
const std::string& key_id,
|
||||
const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm,
|
||||
std::string* out_buffer);
|
||||
virtual CdmResponseType GenericDecrypt(const std::string& in_buffer,
|
||||
const std::string& key_id,
|
||||
const std::string& iv,
|
||||
CdmEncryptionAlgorithm algorithm,
|
||||
std::string* out_buffer);
|
||||
virtual CdmResponseType GenericSign(const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
std::string* signature);
|
||||
virtual CdmResponseType GenericVerify(const std::string& message,
|
||||
const std::string& key_id,
|
||||
CdmSigningAlgorithm algorithm,
|
||||
const std::string& signature);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Terminate();
|
||||
@@ -113,9 +133,17 @@ class CryptoSession {
|
||||
bool GenerateRsaSignature(const std::string& message, std::string* signature);
|
||||
size_t GetOffset(std::string message, std::string field);
|
||||
bool SetDestinationBufferType();
|
||||
|
||||
bool SelectKey(const std::string& key_id);
|
||||
|
||||
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);
|
||||
|
||||
static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128
|
||||
static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature
|
||||
static Lock crypto_lock_;
|
||||
static bool initialized_;
|
||||
@@ -129,11 +157,13 @@ class CryptoSession {
|
||||
bool is_destination_buffer_type_valid_;
|
||||
SecurityLevel requested_security_level_;
|
||||
|
||||
KeyId key_id_;
|
||||
KeyId cached_key_id_;
|
||||
|
||||
uint64_t request_id_base_;
|
||||
static uint64_t request_id_index_;
|
||||
|
||||
CdmCipherMode cipher_mode_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class File;
|
||||
class FileSystem;
|
||||
|
||||
class DeviceFiles {
|
||||
public:
|
||||
@@ -28,7 +28,7 @@ class DeviceFiles {
|
||||
kLicenseStateUnknown,
|
||||
} LicenseState;
|
||||
|
||||
DeviceFiles();
|
||||
DeviceFiles(FileSystem*);
|
||||
virtual ~DeviceFiles();
|
||||
|
||||
virtual bool Init(CdmSecurityLevel security_level);
|
||||
@@ -36,14 +36,12 @@ class DeviceFiles {
|
||||
return Init(security_level);
|
||||
}
|
||||
|
||||
virtual bool StoreCertificate(const std::string& origin,
|
||||
const std::string& certificate,
|
||||
virtual bool StoreCertificate(const std::string& certificate,
|
||||
const std::string& wrapped_private_key);
|
||||
virtual bool RetrieveCertificate(const std::string& origin,
|
||||
std::string* certificate,
|
||||
virtual bool RetrieveCertificate(std::string* certificate,
|
||||
std::string* wrapped_private_key);
|
||||
virtual bool HasCertificate(const std::string& origin);
|
||||
virtual bool RemoveCertificate(const std::string& origin);
|
||||
virtual bool HasCertificate();
|
||||
virtual bool RemoveCertificate();
|
||||
|
||||
virtual bool StoreLicense(const std::string& key_set_id,
|
||||
const LicenseState state,
|
||||
@@ -100,6 +98,13 @@ class DeviceFiles {
|
||||
CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_response);
|
||||
|
||||
virtual bool StoreHlsAttributes(const std::string& key_set_id,
|
||||
const CdmHlsMethod method,
|
||||
const std::vector<uint8_t>& media_segment_iv);
|
||||
virtual bool RetrieveHlsAttributes(const std::string& key_set_id,
|
||||
CdmHlsMethod* method,
|
||||
std::vector<uint8_t>* media_segment_iv);
|
||||
virtual bool DeleteHlsAttributes(const std::string& key_set_id);
|
||||
private:
|
||||
// Helpers that wrap the File interface and automatically handle hashing, as
|
||||
// well as adding the device files base path to to the file name.
|
||||
@@ -113,29 +118,25 @@ class DeviceFiles {
|
||||
bool RemoveFile(const std::string& name);
|
||||
ssize_t GetFileSize(const std::string& name);
|
||||
|
||||
// Certificate and offline licenses are now stored in security
|
||||
// level specific directories. In an earlier version they were
|
||||
// stored in a common directory and need to be copied over.
|
||||
virtual void SecurityLevelPathBackwardCompatibility();
|
||||
|
||||
static std::string GetCertificateFileName(const std::string& origin);
|
||||
static std::string GetCertificateFileName();
|
||||
static std::string GetHlsAttributesFileNameExtension();
|
||||
static std::string GetLicenseFileNameExtension();
|
||||
static std::string GetUsageInfoFileName(const std::string& app_id);
|
||||
static std::string GetFileNameSafeHash(const std::string& input);
|
||||
|
||||
// For testing only:
|
||||
void SetTestFile(File* file);
|
||||
#if defined(UNIT_TEST)
|
||||
FRIEND_TEST(DeviceFilesSecurityLevelTest, SecurityLevel);
|
||||
FRIEND_TEST(DeviceCertificateStoreTest, StoreCertificate);
|
||||
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, SecurityLevelPathBackwardCompatibility);
|
||||
FRIEND_TEST(DeviceFilesTest, StoreLicenses);
|
||||
FRIEND_TEST(DeviceFilesTest, UpdateLicenseState);
|
||||
FRIEND_TEST(DeviceFilesUsageInfoTest, Delete);
|
||||
@@ -153,12 +154,10 @@ class DeviceFiles {
|
||||
|
||||
static std::set<std::string> reserved_license_ids_;
|
||||
|
||||
scoped_ptr<File> file_;
|
||||
FileSystem* file_system_;
|
||||
CdmSecurityLevel security_level_;
|
||||
bool initialized_;
|
||||
|
||||
bool test_file_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(DeviceFiles);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,39 +15,54 @@ namespace wvcdm {
|
||||
|
||||
// File class. The implementation is platform dependent.
|
||||
class File {
|
||||
public:
|
||||
virtual ssize_t Read(char* buffer, size_t bytes);
|
||||
virtual ssize_t Write(const char* buffer, size_t bytes);
|
||||
virtual void Close();
|
||||
|
||||
protected:
|
||||
class Impl;
|
||||
|
||||
File(Impl*);
|
||||
virtual ~File();
|
||||
|
||||
private:
|
||||
Impl* impl_;
|
||||
|
||||
friend class FileSystem;
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(File);
|
||||
};
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
class Impl;
|
||||
|
||||
// defines as bit flag
|
||||
enum OpenFlags {
|
||||
kNoFlags = 0,
|
||||
kBinary = 1,
|
||||
kCreate = 2,
|
||||
kReadOnly = 4, // defaults to read and write access
|
||||
kTruncate = 8
|
||||
kCreate = 1,
|
||||
kReadOnly = 2, // defaults to read and write access
|
||||
kTruncate = 4
|
||||
};
|
||||
|
||||
File();
|
||||
virtual ~File();
|
||||
FileSystem();
|
||||
FileSystem(const std::string& origin, void* extra_data);
|
||||
virtual ~FileSystem();
|
||||
|
||||
virtual bool Open(const std::string& file_path, int flags);
|
||||
virtual ssize_t Read(char* buffer, size_t bytes);
|
||||
virtual ssize_t Write(const char* buffer, size_t bytes);
|
||||
virtual void Close();
|
||||
virtual File* Open(const std::string& file_path, int flags);
|
||||
|
||||
virtual bool Exists(const std::string& file_path);
|
||||
virtual bool Remove(const std::string& file_path);
|
||||
virtual bool Copy(const std::string& old_path, const std::string& new_path);
|
||||
virtual bool List(const std::string& path, std::vector<std::string>* files);
|
||||
virtual bool CreateDirectory(const std::string dir_path);
|
||||
virtual bool IsDirectory(const std::string& dir_path);
|
||||
virtual bool IsRegularFile(const std::string& file_path);
|
||||
virtual ssize_t FileSize(const std::string& file_path);
|
||||
|
||||
const std::string& origin() const { return origin_; }
|
||||
void SetOrigin(const std::string& origin);
|
||||
|
||||
private:
|
||||
Impl* impl_;
|
||||
std::string origin_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(File);
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(FileSystem);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -16,24 +16,62 @@ class InitializationData {
|
||||
InitializationData(const std::string& type = std::string(),
|
||||
const CdmInitData& data = CdmInitData());
|
||||
|
||||
bool is_supported() const { return is_cenc_ || is_webm_; }
|
||||
bool is_supported() const { return is_cenc_ || is_webm_ || is_hls_; }
|
||||
bool is_cenc() const { return is_cenc_; }
|
||||
bool is_hls() const { return is_hls_; }
|
||||
bool is_webm() const { return is_webm_; }
|
||||
|
||||
bool IsEmpty() const { return data_.empty(); }
|
||||
|
||||
const std::string& type() const { return type_; }
|
||||
const CdmInitData& data() const { return data_; }
|
||||
std::vector<uint8_t> hls_iv() const { return hls_iv_; }
|
||||
CdmHlsMethod hls_method() const { return hls_method_; }
|
||||
|
||||
private:
|
||||
// Parse a blob of multiple concatenated PSSH atoms to extract the first
|
||||
// Widevine PSSH.
|
||||
bool ExtractWidevinePssh(const CdmInitData& init_data, CdmInitData* output);
|
||||
|
||||
bool ExtractHlsAttributes(const std::string& attribute_list,
|
||||
CdmHlsMethod* method, std::vector<uint8_t>* iv,
|
||||
std::string* uri);
|
||||
static bool ConstructWidevineInitData(CdmHlsMethod method,
|
||||
const std::string& uri,
|
||||
CdmInitData* output);
|
||||
static bool ExtractQuotedAttribute(const std::string& attribute_list,
|
||||
const std::string& key,
|
||||
std::string* value);
|
||||
static bool ExtractHexAttribute(const std::string& attribute_list,
|
||||
const std::string& key,
|
||||
std::vector<uint8_t>* value);
|
||||
static bool ExtractAttribute(const std::string& attribute_list,
|
||||
const std::string& key, std::string* value);
|
||||
|
||||
static std::vector<std::string> ExtractKeyFormatVersions(
|
||||
const std::string& key_format_versions);
|
||||
|
||||
// For testing only:
|
||||
#if defined(UNIT_TEST)
|
||||
FRIEND_TEST(HlsAttributeExtractionTest, ExtractAttribute);
|
||||
FRIEND_TEST(HlsConstructionTest, InitData);
|
||||
FRIEND_TEST(HlsInitDataConstructionTest, InvalidUriDataFormat);
|
||||
FRIEND_TEST(HlsInitDataConstructionTest, InvalidUriBase64Encode);
|
||||
FRIEND_TEST(HlsHexAttributeExtractionTest, ExtractHexAttribute);
|
||||
FRIEND_TEST(HlsKeyFormatVersionsExtractionTest, ExtractKeyFormatVersions);
|
||||
FRIEND_TEST(HlsParseTest, Parse);
|
||||
FRIEND_TEST(HlsQuotedAttributeExtractionTest, ExtractQuotedAttribute);
|
||||
FRIEND_TEST(HlsTest, ExtractHlsAttributes);
|
||||
#endif
|
||||
|
||||
std::string type_;
|
||||
CdmInitData data_;
|
||||
bool is_cenc_;
|
||||
bool is_hls_;
|
||||
bool is_webm_;
|
||||
|
||||
std::vector<uint8_t> hls_iv_;
|
||||
CdmHlsMethod hls_method_;
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
139
core/include/license_key_status.h
Normal file
139
core/include/license_key_status.h
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_CORE_LICENSE_KEY_STATUS_H_
|
||||
#define WVCDM_CORE_LICENSE_KEY_STATUS_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class LicenseKeyStatus;
|
||||
|
||||
// Holds all content and operator session keys for a session.
|
||||
class LicenseKeys {
|
||||
public:
|
||||
LicenseKeys() {}
|
||||
virtual ~LicenseKeys() { Clear(); }
|
||||
|
||||
virtual bool Empty() { return keys_.empty(); }
|
||||
|
||||
// Returns true if the key is a content key (not an operator session key)
|
||||
virtual bool IsContentKey(const KeyId& key_id);
|
||||
|
||||
// Returns true if the key is currently usable for content decryption.
|
||||
virtual bool CanDecryptContent(const KeyId& key_id);
|
||||
|
||||
// Returns the allowed usages for a key.
|
||||
virtual bool GetAllowedUsage(const KeyId& key_id,
|
||||
CdmKeyAllowedUsage* allowed_usage);
|
||||
|
||||
// Applies a new status to each content key.
|
||||
// Returns true if any statuses changed, and sets new_usable_keys to
|
||||
// true if the status changes resulted in keys becoming usable.
|
||||
virtual bool ApplyStatusChange(CdmKeyStatus new_status,
|
||||
bool* new_usable_keys);
|
||||
|
||||
// Populates the CdmKeyStatusMap with the current content keys.
|
||||
virtual void ExtractKeyStatuses(CdmKeyStatusMap* content_keys);
|
||||
|
||||
// Determines whether the specified key can be used under the current
|
||||
// resolution and/or hdcp constraints. If no constraints have been applied
|
||||
// to the key, returns true.
|
||||
virtual bool MeetsConstraints(const KeyId& key_id);
|
||||
|
||||
// Applies a resolution and/or hdcp change to each key, updating their
|
||||
// useability under their constraints.
|
||||
virtual void ApplyConstraints(uint32_t new_resolution,
|
||||
CryptoSession::HdcpCapability new_hdcp_level);
|
||||
|
||||
// Extracts the keys from a license and makes them available for
|
||||
// querying usage and constraint settings.
|
||||
virtual void SetFromLicense(
|
||||
const video_widevine_server::sdk::License& license);
|
||||
|
||||
private:
|
||||
typedef ::video_widevine_server::sdk::License::KeyContainer KeyContainer;
|
||||
typedef std::map<wvcdm::KeyId, LicenseKeyStatus*>::const_iterator
|
||||
LicenseKeyStatusIterator;
|
||||
|
||||
void Clear();
|
||||
|
||||
bool is_initialized_;
|
||||
std::map<KeyId, LicenseKeyStatus*> keys_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(LicenseKeys);
|
||||
};
|
||||
|
||||
// Holds the current license status of a key.
|
||||
class LicenseKeyStatus {
|
||||
friend class LicenseKeys;
|
||||
|
||||
public:
|
||||
// Returns true if the key is a content key (not an operator session key)
|
||||
virtual bool IsContentKey() { return is_content_key_; }
|
||||
|
||||
// Returns true if the key is currently usable for content decryption
|
||||
virtual bool CanDecryptContent();
|
||||
|
||||
// Returns the usages allowed for this key.
|
||||
virtual bool GetAllowedUsage(CdmKeyAllowedUsage* allowed_usage);
|
||||
|
||||
// Returns the current status of the key.
|
||||
virtual CdmKeyStatus GetKeyStatus() const { return key_status_; }
|
||||
|
||||
// Applies a new status to this key.
|
||||
// Returns true if the status changed, and sets new_usable_keys to
|
||||
// true if the status changes resulted in the key becoming usable.
|
||||
virtual bool ApplyStatusChange(CdmKeyStatus new_status,
|
||||
bool* new_usable_keys);
|
||||
|
||||
// Returns the current constraint status of this key. The result
|
||||
// may change due to calls to ApplyConstraints().
|
||||
// Note: this will return true until the first call to ApplyConstraints().
|
||||
virtual bool MeetsConstraints() const { return meets_constraints_; }
|
||||
|
||||
// Applies the given changes in resolution or HDCP settings.
|
||||
virtual void ApplyConstraints(
|
||||
uint32_t new_resolution, CryptoSession::HdcpCapability new_hdcp_level);
|
||||
|
||||
protected:
|
||||
typedef ::video_widevine_server::sdk::License::KeyContainer KeyContainer;
|
||||
typedef KeyContainer::OperatorSessionKeyPermissions
|
||||
OperatorSessionKeyPermissions;
|
||||
typedef KeyContainer::OutputProtection OutputProtection;
|
||||
typedef KeyContainer::VideoResolutionConstraint VideoResolutionConstraint;
|
||||
typedef ::google::protobuf::RepeatedPtrField<VideoResolutionConstraint>
|
||||
ConstraintList;
|
||||
|
||||
LicenseKeyStatus(const KeyContainer& key);
|
||||
|
||||
virtual ~LicenseKeyStatus() {}
|
||||
|
||||
private:
|
||||
|
||||
void ParseContentKey(const KeyContainer& key);
|
||||
void ParseOperatorSessionKey(const KeyContainer& key);
|
||||
|
||||
bool HasConstraints() {
|
||||
return is_content_key_ && constraints_.size() != 0;
|
||||
}
|
||||
|
||||
void SetConstraints(const ConstraintList& constraints);
|
||||
|
||||
bool is_content_key_;
|
||||
CdmKeyStatus key_status_;
|
||||
bool meets_constraints_;
|
||||
CdmKeyAllowedUsage allowed_usage_;
|
||||
CryptoSession::HdcpCapability default_hdcp_level_;
|
||||
ConstraintList constraints_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(LicenseKeyStatus);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_LICENSE_KEY_STATUS_H_
|
||||
@@ -1,105 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_CORE_MAX_RES_ENGINE_H_
|
||||
#define WVCDM_CORE_MAX_RES_ENGINE_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "lock.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class Clock;
|
||||
class MaxResEngineTest;
|
||||
|
||||
// Similar to the Policy Engine, this acts as an oracle that basically says
|
||||
// "Yes(true) you may still decrypt or no(false) you may not decrypt this data
|
||||
// anymore."
|
||||
class MaxResEngine {
|
||||
public:
|
||||
explicit MaxResEngine(CryptoSession* crypto_session);
|
||||
virtual ~MaxResEngine();
|
||||
|
||||
// The value returned is computed during the last call to SetLicense/
|
||||
// SetResolution/OnTimerEvent and may be out of sync depending on the amount
|
||||
// of time elapsed. The current decryption status is not calculated when this
|
||||
// function is called to avoid overhead in the decryption path.
|
||||
virtual bool CanDecrypt(const KeyId& key_id);
|
||||
|
||||
// SetLicense is used in handling the initial license response. It stores
|
||||
// an exact copy of the key constraints from the license.
|
||||
virtual void SetLicense(const video_widevine_server::sdk::License& license);
|
||||
|
||||
// SetResolution is called when the current output resolution is updated by
|
||||
// the decoder. The max-res engine will recalculate the current resolution
|
||||
// constraints, (if any) which may affect the results for CanDecrypt().
|
||||
virtual void SetResolution(uint32_t width, uint32_t height);
|
||||
|
||||
// OnTimerEvent is called when a timer fires. The max-res engine may check the
|
||||
// current HDCP level using the crypto session, which may affect the results
|
||||
// for CanDecrypt().
|
||||
virtual void OnTimerEvent();
|
||||
|
||||
private:
|
||||
typedef ::video_widevine_server::sdk::License::KeyContainer KeyContainer;
|
||||
typedef ::video_widevine_server::sdk::License::KeyContainer::OutputProtection
|
||||
OutputProtection;
|
||||
typedef ::video_widevine_server::sdk::License::KeyContainer::
|
||||
VideoResolutionConstraint VideoResolutionConstraint;
|
||||
typedef ::google::protobuf::RepeatedPtrField<VideoResolutionConstraint>
|
||||
ConstraintList;
|
||||
|
||||
class KeyStatus {
|
||||
public:
|
||||
explicit KeyStatus(const ConstraintList& constraints);
|
||||
KeyStatus(const ConstraintList& constraints,
|
||||
const OutputProtection::HDCP& default_hdcp_level);
|
||||
|
||||
bool can_decrypt() const { return can_decrypt_; }
|
||||
|
||||
void Update(uint32_t res,
|
||||
CryptoSession::HdcpCapability current_hdcp_level);
|
||||
|
||||
private:
|
||||
void Init(const ConstraintList& constraints);
|
||||
|
||||
VideoResolutionConstraint* GetConstraintForRes(uint32_t res);
|
||||
|
||||
static CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp(
|
||||
const OutputProtection::HDCP& input);
|
||||
|
||||
bool can_decrypt_;
|
||||
|
||||
CryptoSession::HdcpCapability default_hdcp_level_;
|
||||
ConstraintList constraints_;
|
||||
};
|
||||
|
||||
typedef std::map<wvcdm::KeyId,
|
||||
wvcdm::MaxResEngine::KeyStatus*>::const_iterator KeyIterator;
|
||||
|
||||
void Init(CryptoSession* crypto_session, Clock* clock);
|
||||
|
||||
void DeleteAllKeys();
|
||||
|
||||
Lock status_lock_;
|
||||
std::map<KeyId, KeyStatus*> keys_;
|
||||
uint32_t current_resolution_;
|
||||
int64_t next_check_time_;
|
||||
|
||||
scoped_ptr<Clock> clock_;
|
||||
CryptoSession* crypto_session_;
|
||||
|
||||
// For testing
|
||||
friend class MaxResEngineTest;
|
||||
MaxResEngine(CryptoSession* crypto_session, Clock* clock);
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(MaxResEngine);
|
||||
};
|
||||
|
||||
} // wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_MAX_RES_ENGINE_H_
|
||||
@@ -34,6 +34,7 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(SecurityLevel level,
|
||||
size_t* count);
|
||||
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
|
||||
size_t* maximum);
|
||||
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level);
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "license_key_status.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "max_res_engine.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
@@ -67,7 +67,10 @@ class PolicyEngine {
|
||||
|
||||
virtual void NotifySessionExpiration();
|
||||
|
||||
virtual CdmResponseType Query(CdmQueryMap* key_info);
|
||||
virtual CdmResponseType Query(CdmQueryMap* query_response);
|
||||
|
||||
virtual CdmResponseType QueryKeyAllowedUsage(const KeyId& key_id,
|
||||
CdmKeyAllowedUsage* key_usage);
|
||||
|
||||
virtual const LicenseIdentification& license_id() { return license_id_; }
|
||||
|
||||
@@ -84,11 +87,20 @@ class PolicyEngine {
|
||||
bool IsPlaybackStarted() { return playback_start_time_ > 0; }
|
||||
|
||||
bool IsLicenseOrPlaybackDurationExpired(int64_t current_time);
|
||||
int64_t GetLicenseOrPlaybackDurationRemaining();
|
||||
|
||||
bool CanRenew() { return policy_.can_renew(); }
|
||||
|
||||
private:
|
||||
friend class PolicyEngineTest;
|
||||
friend class PolicyEngineConstraintsTest;
|
||||
|
||||
void InitDevice(CryptoSession* crypto_session);
|
||||
void CheckDevice(int64_t current_time);
|
||||
|
||||
void SetDeviceResolution(uint32_t width, uint32_t height) {
|
||||
current_resolution_ = width * height;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
kLicenseStateInitial,
|
||||
@@ -119,9 +131,9 @@ class PolicyEngine {
|
||||
// expiry time changes.
|
||||
void NotifyExpirationUpdate();
|
||||
|
||||
// These setters are for testing only. Takes ownership of the pointers.
|
||||
// set_clock() is for testing only. It alters ownership of the
|
||||
// passed-in pointer.
|
||||
void set_clock(Clock* clock);
|
||||
void set_max_res_engine(MaxResEngine* max_res_engine);
|
||||
|
||||
LicenseState license_state_;
|
||||
|
||||
@@ -153,9 +165,14 @@ class PolicyEngine {
|
||||
CdmSessionId session_id_;
|
||||
WvCdmEventListener* event_listener_;
|
||||
|
||||
scoped_ptr<MaxResEngine> max_res_engine_;
|
||||
// Keys associated with license - holds allowed usage, usage constraints,
|
||||
// and current status (CdmKeyStatus)
|
||||
scoped_ptr<LicenseKeys> license_keys_;
|
||||
|
||||
std::map<KeyId, CdmKeyStatus> keys_status_;
|
||||
// Device checks
|
||||
int64_t next_device_check_;
|
||||
uint32_t current_resolution_;
|
||||
CryptoSession* crypto_session_;
|
||||
|
||||
scoped_ptr<Clock> clock_;
|
||||
|
||||
|
||||
@@ -15,12 +15,13 @@ std::vector<uint8_t> a2b_hex(const std::string& label, const std::string& b);
|
||||
std::string a2bs_hex(const std::string& b);
|
||||
std::string b2a_hex(const std::vector<uint8_t>& b);
|
||||
std::string b2a_hex(const std::string& b);
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bin_input);
|
||||
std::vector<uint8_t> Base64Decode(const std::string& bin_input);
|
||||
std::string Base64SafeEncode(const std::vector<uint8_t>& bin_input);
|
||||
std::string Base64SafeEncodeNoPad(const std::vector<uint8_t>& bin_input);
|
||||
std::vector<uint8_t> Base64SafeDecode(const std::string& bin_input);
|
||||
std::string HexEncode(const uint8_t* bytes, unsigned size);
|
||||
std::string IntToString(int value);
|
||||
std::string UintToString(unsigned int value);
|
||||
int64_t htonll64(int64_t x);
|
||||
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
||||
|
||||
|
||||
@@ -80,8 +80,19 @@ static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4";
|
||||
static const std::string WEBM_VIDEO_MIME_TYPE = "video/webm";
|
||||
static const std::string WEBM_AUDIO_MIME_TYPE = "audio/webm";
|
||||
static const std::string CENC_INIT_DATA_FORMAT = "cenc";
|
||||
static const std::string HLS_INIT_DATA_FORMAT = "hls";
|
||||
static const std::string WEBM_INIT_DATA_FORMAT = "webm";
|
||||
|
||||
static const std::string HLS_KEYFORMAT_ATTRIBUTE = "KEYFORMAT";
|
||||
static const std::string HLS_KEYFORMAT_VERSIONS_ATTRIBUTE = "KEYFORMATVERSIONS";
|
||||
static const std::string HLS_KEYFORMAT_VERSION_VALUE_1 = "1";
|
||||
static const std::string HLS_METHOD_ATTRIBUTE = "METHOD";
|
||||
static const std::string HLS_METHOD_AES_128 = "AES-128";
|
||||
static const std::string HLS_METHOD_NONE = "NONE";
|
||||
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[] = "";
|
||||
} // namespace wvcdm
|
||||
|
||||
|
||||
@@ -149,9 +149,9 @@ enum CdmResponseType {
|
||||
RENEW_KEY_ERROR_1,
|
||||
RENEW_KEY_ERROR_2,
|
||||
LICENSE_RENEWAL_SIGNING_ERROR,
|
||||
RESTORE_OFFLINE_LICENSE_ERROR_1,
|
||||
UNUSED_4, /* previously RESTORE_OFFLINE_LICENSE_ERROR_1 */
|
||||
RESTORE_OFFLINE_LICENSE_ERROR_2,
|
||||
SESSION_INIT_ERROR_1,
|
||||
UNUSED_5, /* SESSION_INIT_ERROR_1 */
|
||||
SESSION_INIT_ERROR_2,
|
||||
SESSION_INIT_GET_KEYBOX_ERROR,
|
||||
SESSION_NOT_FOUND_1,
|
||||
@@ -169,7 +169,7 @@ enum CdmResponseType {
|
||||
SIGNATURE_NOT_FOUND,
|
||||
STORE_LICENSE_ERROR_1,
|
||||
STORE_LICENSE_ERROR_2,
|
||||
STORE_LICENSE_ERROR_3,
|
||||
UNUSED_6, /* previously STORE_LICENSE_ERROR_3 */
|
||||
STORE_USAGE_INFO_ERROR,
|
||||
UNPROVISION_ERROR_1,
|
||||
UNPROVISION_ERROR_2,
|
||||
@@ -213,6 +213,38 @@ enum CdmResponseType {
|
||||
SESSION_NOT_FOUND_11,
|
||||
LOAD_USAGE_INFO_FILE_ERROR,
|
||||
LOAD_USAGE_INFO_MISSING,
|
||||
SESSION_FILE_HANDLE_INIT_ERROR,
|
||||
INCORRECT_CRYPTO_MODE,
|
||||
INVALID_PARAMETERS_ENG_5,
|
||||
DECRYPT_ERROR,
|
||||
INSUFFICIENT_OUTPUT_PROTECTION,
|
||||
SESSION_NOT_FOUND_12,
|
||||
KEY_NOT_FOUND_1,
|
||||
KEY_NOT_FOUND_2,
|
||||
KEY_CONFLICT_1,
|
||||
INVALID_PARAMETERS_ENG_6,
|
||||
INVALID_PARAMETERS_ENG_7,
|
||||
INVALID_PARAMETERS_ENG_8,
|
||||
INVALID_PARAMETERS_ENG_9,
|
||||
INVALID_PARAMETERS_ENG_10,
|
||||
INVALID_PARAMETERS_ENG_11,
|
||||
INVALID_PARAMETERS_ENG_12,
|
||||
SESSION_NOT_FOUND_13,
|
||||
SESSION_NOT_FOUND_14,
|
||||
SESSION_NOT_FOUND_15,
|
||||
SESSION_NOT_FOUND_16,
|
||||
KEY_NOT_FOUND_3,
|
||||
KEY_NOT_FOUND_4,
|
||||
KEY_NOT_FOUND_5,
|
||||
KEY_NOT_FOUND_6,
|
||||
KEY_ERROR_1,
|
||||
KEY_ERROR_2,
|
||||
KEY_ERROR_3,
|
||||
KEY_ERROR_4,
|
||||
INVALID_PARAMETERS_ENG_13,
|
||||
INVALID_PARAMETERS_ENG_14,
|
||||
INVALID_PARAMETERS_ENG_15,
|
||||
INVALID_PARAMETERS_ENG_16,
|
||||
};
|
||||
|
||||
enum CdmKeyStatus {
|
||||
@@ -258,9 +290,89 @@ enum CdmCertificateType {
|
||||
kCertificateX509,
|
||||
};
|
||||
|
||||
enum CdmHlsMethod {
|
||||
kHlsMethodNone,
|
||||
kHlsMethodAes128,
|
||||
kHlsMethodSampleAes,
|
||||
};
|
||||
|
||||
enum CdmCipherMode {
|
||||
kCipherModeCtr,
|
||||
kCipherModeCbc,
|
||||
};
|
||||
|
||||
enum CdmEncryptionAlgorithm {
|
||||
kEncryptionAlgorithmUnknown,
|
||||
kEncryptionAlgorithmAesCbc128
|
||||
};
|
||||
|
||||
enum CdmSigningAlgorithm {
|
||||
kSigningAlgorithmUnknown,
|
||||
kSigningAlgorithmHmacSha256
|
||||
};
|
||||
|
||||
class CdmKeyAllowedUsage {
|
||||
public:
|
||||
CdmKeyAllowedUsage() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
bool Valid() const { return valid_; }
|
||||
void SetValid() { valid_ = true; }
|
||||
|
||||
void Clear() {
|
||||
decrypt_to_clear_buffer = false;
|
||||
decrypt_to_secure_buffer = false;
|
||||
generic_encrypt = false;
|
||||
generic_decrypt = false;
|
||||
generic_sign = false;
|
||||
generic_verify = false;
|
||||
valid_ = false;
|
||||
}
|
||||
|
||||
bool Equals(const CdmKeyAllowedUsage& other) {
|
||||
if (!valid_ || !other.Valid() ||
|
||||
decrypt_to_clear_buffer != other.decrypt_to_clear_buffer ||
|
||||
decrypt_to_secure_buffer != other.decrypt_to_secure_buffer ||
|
||||
generic_encrypt != other.generic_encrypt ||
|
||||
generic_decrypt != other.generic_decrypt ||
|
||||
generic_sign != other.generic_sign ||
|
||||
generic_verify != other.generic_verify) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool decrypt_to_clear_buffer;
|
||||
bool decrypt_to_secure_buffer;
|
||||
bool generic_encrypt;
|
||||
bool generic_decrypt;
|
||||
bool generic_sign;
|
||||
bool generic_verify;
|
||||
|
||||
private:
|
||||
bool valid_;
|
||||
};
|
||||
|
||||
// For schemes that do not use pattern encryption (cenc and cbc1), encrypt
|
||||
// and skip should be set to 0. For those that do (cens and cbcs), it is
|
||||
// recommended that encrypt+skip bytes sum to 10 and for cbcs that a 1:9
|
||||
// encrypt:skip ratio be used. See ISO/IEC DIS 23001-7, section 10.4.2 for
|
||||
// more information.
|
||||
struct CdmCencPatternEncryptionDescriptor {
|
||||
size_t encrypt_blocks; // number of 16 byte blocks to decrypt
|
||||
size_t skip_blocks; // number of 16 byte blocks to leave in clear
|
||||
size_t offset_blocks; // offset into the pattern for this call, in blocks
|
||||
CdmCencPatternEncryptionDescriptor()
|
||||
: encrypt_blocks(0),
|
||||
skip_blocks(0),
|
||||
offset_blocks(0) {}
|
||||
};
|
||||
|
||||
struct CdmDecryptionParameters {
|
||||
bool is_encrypted;
|
||||
bool is_secure;
|
||||
CdmCipherMode cipher_mode;
|
||||
const KeyId* key_id;
|
||||
const uint8_t* encrypt_buffer;
|
||||
size_t encrypt_length;
|
||||
@@ -271,9 +383,11 @@ struct CdmDecryptionParameters {
|
||||
size_t decrypt_buffer_offset;
|
||||
uint8_t subsample_flags;
|
||||
bool is_video;
|
||||
CdmCencPatternEncryptionDescriptor pattern_descriptor;
|
||||
CdmDecryptionParameters()
|
||||
: is_encrypted(true),
|
||||
is_secure(true),
|
||||
cipher_mode(kCipherModeCtr),
|
||||
key_id(NULL),
|
||||
encrypt_buffer(NULL),
|
||||
encrypt_length(0),
|
||||
@@ -290,6 +404,7 @@ struct CdmDecryptionParameters {
|
||||
size_t offset, void* decrypted_buffer)
|
||||
: is_encrypted(true),
|
||||
is_secure(true),
|
||||
cipher_mode(kCipherModeCtr),
|
||||
key_id(key),
|
||||
encrypt_buffer(encrypted_buffer),
|
||||
encrypt_length(encrypted_length),
|
||||
@@ -302,6 +417,12 @@ struct CdmDecryptionParameters {
|
||||
is_video(true) {}
|
||||
};
|
||||
|
||||
struct CdmKeyRequest {
|
||||
CdmKeyMessage message;
|
||||
CdmKeyRequestType type;
|
||||
std::string url;
|
||||
};
|
||||
|
||||
// forward class references
|
||||
class KeyMessage;
|
||||
class Request;
|
||||
|
||||
Reference in New Issue
Block a user