diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 6159fafe..8766de81 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -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 crypto_session_; CdmCertificateType cert_type_; std::unique_ptr service_certificate_; diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index fbff6d49..8357232a 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -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 (SignedDrmCertificate). const std::string& device_cert_data = @@ -520,4 +530,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