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, virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id,
bool* exists, uint32_t* nonce); bool* exists, uint32_t* nonce);
virtual CdmResponseType GetProvisioningMethod(
SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
private: private:
friend class CryptoSessionForTest; friend class CryptoSessionForTest;
CdmResponseType GetProvisioningMethod(SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
void Init(); void Init();
void Terminate(); void Terminate();
bool GetTokenFromKeybox(std::string* token); bool GetTokenFromKeybox(std::string* token);

View File

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

View File

@@ -872,6 +872,19 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) {
} }
CdmResponseType CdmEngine::Unprovision(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_); DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) { if (!handle.Init(security_level)) {
LOGE("CdmEngine::Unprovision: unable to initialize device files"); LOGE("CdmEngine::Unprovision: unable to initialize device files");

View File

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

View File

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

View File

@@ -520,7 +520,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kLoadEntitledContentKeysError; return kLoadEntitledContentKeysError;
case wvcdm::GET_PROVISIONING_METHOD_ERROR: case wvcdm::GET_PROVISIONING_METHOD_ERROR:
return kGetProvisioningError; return kGetProvisioningError;
case wvcdm::DEVICE_CANNOT_REPROVISION:
return kDeviceCannotReprovision;
} }
// Return here instead of as a default case so that the compiler will warn // 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::NOT_AN_ENTITLEMENT_SESSION:
case wvcdm::LOAD_ENTITLED_CONTENT_KEYS_ERROR: case wvcdm::LOAD_ENTITLED_CONTENT_KEYS_ERROR:
case wvcdm::GET_PROVISIONING_METHOD_ERROR: case wvcdm::GET_PROVISIONING_METHOD_ERROR:
case wvcdm::DEVICE_CANNOT_REPROVISION:
ALOGW("Returns UNKNOWN error for legacy status: %d", res); ALOGW("Returns UNKNOWN error for legacy status: %d", res);
return Status::ERROR_DRM_UNKNOWN; return Status::ERROR_DRM_UNKNOWN;