Support Offline Licenses

Bug: 8621588

Merge of the following CLs from the Widevine CDM repository:

https://widevine-internal-review.googlesource.com/#/c/5602/
https://widevine-internal-review.googlesource.com/#/c/5431/
https://widevine-internal-review.googlesource.com/#/c/5660/

Change-Id: If37940e2535e1a1eca95e4394d8cf9bf689e9c3a
This commit is contained in:
Jeff Tinker
2013-05-15 19:23:36 -07:00
parent 898d870126
commit 1b295f4c81
30 changed files with 1647 additions and 471 deletions

View File

@@ -14,6 +14,7 @@ class CryptoEngine;
class WvCdmEventListener;
typedef std::map<CdmSessionId, CdmSession*> CdmSessionMap;
typedef std::map<CdmKeySetId, CdmSessionId> CdmReleaseKeySetMap;
class CdmEngine : public TimerHandler {
public:
@@ -24,12 +25,13 @@ class CdmEngine : public TimerHandler {
CdmResponseType OpenSession(const CdmKeySystem& key_system,
CdmSessionId* session_id);
CdmResponseType CloseSession(const CdmSessionId& session_id);
CdmResponseType OpenKeySetSession(const CdmKeySetId& key_set_id);
CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
// License related methods
// Construct a valid license request
CdmResponseType GenerateKeyRequest(const CdmSessionId& session_id,
bool is_key_system_present,
const CdmKeySystem& key_system,
const CdmKeySetId& key_set_id,
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
@@ -38,12 +40,14 @@ class CdmEngine : public TimerHandler {
// Accept license response and extract key info.
CdmResponseType AddKey(const CdmSessionId& session_id,
const CdmKeyResponse& key_data);
const CdmKeyResponse& key_data,
CdmKeySetId& key_set_id);
CdmResponseType RestoreKey(const CdmSessionId& session_id,
const CdmKeySetId& key_set_id);
// Cancel session and unload keys.
CdmResponseType CancelKeyRequest(const CdmSessionId& session_id,
bool is_key_system_present,
const CdmKeySystem& key_system);
CdmResponseType CancelKeyRequest(const CdmSessionId& session_id);
// Construct valid renewal request for the current session keys.
CdmResponseType GenerateRenewalRequest(const CdmSessionId& session_id,
@@ -121,9 +125,12 @@ class CdmEngine : public TimerHandler {
void DisablePolicyTimer();
virtual void OnTimerEvent();
virtual void OnKeyReleaseEvent(CdmKeySetId key_set_id);
// instance variables
CdmSession* provisioning_session_;
CdmSessionMap sessions_;
CdmReleaseKeySetMap release_key_sets_;
// policy timer
Timer policy_timer_;

View File

@@ -19,14 +19,16 @@ namespace wvcdm {
class CdmSession {
public:
CdmSession() : session_id_(GenerateSessionId()), license_received_(false),
reinitialize_session_(false) {}
reinitialize_session_(false), license_type_(kLicenseTypeStreaming) {}
~CdmSession() {}
CdmResponseType Init();
CdmResponseType ReInit();
bool DestroySession();
CdmResponseType RestoreOfflineSession(const CdmKeySetId& key_set_id,
const CdmLicenseType license_type);
void set_key_system(const CdmKeySystem& ksystem) { key_system_ = ksystem; }
const CdmKeySystem& key_system() { return key_system_; }
@@ -37,12 +39,13 @@ class CdmSession {
CdmResponseType GenerateKeyRequest(const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
const CdmAppParameterMap& app_parameters,
CdmKeyMessage* key_request,
std::string* server_url);
// AddKey() - Accept license response and extract key info.
CdmResponseType AddKey(const CdmKeyResponse& key_response);
CdmResponseType AddKey(const CdmKeyResponse& key_response,
CdmKeySetId* key_set_id);
// CancelKeyRequest() - Cancel session.
CdmResponseType CancelKeyRequest();
@@ -74,19 +77,31 @@ class CdmSession {
// RenewKey() - Accept renewal response and update key info.
CdmResponseType RenewKey(const CdmKeyResponse& key_response);
// License release
// GenerateReleaseRequest() - Construct valid release request for the current
// session keys.
CdmResponseType GenerateReleaseRequest(CdmKeyMessage* key_request,
std::string* server_url);
// RenewKey() - Accept renewal response and update key info.
CdmResponseType ReleaseKey(const CdmKeyResponse& key_response);
bool IsKeyValid(const KeyId& key_id);
bool AttachEventListener(WvCdmEventListener* listener);
bool DetachEventListener(WvCdmEventListener* listener);
void OnTimerEvent();
void OnKeyReleaseEvent(CdmKeySetId key_set_id);
private:
// Generate unique ID for each new session.
CdmSessionId GenerateSessionId();
CdmKeySetId GenerateKeySetId(CdmInitData& pssh_data);
bool LoadDeviceCertificate(std::string* cert, std::string* wrapped_key);
bool StoreLicense(bool active);
// instance variables
const CdmSessionId session_id_;
@@ -97,6 +112,19 @@ class CdmSession {
bool license_received_;
bool reinitialize_session_;
CdmLicenseType license_type_;
// license type offline related information
CdmInitData offline_pssh_data_;
CdmKeyMessage offline_key_request_;
CdmKeyResponse offline_key_response_;
CdmKeyMessage offline_key_renewal_request_;
CdmKeyResponse offline_key_renewal_response_;
std::string offline_release_server_url_;
// license type release and offline related information
CdmKeySetId key_set_id_;
KeyId key_id_;
// Used for certificate based licensing

View File

@@ -9,15 +9,41 @@ namespace wvcdm {
class DeviceFiles {
public:
typedef enum {
kLicenseStateActive,
kLicenseStateReleasing,
kLicenseStateUnknown,
} LicenseState;
static bool StoreCertificate(const std::string& certificate,
const std::string& wrapped_private_key);
static bool RetrieveCertificate(std::string* certificate,
std::string* wrapped_private_key);
static bool StoreLicense(const std::string& key_set_id,
const LicenseState state,
const CdmInitData& pssh_data,
const CdmKeyMessage& key_request,
const CdmKeyResponse& key_response,
const CdmKeyMessage& key_renewal_request,
const CdmKeyResponse& key_renewal_response,
const std::string& release_server_url);
static bool RetrieveLicense(const std::string& key_set_id,
LicenseState* state,
CdmInitData* pssh_data,
CdmKeyMessage* key_request,
CdmKeyResponse* key_response,
CdmKeyMessage* key_renewal_request,
CdmKeyResponse* key_renewal_response,
std::string* release_server_url);
static bool DeleteLicense(const std::string& key_set_id);
static bool LicenseExists(const std::string& key_set_id);
static std::string GetBasePath(const char* dir);
static const char* kBasePath;
static const char* kPathDelimiter;
static const char* kDeviceCertificateFileName;
static const char* kLicenseFileNameExt;
private:
static bool Hash(const std::string& data, std::string* hash);

View File

@@ -26,15 +26,21 @@ class CdmLicense {
bool PrepareKeyRequest(const CdmInitData& pssh_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
const CdmAppParameterMap& app_parameters,
CdmKeyMessage* signed_request,
std::string* server_url);
bool PrepareKeyRenewalRequest(CdmKeyMessage* signed_request,
std::string* server_url);
bool PrepareKeyUpdateRequest(bool is_renewal,
CdmKeyMessage* signed_request,
std::string* server_url);
CdmResponseType HandleKeyResponse(const CdmKeyResponse& license_response);
CdmResponseType HandleKeyRenewalResponse(
CdmResponseType HandleKeyUpdateResponse(
bool is_renewal,
const CdmKeyResponse& license_response);
bool RestoreOfflineLicense(CdmKeyMessage& license_request,
CdmKeyResponse& license_response,
CdmKeyResponse& license_renewal_response);
private:
CdmResponseType HandleKeyErrorResponse(const SignedMessage& signed_message);

View File

@@ -5,6 +5,8 @@
#include <string>
#include "wv_cdm_types.h"
namespace wvcdm {
static const size_t KEY_CONTROL_SIZE = 16;
// TODO(kqyang): Key ID size is not fixed in spec, but conventionally we
@@ -16,6 +18,11 @@ static const size_t KEY_PAD_SIZE = 16;
static const size_t KEY_SIZE = 16;
static const size_t MAC_KEY_SIZE = 32;
static const std::string SESSION_ID_PREFIX = "sid";
static const std::string KEY_SET_ID_PREFIX = "ksid";
static const CdmKeySystem KEY_SYSTEM = "com.widevine";
// define query keys, values here
static const std::string QUERY_KEY_LICENSE_TYPE = "LicenseType";
// "Streaming", "Offline"

View File

@@ -11,15 +11,22 @@ namespace wvcdm {
// The caller of the CDM API must provide an implementation for onEvent
// and signal its intent by using the Attach/DetachEventListener methods
// in the WvContentDecryptionModule class.
// The listener may also specify, when the instance is created, whether to be
// notified about events for a particular session or all sessions.
class WvCdmEventListener {
public:
WvCdmEventListener() {}
WvCdmEventListener(CdmSessionId& session_id) : session_id_(session_id) {}
virtual ~WvCdmEventListener() {}
virtual void onEvent(const CdmSessionId& session_id,
CdmEventType cdm_event) = 0;
virtual CdmSessionId session_id() { return session_id_; }
private:
CdmSessionId session_id_;
CORE_DISALLOW_COPY_AND_ASSIGN(WvCdmEventListener);
};

View File

@@ -16,6 +16,7 @@ typedef std::string CdmKeyMessage;
typedef std::string CdmKeyResponse;
typedef std::string KeyId;
typedef std::string CdmSessionId;
typedef std::string CdmKeySetId;
typedef std::string RequestId;
typedef uint32_t CryptoResult;
typedef uint32_t CryptoSessionId;
@@ -50,7 +51,8 @@ enum CdmEventType {
enum CdmLicenseType {
kLicenseTypeOffline,
kLicenseTypeStreaming
kLicenseTypeStreaming,
kLicenseTypeRelease
};
// forward class references