File util, generic crypto, and key query
This CL merges several CLs from the widevine repo: http://go/wvgerrit/18012 Add support for querying allowed usage for key. http://go/wvgerrit/17971 Add per-origin storage. http://go/wvgerrit/18152 Add OEMCrypto's generic crypto operations to CDM. http://go/wvgerrit/17911 QueryKeyControlInfo => QueryOemCryptoSessionId Note: numbering in wv_cdm_types.h was added in this CL and will be back ported to wvgerrit in a future CL. Change-Id: Idb9e9a67e94f62f25dc16c5307f75a08b3430b64
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,26 +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,
|
||||
const std::string& origin,
|
||||
WvCdmEventListener* event_listener,
|
||||
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
|
||||
@@ -93,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
|
||||
@@ -147,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?
|
||||
@@ -170,7 +208,6 @@ class CdmEngine {
|
||||
// private methods
|
||||
CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
||||
CdmClientPropertySet* property_set,
|
||||
const std::string& origin,
|
||||
WvCdmEventListener* event_listener,
|
||||
const CdmSessionId* forced_session_id,
|
||||
CdmSessionId* session_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,24 +23,7 @@ class WvCdmEventListener;
|
||||
|
||||
class CdmSession {
|
||||
public:
|
||||
CdmSession(const std::string& origin)
|
||||
: initialized_(false),
|
||||
origin_(origin),
|
||||
crypto_session_(new CryptoSession),
|
||||
file_handle_(new DeviceFiles),
|
||||
license_received_(false),
|
||||
is_offline_(false),
|
||||
is_release_(false),
|
||||
is_temporary_(false),
|
||||
security_level_(kSecurityLevelUninitialized),
|
||||
requested_security_level_(kLevelDefault),
|
||||
is_initial_decryption_(true),
|
||||
has_decrypted_since_last_report_(false),
|
||||
is_initial_usage_update_(true),
|
||||
is_usage_update_needed_(false),
|
||||
mock_license_parser_in_use_(false),
|
||||
mock_policy_engine_in_use_(false) {}
|
||||
|
||||
CdmSession(FileSystem* file_system);
|
||||
virtual ~CdmSession();
|
||||
|
||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
|
||||
@@ -63,13 +47,17 @@ class CdmSession {
|
||||
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);
|
||||
@@ -131,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();
|
||||
@@ -150,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_;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -103,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();
|
||||
@@ -114,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_;
|
||||
@@ -130,7 +157,7 @@ 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_;
|
||||
|
||||
@@ -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,
|
||||
@@ -113,18 +111,11 @@ 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 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);
|
||||
@@ -135,7 +126,6 @@ class DeviceFiles {
|
||||
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 +143,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
|
||||
|
||||
139
libwvdrmengine/cdm/core/include/license_key_status.h
Normal file
139
libwvdrmengine/cdm/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_
|
||||
@@ -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_; }
|
||||
|
||||
@@ -90,6 +93,14 @@ class PolicyEngine {
|
||||
|
||||
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,
|
||||
@@ -120,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_;
|
||||
|
||||
@@ -154,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_;
|
||||
|
||||
|
||||
@@ -218,6 +218,33 @@ enum CdmResponseType {
|
||||
INVALID_PARAMETERS_ENG_5,
|
||||
DECRYPT_ERROR,
|
||||
INSUFFICIENT_OUTPUT_PROTECTION,
|
||||
SESSION_NOT_FOUND_12, /* 180 */
|
||||
KEY_NOT_FOUND_1,
|
||||
KEY_NOT_FOUND_2,
|
||||
KEY_CONFLICT_1,
|
||||
INVALID_PARAMETERS_ENG_6,
|
||||
INVALID_PARAMETERS_ENG_7, /* 185 */
|
||||
INVALID_PARAMETERS_ENG_8,
|
||||
INVALID_PARAMETERS_ENG_9,
|
||||
INVALID_PARAMETERS_ENG_10,
|
||||
INVALID_PARAMETERS_ENG_11, /* 190 */
|
||||
INVALID_PARAMETERS_ENG_12,
|
||||
SESSION_NOT_FOUND_13,
|
||||
SESSION_NOT_FOUND_14,
|
||||
SESSION_NOT_FOUND_15,
|
||||
SESSION_NOT_FOUND_16, /* 195 */
|
||||
KEY_NOT_FOUND_3,
|
||||
KEY_NOT_FOUND_4,
|
||||
KEY_NOT_FOUND_5,
|
||||
KEY_NOT_FOUND_6,
|
||||
KEY_ERROR_1, /* 200 */
|
||||
KEY_ERROR_2,
|
||||
KEY_ERROR_3,
|
||||
KEY_ERROR_4,
|
||||
INVALID_PARAMETERS_ENG_13,
|
||||
INVALID_PARAMETERS_ENG_14, /* 205 */
|
||||
INVALID_PARAMETERS_ENG_15,
|
||||
INVALID_PARAMETERS_ENG_16,
|
||||
};
|
||||
|
||||
enum CdmKeyStatus {
|
||||
@@ -274,6 +301,59 @@ enum CdmCipherMode {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user