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
This commit is contained in:
Rahul Frias
2015-06-12 14:37:41 -07:00
parent a8328dd2f9
commit b33298a742
6 changed files with 38 additions and 11 deletions

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<int>(response.size()));
@@ -848,9 +850,10 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) {
EXPECT_EQ(0, static_cast<int>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
key_msg_ = key_msg1;
response = GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(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<int>(cert.size()));

View File

@@ -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,

View File

@@ -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;
}