Bug: 8770327
1. Allow provisioning retries
Allow multiple provisioning request messages to be generated without
requiring an equal number of HandleProvisioningResponse's. This is to
allow for lost messages.
2. Properly deletes cdm and crypto sessions created for cert provisioning.
The CleanupProvisioningSession() has not been deleting the cdm and crypto sessions
created for certificate provisioning properly. The lives of these sessions are
short and therefore, not added to the CdmSessionMap. We need to explicitly delete
these objects when error occurs or when we are done with provisioning.
3. Fixes provisioning responses that contain multiple chunks.
When we make multiple provisioning requests during testing, Apiary
sends response that contains more than one chunk. The test app.
needs to parse the response and concatenates the chunk data.
Otherwise, the size for each chunk is treated as base64 encoded data,
which will generate error when we try to deserialize the response
message.
Merge of https://widevine-internal-review.googlesource.com/#/c/5451/
from the Widevine CDM repository
Change-Id: I5b0ed982849c12628a3949f8d51515fcf6ce5a5f
137 lines
4.9 KiB
C++
137 lines
4.9 KiB
C++
// Copyright 2013 Google Inc. All Rights Reserved.
|
|
|
|
#ifndef CDM_BASE_CDM_ENGINE_H_
|
|
#define CDM_BASE_CDM_ENGINE_H_
|
|
|
|
#include "crypto_session.h"
|
|
#include "timer.h"
|
|
#include "wv_cdm_types.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
class CdmSession;
|
|
class CryptoEngine;
|
|
class WvCdmEventListener;
|
|
|
|
typedef std::map<CdmSessionId, CdmSession*> CdmSessionMap;
|
|
|
|
class CdmEngine : public TimerHandler {
|
|
public:
|
|
CdmEngine();
|
|
~CdmEngine();
|
|
|
|
// Session related methods
|
|
CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
|
CdmSessionId* session_id);
|
|
CdmResponseType CloseSession(const CdmSessionId& session_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 CdmInitData& init_data,
|
|
const CdmLicenseType license_type,
|
|
CdmAppParameterMap& app_parameters,
|
|
CdmKeyMessage* key_request,
|
|
std::string* server_url);
|
|
|
|
// Accept license response and extract key info.
|
|
CdmResponseType AddKey(const CdmSessionId& session_id,
|
|
const CdmKeyResponse& key_data);
|
|
|
|
// Cancel session and unload keys.
|
|
CdmResponseType CancelKeyRequest(const CdmSessionId& session_id,
|
|
bool is_key_system_present,
|
|
const CdmKeySystem& key_system);
|
|
|
|
// Construct valid renewal request for the current session keys.
|
|
CdmResponseType GenerateRenewalRequest(const CdmSessionId& session_id,
|
|
CdmKeyMessage* key_request,
|
|
std::string* server_url);
|
|
|
|
// Accept renewal response and update key info.
|
|
CdmResponseType RenewKey(const CdmSessionId& session_id,
|
|
const CdmKeyResponse& key_data);
|
|
|
|
// Query system information
|
|
CdmResponseType QueryStatus(CdmQueryMap* info);
|
|
|
|
// Query license information
|
|
CdmResponseType QueryKeyStatus(const CdmSessionId& session_id,
|
|
CdmQueryMap* key_info);
|
|
|
|
// Query seesion control information
|
|
CdmResponseType QueryKeyControlInfo(const CdmSessionId& session_id,
|
|
CdmQueryMap* key_info);
|
|
|
|
// Provisioning related methods
|
|
CdmResponseType GetProvisioningRequest(CdmProvisioningRequest* request,
|
|
std::string* default_url);
|
|
|
|
CdmResponseType HandleProvisioningResponse(CdmProvisioningResponse& response);
|
|
|
|
// Secure stop related methods
|
|
CdmResponseType GetSecureStops(CdmSecureStops* secure_stops);
|
|
CdmResponseType ReleaseSecureStops(const CdmSecureStopReleaseMessage& message);
|
|
|
|
// Decryption and key related methods
|
|
// Accept encrypted buffer and return decrypted data.
|
|
CdmResponseType Decrypt(const CdmSessionId& session_id,
|
|
bool is_encrypted,
|
|
bool is_secure,
|
|
const KeyId& key_id,
|
|
const uint8_t* encrypt_buffer,
|
|
size_t encrypt_length,
|
|
const std::vector<uint8_t>& iv,
|
|
size_t block_offset,
|
|
void* decrypt_buffer,
|
|
size_t decrypt_buffer_offset,
|
|
bool is_video);
|
|
|
|
// Is the key known to any session?
|
|
bool IsKeyValid(const KeyId& key_id);
|
|
|
|
// Event listener related methods
|
|
bool AttachEventListener(const CdmSessionId& session_id,
|
|
WvCdmEventListener* listener);
|
|
bool DetachEventListener(const CdmSessionId& session_id,
|
|
WvCdmEventListener* listener);
|
|
|
|
// Parse a blob of multiple concatenated PSSH atoms to extract the first
|
|
// widevine pssh
|
|
static bool ExtractWidevinePssh(const CdmInitData& init_data,
|
|
CdmInitData* output);
|
|
private:
|
|
// private methods
|
|
// Cancel all sessions
|
|
bool CancelSessions();
|
|
void CleanupProvisioningSession();
|
|
void ComposeJsonRequestAsQueryString(const std::string& message,
|
|
CdmProvisioningRequest* request);
|
|
|
|
bool ParseJsonResponse(const CdmProvisioningResponse& json_str,
|
|
const std::string& start_substr,
|
|
const std::string& end_substr,
|
|
std::string* result);
|
|
bool ValidateKeySystem(const CdmKeySystem& key_system);
|
|
|
|
// timer related methods to drive policy decisions
|
|
void EnablePolicyTimer();
|
|
void DisablePolicyTimer();
|
|
virtual void OnTimerEvent();
|
|
|
|
// instance variables
|
|
CdmSession* provisioning_session_;
|
|
CdmSessionMap sessions_;
|
|
|
|
// policy timer
|
|
Timer policy_timer_;
|
|
|
|
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
|
|
};
|
|
|
|
} // namespace wvcdm
|
|
|
|
#endif // CDM_BASE_CDM_ENGINE_H_
|