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_REQUEST,
EMPTY_LICENSE_RESPONSE_1, EMPTY_LICENSE_RESPONSE_1,
EMPTY_LICENSE_RESPONSE_2, EMPTY_LICENSE_RESPONSE_2,
EMPTY_PROVISIONING_CERTIFICATE, EMPTY_PROVISIONING_CERTIFICATE_1,
EMPTY_PROVISIONING_RESPONSE, EMPTY_PROVISIONING_RESPONSE,
EMPTY_SESSION_ID, EMPTY_SESSION_ID,
GENERATE_DERIVED_KEYS_ERROR, GENERATE_DERIVED_KEYS_ERROR,
@@ -186,6 +186,7 @@ enum CdmResponseType {
CLIENT_ID_RSA_INIT_ERROR, CLIENT_ID_RSA_INIT_ERROR,
CLIENT_ID_RSA_ENCRYPT_ERROR, CLIENT_ID_RSA_ENCRYPT_ERROR,
INVALID_QUERY_STATUS, INVALID_QUERY_STATUS,
EMPTY_PROVISIONING_CERTIFICATE_2,
}; };
enum CdmKeyStatus { enum CdmKeyStatus {

View File

@@ -566,8 +566,26 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
return INVALID_PROVISIONING_PARAMETERS_2; return INVALID_PROVISIONING_PARAMETERS_2;
} }
if (NULL == cert_provisioning_.get()) { if (NULL == cert_provisioning_.get()) {
LOGE("CdmEngine::HandleProvisioningResponse: provisioning object missing."); // Certificate provisioning object has been released. Check if a concurrent
return EMPTY_PROVISIONING_CERTIFICATE; // 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( CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse(
origin, response, cert, wrapped_key); origin, response, cert, wrapped_key);

View File

@@ -100,7 +100,7 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
break; break;
case EMPTY_LICENSE_RESPONSE_2: *os << "EMPTY_LICENSE_RESPONSE_2"; case EMPTY_LICENSE_RESPONSE_2: *os << "EMPTY_LICENSE_RESPONSE_2";
break; break;
case EMPTY_PROVISIONING_CERTIFICATE: *os << "EMPTY_PROVISIONING_CERTIFICATE"; case EMPTY_PROVISIONING_CERTIFICATE_1: *os << "EMPTY_PROVISIONING_CERTIFICATE_1";
break; break;
case EMPTY_PROVISIONING_RESPONSE: *os << "EMPTY_PROVISIONING_RESPONSE"; case EMPTY_PROVISIONING_RESPONSE: *os << "EMPTY_PROVISIONING_RESPONSE";
break; break;
@@ -289,6 +289,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
break; break;
case USAGE_INFO_NOT_FOUND: *os << "USAGE_INFO_NOT_FOUND"; case USAGE_INFO_NOT_FOUND: *os << "USAGE_INFO_NOT_FOUND";
break; break;
case EMPTY_PROVISIONING_CERTIFICATE_2: *os << "EMPTY_PROVISIONING_CERTIFICATE_2";
break;
default: default:
*os << "Unknown CdmResponseType"; *os << "Unknown CdmResponseType";
break; break;

View File

@@ -829,17 +829,19 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) {
std::string provisioning_server_url; std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine; CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key; std::string cert_authority, cert, wrapped_key;
std::string key_msg1, key_msg2;
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, EMPTY_ORIGIN, 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(provisioning_server_url, g_config->provisioning_server_url());
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest(
cert_type, cert_authority, EMPTY_ORIGIN, 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()); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
key_msg_ = key_msg2;
std::string response = std::string response =
GetCertRequestResponse(g_config->provisioning_server_url()); GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); 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>(cert.size()));
EXPECT_EQ(0, static_cast<int>(wrapped_key.size())); EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
key_msg_ = key_msg1;
response = GetCertRequestResponse(g_config->provisioning_server_url()); response = GetCertRequestResponse(g_config->provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size())); 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, decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
&wrapped_key)); &wrapped_key));
EXPECT_EQ(0, static_cast<int>(cert.size())); EXPECT_EQ(0, static_cast<int>(cert.size()));

View File

@@ -57,7 +57,7 @@ enum {
kEmptyLicenseRequest = ERROR_DRM_VENDOR_MIN + 41, kEmptyLicenseRequest = ERROR_DRM_VENDOR_MIN + 41,
kEmptyLicenseResponse1 = ERROR_DRM_VENDOR_MIN + 42, kEmptyLicenseResponse1 = ERROR_DRM_VENDOR_MIN + 42,
kEmptyLicenseResponse2 = ERROR_DRM_VENDOR_MIN + 43, kEmptyLicenseResponse2 = ERROR_DRM_VENDOR_MIN + 43,
kEmptyProvisioningCertificate = ERROR_DRM_VENDOR_MIN + 44, kEmptyProvisioningCertificate1 = ERROR_DRM_VENDOR_MIN + 44,
kEmptyProvisioningResponse = ERROR_DRM_VENDOR_MIN + 45, kEmptyProvisioningResponse = ERROR_DRM_VENDOR_MIN + 45,
kEmptySessionId = ERROR_DRM_VENDOR_MIN + 46, kEmptySessionId = ERROR_DRM_VENDOR_MIN + 46,
kGenerateDerivedKeysError = ERROR_DRM_VENDOR_MIN + 47, kGenerateDerivedKeysError = ERROR_DRM_VENDOR_MIN + 47,
@@ -161,7 +161,8 @@ enum {
kClientIdRsaInitError = ERROR_DRM_VENDOR_MIN + 145, kClientIdRsaInitError = ERROR_DRM_VENDOR_MIN + 145,
kClientIdRsaEncryptError = ERROR_DRM_VENDOR_MIN + 146, kClientIdRsaEncryptError = ERROR_DRM_VENDOR_MIN + 146,
kInvalidQueryStatus = ERROR_DRM_VENDOR_MIN + 147, 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 // Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX, kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -101,8 +101,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kEmptyLicenseResponse1; return kEmptyLicenseResponse1;
case wvcdm::EMPTY_LICENSE_RESPONSE_2: case wvcdm::EMPTY_LICENSE_RESPONSE_2:
return kEmptyLicenseResponse2; return kEmptyLicenseResponse2;
case wvcdm::EMPTY_PROVISIONING_CERTIFICATE: case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_1:
return kEmptyProvisioningCertificate; return kEmptyProvisioningCertificate1;
case wvcdm::EMPTY_PROVISIONING_RESPONSE: case wvcdm::EMPTY_PROVISIONING_RESPONSE:
return kEmptyProvisioningResponse; return kEmptyProvisioningResponse;
case wvcdm::EMPTY_SESSION_ID: case wvcdm::EMPTY_SESSION_ID:
@@ -311,6 +311,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kErrorCDMGeneric; return kErrorCDMGeneric;
case wvcdm::INVALID_QUERY_STATUS: case wvcdm::INVALID_QUERY_STATUS:
return kInvalidQueryStatus; return kInvalidQueryStatus;
case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_2:
return kEmptyProvisioningCertificate2;
case wvcdm::UNKNOWN_ERROR: case wvcdm::UNKNOWN_ERROR:
return android::ERROR_DRM_UNKNOWN; return android::ERROR_DRM_UNKNOWN;
} }