Release crypto resources when provisioning fails

[ Merge of http://go/wvgerrit/119564 ]

This closes a crypto session when the provisioning request fails. We
cannot be as eager when handling the response as the app may have
multiple simultaneous provisioning attempts in flight. In this case
all provisioning responses except the one associated with the last
request will fail. If we close the session on error, even the one
associated with the last request may fail.

Bug: 180986725
Test: WV unit/integration tests
Change-Id: Ic3d33a374e442b5bf040e345bed829d91c4ef1dc
This commit is contained in:
Rahul Frias
2021-02-23 12:46:43 -08:00
parent d40302f3e3
commit 83a85430e3
2 changed files with 37 additions and 2 deletions

View File

@@ -64,6 +64,12 @@ class CertificateProvisioning {
const std::string& provisioning_response, std::string* result);
private:
CdmResponseType GetProvisioningRequestInternal(
SecurityLevel requested_security_level, CdmCertificateType cert_type,
const std::string& cert_authority, const std::string& origin,
const std::string& spoid, CdmProvisioningRequest* request,
std::string* default_url);
CdmResponseType SetSpoidParameter(
const std::string& origin, const std::string& spoid,
video_widevine::ProvisioningRequest* request);
@@ -71,6 +77,15 @@ class CertificateProvisioning {
video_widevine::SignedProvisioningMessage::ProvisioningType
GetProvisioningType();
// Closes crypto session if one is open. Avoid calling this method when
// processing a response. Multiple provisioning responses might be
// simultaneously in flight. Only the response associated with the last
// provisioning request can be processed. All the other responses will
// fail. If the session is closed when these responses fail, even the one
// associated with the last provisioning request may fail.
CdmResponseType CloseSessionOnError(CdmResponseType status);
void CloseSession();
std::unique_ptr<CryptoSession> crypto_session_;
CdmCertificateType cert_type_;
std::unique_ptr<ServiceCertificate> service_certificate_;

View File

@@ -194,6 +194,16 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
const std::string& cert_authority, const std::string& origin,
const std::string& spoid, CdmProvisioningRequest* request,
std::string* default_url) {
return CloseSessionOnError(GetProvisioningRequestInternal(
requested_security_level, cert_type, cert_authority, origin, spoid,
request, default_url));
}
CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
SecurityLevel requested_security_level, CdmCertificateType cert_type,
const std::string& cert_authority, const std::string& origin,
const std::string& spoid, CdmProvisioningRequest* request,
std::string* default_url) {
if (!request || !default_url) {
LOGE("Output parameter |%s| is not provided",
request ? "default_url" : "request");
@@ -202,7 +212,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
default_url->assign(kProvisioningServerUrl);
if (crypto_session_->IsOpen()) crypto_session_->Close();
CloseSession();
CdmResponseType status = crypto_session_->Open(requested_security_level);
if (NO_ERROR != status) {
LOGE("Failed to create a crypto session: status = %d",
@@ -423,7 +433,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
}
const CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel();
crypto_session_->Close();
CloseSession();
// This is the entire certificate (SignedDrmDeviceCertificate).
const std::string& device_cert_data =
@@ -521,4 +531,14 @@ bool CertificateProvisioning::ExtractDeviceInfo(
return true;
}
void CertificateProvisioning::CloseSession() {
if (crypto_session_->IsOpen()) crypto_session_->Close();
}
CdmResponseType CertificateProvisioning::CloseSessionOnError(
CdmResponseType status) {
if (status != NO_ERROR) CloseSession();
return status;
}
} // namespace wvcdm