From b33298a742f7821beee465cd1914a05014ed69a3 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Fri, 12 Jun 2015 14:37:41 -0700 Subject: [PATCH] Fix for concurrent provisioning attempts [ Merge from http://go/wvgerrit/14670 ] Concurrent provisioning attempts are declared successful if any one of them succeeds. Earlier only the successful ones were declared as such. b/21727698 Change-Id: I67dedca44790a4ae236e14f90a8fc91775273905 --- .../cdm/core/include/wv_cdm_types.h | 3 ++- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 22 +++++++++++++++++-- .../cdm/core/test/test_printers.cpp | 4 +++- .../cdm/test/request_license_test.cpp | 9 +++++--- libwvdrmengine/include/WVErrors.h | 5 +++-- libwvdrmengine/include/mapErrors-inl.h | 6 +++-- 6 files changed, 38 insertions(+), 11 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 47714cb5..81d0ec4a 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -83,7 +83,7 @@ enum CdmResponseType { EMPTY_LICENSE_REQUEST, EMPTY_LICENSE_RESPONSE_1, EMPTY_LICENSE_RESPONSE_2, - EMPTY_PROVISIONING_CERTIFICATE, + EMPTY_PROVISIONING_CERTIFICATE_1, EMPTY_PROVISIONING_RESPONSE, EMPTY_SESSION_ID, GENERATE_DERIVED_KEYS_ERROR, @@ -186,6 +186,7 @@ enum CdmResponseType { CLIENT_ID_RSA_INIT_ERROR, CLIENT_ID_RSA_ENCRYPT_ERROR, INVALID_QUERY_STATUS, + EMPTY_PROVISIONING_CERTIFICATE_2, }; enum CdmKeyStatus { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 3ff1728a..d761eae8 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -566,8 +566,26 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( return INVALID_PROVISIONING_PARAMETERS_2; } if (NULL == cert_provisioning_.get()) { - LOGE("CdmEngine::HandleProvisioningResponse: provisioning object missing."); - return EMPTY_PROVISIONING_CERTIFICATE; + // Certificate provisioning object has been released. Check if a concurrent + // provisioning attempt has succeeded before declaring failure. + CryptoSession crypto_session; + CdmResponseType status = + crypto_session.Open(cert_provisioning_requested_security_level_); + if (NO_ERROR != status) { + LOGE( + "CdmEngine::HandleProvisioningResponse: provisioning object " + "missing and crypto session open failed."); + return EMPTY_PROVISIONING_CERTIFICATE_2; + } + CdmSecurityLevel security_level = crypto_session.GetSecurityLevel(); + if (!IsProvisioned(security_level, origin)) { + LOGE( + "CdmEngine::HandleProvisioningResponse: provisioning object " + "missing."); + return EMPTY_PROVISIONING_CERTIFICATE_1; + } + + return NO_ERROR; } CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( origin, response, cert, wrapped_key); diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 7badaff3..278945e0 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -100,7 +100,7 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case EMPTY_LICENSE_RESPONSE_2: *os << "EMPTY_LICENSE_RESPONSE_2"; break; - case EMPTY_PROVISIONING_CERTIFICATE: *os << "EMPTY_PROVISIONING_CERTIFICATE"; + case EMPTY_PROVISIONING_CERTIFICATE_1: *os << "EMPTY_PROVISIONING_CERTIFICATE_1"; break; case EMPTY_PROVISIONING_RESPONSE: *os << "EMPTY_PROVISIONING_RESPONSE"; break; @@ -289,6 +289,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case USAGE_INFO_NOT_FOUND: *os << "USAGE_INFO_NOT_FOUND"; break; + case EMPTY_PROVISIONING_CERTIFICATE_2: *os << "EMPTY_PROVISIONING_CERTIFICATE_2"; + break; default: *os << "Unknown CdmResponseType"; break; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index bfc2420e..8e5057aa 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -829,17 +829,19 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) { std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; + std::string key_msg1, key_msg2; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg_, &provisioning_server_url)); + &key_msg1, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg_, &provisioning_server_url)); + &key_msg2, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); + key_msg_ = key_msg2; std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); @@ -848,9 +850,10 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) { EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); + key_msg_ = key_msg1; response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); - EXPECT_EQ(wvcdm::EMPTY_PROVISIONING_CERTIFICATE, + EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert, &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 480fac97..f0892dc9 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -57,7 +57,7 @@ enum { kEmptyLicenseRequest = ERROR_DRM_VENDOR_MIN + 41, kEmptyLicenseResponse1 = ERROR_DRM_VENDOR_MIN + 42, kEmptyLicenseResponse2 = ERROR_DRM_VENDOR_MIN + 43, - kEmptyProvisioningCertificate = ERROR_DRM_VENDOR_MIN + 44, + kEmptyProvisioningCertificate1 = ERROR_DRM_VENDOR_MIN + 44, kEmptyProvisioningResponse = ERROR_DRM_VENDOR_MIN + 45, kEmptySessionId = ERROR_DRM_VENDOR_MIN + 46, kGenerateDerivedKeysError = ERROR_DRM_VENDOR_MIN + 47, @@ -161,7 +161,8 @@ enum { kClientIdRsaInitError = ERROR_DRM_VENDOR_MIN + 145, kClientIdRsaEncryptError = ERROR_DRM_VENDOR_MIN + 146, kInvalidQueryStatus = ERROR_DRM_VENDOR_MIN + 147, - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 147, + kEmptyProvisioningCertificate2 = ERROR_DRM_VENDOR_MIN + 148, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 148, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index cd0479ac..c63d4944 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -101,8 +101,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kEmptyLicenseResponse1; case wvcdm::EMPTY_LICENSE_RESPONSE_2: return kEmptyLicenseResponse2; - case wvcdm::EMPTY_PROVISIONING_CERTIFICATE: - return kEmptyProvisioningCertificate; + case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_1: + return kEmptyProvisioningCertificate1; case wvcdm::EMPTY_PROVISIONING_RESPONSE: return kEmptyProvisioningResponse; case wvcdm::EMPTY_SESSION_ID: @@ -311,6 +311,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kErrorCDMGeneric; case wvcdm::INVALID_QUERY_STATUS: return kInvalidQueryStatus; + case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_2: + return kEmptyProvisioningCertificate2; case wvcdm::UNKNOWN_ERROR: return android::ERROR_DRM_UNKNOWN; }