Squashed commit of 3 CLs related to provisioning retries

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
This commit is contained in:
Jeff Tinker
2013-05-06 23:04:34 -07:00
parent d0f1784615
commit 7aa99d4a36
3 changed files with 150 additions and 36 deletions

View File

@@ -3,6 +3,7 @@
#ifndef CDM_BASE_CDM_ENGINE_H_
#define CDM_BASE_CDM_ENGINE_H_
#include "crypto_session.h"
#include "timer.h"
#include "wv_cdm_types.h"
@@ -105,7 +106,7 @@ class CdmEngine : public TimerHandler {
// private methods
// Cancel all sessions
bool CancelSessions();
void CleanupProvisioningSession(const CdmSessionId& cdm_session_id);
void CleanupProvisioningSession();
void ComposeJsonRequestAsQueryString(const std::string& message,
CdmProvisioningRequest* request);

View File

@@ -327,9 +327,29 @@ CdmResponseType CdmEngine::QueryKeyControlInfo(
return iter->second->QueryKeyControlInfo(key_info);
}
void CdmEngine::CleanupProvisioningSession(const CdmSessionId& cdm_session_id) {
CloseSession(cdm_session_id);
provisioning_session_ = NULL;
/*
* The certificate provisioning process creates a cdm and a crypto session.
* 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.
*/
void CdmEngine::CleanupProvisioningSession() {
if (provisioning_session_) {
CryptoEngine* crypto_engine = CryptoEngine::GetInstance();
if (crypto_engine) {
CdmSessionId cdm_session_id = provisioning_session_->session_id();
CryptoSession* crypto_session =
crypto_engine->FindSession(cdm_session_id);
if (crypto_session) {
LOGV("delete crypto session for id=%s", cdm_session_id.c_str());
delete crypto_session;
} else {
LOGE("CleanupProvisioningSession: cannot find crypto_session");
}
}
delete provisioning_session_;
provisioning_session_ = NULL;
}
}
/*
@@ -382,8 +402,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
default_url->assign(kDefaultProvisioningServerUrl);
if (provisioning_session_) {
LOGE("GetProvisioningRequest: duplicate provisioning request?");
return UNKNOWN_ERROR;
CleanupProvisioningSession();
}
//
@@ -418,7 +437,10 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
return UNKNOWN_ERROR;
}
// TODO(edwinwong): replace this cdm session pointer with crypto session
// pointer if feasible
provisioning_session_ = cdm_session;
LOGV("provisioning session id=%s", cdm_session_id.c_str());
//
//---------------------------------------------------------------------------
@@ -430,7 +452,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
std::string token;
if (!crypto_engine->GetToken(&token)) {
LOGE("GetProvisioningRequest: fails to get token");
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
client_id->set_token(token);
@@ -438,8 +460,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
uint32_t nonce;
if (!crypto_session->GenerateNonce(&nonce)) {
LOGE("GetProvisioningRequest: fails to generate a nonce");
crypto_engine->DestroySession(cdm_session_id);
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
@@ -456,12 +477,12 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
if (!crypto_session->PrepareRequest(serialized_message,
&request_signature, true)) {
request->clear();
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
if (request_signature.empty()) {
request->clear();
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
@@ -568,14 +589,14 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
SignedProvisioningMessage signed_response;
if (!signed_response.ParseFromString(serialized_signed_response)) {
LOGE("Fails to parse signed serialized response");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
if (!signed_response.has_signature() || !signed_response.has_message()) {
LOGE("Invalid response - signature or message not found");
CleanupProvisioningSession(cdm_session_id);
return UNKNOWN_ERROR;
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
const std::string& signed_message = signed_response.message();
@@ -583,13 +604,13 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
if (!provisioning_response.ParseFromString(signed_message)) {
LOGE("Fails to parse signed message");
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
if (!provisioning_response.has_device_rsa_key()) {
LOGE("Invalid response - key not found");
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
@@ -607,7 +628,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
rsa_key_iv,
&wrapped_rsa_key)) {
LOGE("HandleProvisioningResponse: RewrapDeviceRSAKey fails");
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return UNKNOWN_ERROR;
}
@@ -616,10 +637,9 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
//
//---------------------------------------------------------------------------
// Closes the cdm session.
// Deletes cdm and crypto sessions created for provisioning.
//
CleanupProvisioningSession(cdm_session_id);
CleanupProvisioningSession();
return NO_ERROR;
}