Allow a service certificate to be specified for provisioning

[ Merge of http://go/wvgerrit/48400 ]

Client identification information has recently been enabled in
provisioning messages. For privacy concerns this information
is being encrypted with a default service certificate.
Apps need to be able to override the default one to allow
for provisioning with third party provisioning services.

Bug: 78420508
Test: WV unit, integration tests
      New WvCdmRequestLicenseTest.ProvisioningTestWithServiceCertificate test
      GTS MediaDrmTestCases

Change-Id: Iee61ad47d33ce011efbea4eb90f7e4b1f032d15f
This commit is contained in:
Rahul Frias
2018-04-22 10:58:15 -07:00
parent d873f40d80
commit 816f00e533
16 changed files with 179 additions and 88 deletions

View File

@@ -261,6 +261,8 @@ class WVDrmPlugin : public android::DrmPlugin,
CdmIdentifier mCdmIdentifier;
std::string mProvisioningServiceCertificate;
status_t queryProperty(const std::string& property,
std::string& stringValue) const;

View File

@@ -402,6 +402,8 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
std::string mProvisioningServiceCertificate;
Status queryProperty(const std::string& property,
std::string& stringValue) const;

View File

@@ -370,11 +370,10 @@ status_t WVDrmPlugin::getProvisionRequest(const String8& cert_type,
string cdmCertAuthority = cert_authority.string();
CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType,
cdmCertAuthority,
mCdmIdentifier,
&cdmProvisionRequest,
&cdmDefaultUrl);
CdmResponseType res = mCDM->GetProvisioningRequest(
cdmCertType, cdmCertAuthority, mCdmIdentifier,
mProvisioningServiceCertificate, &cdmProvisionRequest,
&cdmDefaultUrl);
if (isCdmResponseTypeSuccess(res)) {
request = ToVector(cdmProvisionRequest);
@@ -541,6 +540,8 @@ status_t WVDrmPlugin::getPropertyByteArray(const String8& name,
return queryProperty(QUERY_KEY_PROVISIONING_ID, value);
} else if (name == "serviceCertificate") {
value = ToVector(mPropertySet.service_certificate());
} else if (name == "provisioningServiceCertificate") {
value = ToVector(mProvisioningServiceCertificate);
} else if (name == "metrics") {
std::string serialized_metrics;
drm_metrics::WvCdmMetrics metrics;
@@ -642,6 +643,13 @@ status_t WVDrmPlugin::setPropertyByteArray(const String8& name,
} else {
return android::BAD_VALUE;
}
} else if (name == "provisioningServiceCertificate") {
std::string cert(value.begin(), value.end());
if (value.isEmpty() || mCDM->IsValidServiceCertificate(cert)) {
mProvisioningServiceCertificate = cert;
} else {
return android::BAD_VALUE;
}
} else {
ALOGE("App set unknown byte array property %s", name.string());
return android::ERROR_DRM_CANNOT_HANDLE;

View File

@@ -596,8 +596,8 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
std::string cdmCertAuthority = certificateAuthority;
CdmResponseType res = mCDM->GetProvisioningRequest(
cdmCertType, cdmCertAuthority, identifier, &cdmProvisionRequest,
&cdmDefaultUrl);
cdmCertType, cdmCertAuthority, identifier,
mProvisioningServiceCertificate, &cdmProvisionRequest, &cdmDefaultUrl);
if (isCdmResponseTypeSuccess(res)) {
request = StrToVector(cdmProvisionRequest);
defaultUrl.clear();
@@ -996,6 +996,8 @@ Return<void> WVDrmPlugin::getPropertyByteArray(
}
} else if (name == "serviceCertificate") {
value = StrToVector(mPropertySet.service_certificate());
} else if (name == "provisioningServiceCertificate") {
value = StrToVector(mProvisioningServiceCertificate);
} else if (name == "metrics") {
drm_metrics::WvCdmMetrics metrics;
// If the cdm identifier is not yet sealed, then there are no metrics
@@ -1126,6 +1128,13 @@ Return<Status> WVDrmPlugin::setPropertyByteArray(
} else {
return Status::BAD_VALUE;
}
} else if (name == "provisioningServiceCertificate") {
std::string cert(_value.begin(), _value.end());
if (_value.empty() || mCDM->IsValidServiceCertificate(cert)) {
mProvisioningServiceCertificate = cert;
} else {
return Status::BAD_VALUE;
}
} else {
ALOGE("App set unknown byte array property %s", name.c_str());
return Status::ERROR_DRM_CANNOT_HANDLE;

View File

@@ -173,9 +173,10 @@ class MockCDM : public WvContentDecryptionModule {
MOCK_METHOD2(QueryOemCryptoSessionId, CdmResponseType(const CdmSessionId&,
CdmQueryMap*));
MOCK_METHOD5(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
MOCK_METHOD6(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
const std::string&,
const CdmIdentifier&,
const std::string&,
CdmProvisioningRequest*,
std::string*));
@@ -803,9 +804,10 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
static const char* kDefaultUrl = "http://google.com/";
EXPECT_CALL(*cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(),
HasOrigin(EMPTY_ORIGIN), _, _))
.WillOnce(DoAll(SetArgPointee<3>(cdmRequest),
SetArgPointee<4>(kDefaultUrl),
HasOrigin(EMPTY_ORIGIN), IsEmpty(),
_, _))
.WillOnce(DoAll(SetArgPointee<4>(cdmRequest),
SetArgPointee<5>(kDefaultUrl),
testing::Return(wvcdm::NO_ERROR)));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);

View File

@@ -85,9 +85,10 @@ class MockCDM : public WvContentDecryptionModule {
MOCK_METHOD2(QueryOemCryptoSessionId, CdmResponseType(const CdmSessionId&,
CdmQueryMap*));
MOCK_METHOD5(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
MOCK_METHOD6(GetProvisioningRequest, CdmResponseType(CdmCertificateType,
const std::string&,
const CdmIdentifier&,
const std::string&,
CdmProvisioningRequest*,
std::string*));
@@ -605,9 +606,10 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
static const char* kDefaultUrl = "http://google.com/";
EXPECT_CALL(*cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(),
HasOrigin(EMPTY_ORIGIN), _, _))
.WillOnce(DoAll(SetArgPointee<3>(cdmRequest),
SetArgPointee<4>(kDefaultUrl),
HasOrigin(EMPTY_ORIGIN), IsEmpty(),
_, _))
.WillOnce(DoAll(SetArgPointee<4>(cdmRequest),
SetArgPointee<5>(kDefaultUrl),
Return(wvcdm::NO_ERROR)));
Vector<uint8_t> request;