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

@@ -40,15 +40,6 @@ class CdmEngine {
CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID);
virtual ~CdmEngine();
// Set service certificate used when provisioning under this CDM/CdmEngine.
// If no valid service certificate is set, a default one associated with
// the WV production provisioning server will be used.
virtual CdmResponseType SetProvisioningServiceCertificate(
const std::string& certificate);
// Report whether the service certificate has been set.
virtual bool HasProvisioningServiceCertificate();
// Session related methods
virtual CdmResponseType OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
@@ -166,6 +157,7 @@ class CdmEngine {
// Generate and return a valid provisioning request.
virtual CdmResponseType GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority,
const std::string& service_certificate,
CdmProvisioningRequest* request, std::string* default_url);
// Verify and process a provisioning response.
@@ -288,6 +280,8 @@ class CdmEngine {
virtual metrics::EngineMetrics* GetMetrics() { return &metrics_; }
virtual CdmResponseType ValidateServiceCertificate(const std::string& cert);
private:
// private methods
CdmResponseType OpenSession(
@@ -328,9 +322,6 @@ class CdmEngine {
static bool seeded_;
// Service certificate for the provisioning server.
ServiceCertificate provisioning_service_certificate_;
// usage related variables
scoped_ptr<CdmSession> usage_session_;
scoped_ptr<UsagePropertySet> usage_property_set_;

View File

@@ -69,10 +69,6 @@ class Properties {
std::string* service_certificate);
static bool SetServiceCertificate(const CdmSessionId& session_id,
const std::string& service_certificate);
static bool GetDeviceProvisioningServiceCertificate(
const CdmSessionId& session_id, std::string* service_certificate);
static bool SetDeviceProvisioningServiceCertificate(
const CdmSessionId& session_id, const std::string& service_certificate);
static bool UsePrivacyMode(const CdmSessionId& session_id);
static uint32_t GetSessionSharingId(const CdmSessionId& session_id);

View File

@@ -85,15 +85,6 @@ CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid)
CdmEngine::~CdmEngine() {}
CdmResponseType CdmEngine::SetProvisioningServiceCertificate(
const std::string& certificate) {
return provisioning_service_certificate_.Init(certificate);
}
bool CdmEngine::HasProvisioningServiceCertificate() {
return provisioning_service_certificate_.has_certificate();
}
CdmResponseType CdmEngine::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
const CdmSessionId& forced_session_id, WvCdmEventListener* event_listener) {
@@ -758,7 +749,8 @@ CdmResponseType CdmEngine::QueryOemCryptoSessionId(
*/
CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority,
CdmProvisioningRequest* request, std::string* default_url) {
const std::string& service_certificate, CdmProvisioningRequest* request,
std::string* default_url) {
LOGI("CdmEngine::GetProvisioningRequest");
if (!request) {
LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters");
@@ -774,8 +766,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
if (NULL == cert_provisioning_.get()) {
cert_provisioning_.reset(
new CertificateProvisioning(metrics_.GetCryptoMetrics()));
CdmResponseType status = cert_provisioning_->Init(
provisioning_service_certificate_.certificate());
CdmResponseType status = cert_provisioning_->Init(service_certificate);
if (status != NO_ERROR) return status;
}
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
@@ -1711,6 +1702,11 @@ void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
}
}
CdmResponseType CdmEngine::ValidateServiceCertificate(const std::string& cert) {
ServiceCertificate certificate;
return certificate.Init(cert);
}
std::string CdmEngine::MapHdcpVersion(
CryptoSession::HdcpCapability version) {
switch (version) {

View File

@@ -193,13 +193,11 @@ class WvCdmEnginePreProvTest : public testing::Test {
// try to provision. This is needed for testing nonce floods.
CryptoSession keep_alive(cdm_engine_.GetMetrics()->GetCryptoMetrics());
ASSERT_EQ(NO_ERROR, cdm_engine_.SetProvisioningServiceCertificate(
g_provisioning_service_certificate));
CdmResponseType result = NO_ERROR;
for(int i = 0; i < 2; ++i) { // Retry once if there is a nonce problem.
result = cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, &prov_request,
&provisioning_server_url);
cert_type, cert_authority, g_provisioning_service_certificate,
&prov_request, &provisioning_server_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGW("Woops. Nonce problem. Try again?");
sleep(1);
@@ -295,11 +293,9 @@ class WvCdmEnginePreProvTestUatBinary : public WvCdmEnginePreProvTest {
CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority;
std::string cert, wrapped_key;
ASSERT_EQ(NO_ERROR, cdm_engine_.SetProvisioningServiceCertificate(
g_provisioning_service_certificate));
ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, &binary_prov_request,
&provisioning_server_url));
cert_type, cert_authority, g_provisioning_service_certificate,
&binary_prov_request, &provisioning_server_url));
// prov_request is binary - base64 encode it
std::string prov_request(Base64SafeEncodeNoPad(
@@ -508,18 +504,20 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest {
std::string server_url_;
};
// Test that service certificate is initially absent.
TEST_F(WvCdmEnginePreProvTestStaging,
ProvisioningServiceCertificateInitialNoneTest) {
ASSERT_FALSE(cdm_engine_.HasProvisioningServiceCertificate());
// Tests to validate service certificate
TEST_F(WvCdmEnginePreProvTestUat, ProvisioningServiceCertificateValidTest) {
ASSERT_EQ(
cdm_engine_.ValidateServiceCertificate(
g_provisioning_service_certificate),
NO_ERROR);
};
// Test that service certificate can be properly installed.
TEST_F(WvCdmEnginePreProvTestStaging, ProvisioningServiceCertificateGoodTest) {
ASSERT_EQ(cdm_engine_.SetProvisioningServiceCertificate(
g_license_service_certificate),
NO_ERROR);
ASSERT_TRUE(cdm_engine_.HasProvisioningServiceCertificate());
TEST_F(WvCdmEnginePreProvTestUat, ProvisioningServiceCertificateInvalidTest) {
std::string certificate = g_provisioning_service_certificate;
// Add four nulls to the beginning of the cert to invalidate it
certificate.insert(0, 4, 0);
ASSERT_NE(cdm_engine_.ValidateServiceCertificate(certificate), NO_ERROR);
};
// Test that provisioning works, even if device is already provisioned.