Do Not Unprovision Baked-In DRM Certs

Merge from Widevine repo of http://go/wvgerrit/49820

Devices with baked-in DRM certs cannot be reprovisioned. As such, we
must protect them against being unprovisioned. Currently, our unit
tests break such devices by attempting to unprovision them. This patch
adds code to block the Unprovision() call on these devices.

Bug: 69264798
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759
Change-Id: I49322dcb2d3d5c7953e870eb91a9e0b978d4dabe
This commit is contained in:
Fred Gylys-Colwell
2018-06-30 22:30:57 -07:00
parent 13a76d1236
commit 240652afcf
7 changed files with 25 additions and 4 deletions

View File

@@ -199,11 +199,13 @@ class CryptoSession {
virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id,
bool* exists, uint32_t* nonce);
virtual CdmResponseType GetProvisioningMethod(
SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
private:
friend class CryptoSessionForTest;
CdmResponseType GetProvisioningMethod(SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
void Init();
void Terminate();
bool GetTokenFromKeybox(std::string* token);

View File

@@ -333,6 +333,7 @@ enum CdmResponseType {
GET_PROVISIONING_METHOD_ERROR = 289,
SESSION_NOT_FOUND_17 = 290,
SESSION_NOT_FOUND_18 = 291,
DEVICE_CANNOT_REPROVISION = 293,
};
enum CdmKeyStatus {

View File

@@ -872,6 +872,19 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) {
}
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
// Devices with baked-in DRM certs cannot be reprovisioned and therefore must
// not be unprovisioned.
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
CdmClientTokenType token_type = kClientTokenUninitialized;
CdmResponseType res = crypto_session.GetProvisioningMethod(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault,
&token_type);
if (res != NO_ERROR) {
return res;
} else if (token_type == kClientTokenDrmCert) {
return DEVICE_CANNOT_REPROVISION;
}
DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) {
LOGE("CdmEngine::Unprovision: unable to initialize device files");

View File

@@ -599,6 +599,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
break;
case SESSION_NOT_FOUND_18: *os << "SESSION_NOT_FOUND_18";
break;
case DEVICE_CANNOT_REPROVISION: *os << "DEVICE_CANNOT_REPROVISION";
break;
default:
*os << "Unknown CdmResponseType";
break;

View File

@@ -269,10 +269,11 @@ enum {
kNotAnEntitlementSession = ERROR_DRM_VENDOR_MIN + 278,
kLoadEntitledContentKeysError = ERROR_DRM_VENDOR_MIN + 279,
kGetProvisioningError = ERROR_DRM_VENDOR_MIN + 280,
kDeviceCannotReprovision = ERROR_DRM_VENDOR_MIN + 281,
// This should always follow the last error code.
// The offset value should be updated each time a new error code is added.
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 280,
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 281,
// Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -520,7 +520,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kLoadEntitledContentKeysError;
case wvcdm::GET_PROVISIONING_METHOD_ERROR:
return kGetProvisioningError;
case wvcdm::DEVICE_CANNOT_REPROVISION:
return kDeviceCannotReprovision;
}
// Return here instead of as a default case so that the compiler will warn

View File

@@ -299,6 +299,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::NOT_AN_ENTITLEMENT_SESSION:
case wvcdm::LOAD_ENTITLED_CONTENT_KEYS_ERROR:
case wvcdm::GET_PROVISIONING_METHOD_ERROR:
case wvcdm::DEVICE_CANNOT_REPROVISION:
ALOGW("Returns UNKNOWN error for legacy status: %d", res);
return Status::ERROR_DRM_UNKNOWN;