Merge "Corrections for license release on fallback to L3" into lmp-dev
This commit is contained in:
@@ -34,7 +34,9 @@ class CdmEngine {
|
||||
CdmSessionId* session_id);
|
||||
virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
|
||||
|
||||
virtual CdmResponseType OpenKeySetSession(const CdmKeySetId& key_set_id);
|
||||
virtual CdmResponseType OpenKeySetSession(
|
||||
const CdmKeySetId& key_set_id,
|
||||
const CdmClientPropertySet* property_set);
|
||||
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
|
||||
|
||||
// License related methods
|
||||
|
||||
@@ -108,7 +108,9 @@ CdmResponseType CdmEngine::OpenSession(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::OpenKeySetSession(const CdmKeySetId& key_set_id) {
|
||||
CdmResponseType CdmEngine::OpenKeySetSession(
|
||||
const CdmKeySetId& key_set_id,
|
||||
const CdmClientPropertySet* property_set) {
|
||||
LOGI("CdmEngine::OpenKeySetSession");
|
||||
|
||||
if (key_set_id.empty()) {
|
||||
@@ -117,7 +119,7 @@ CdmResponseType CdmEngine::OpenKeySetSession(const CdmKeySetId& key_set_id) {
|
||||
}
|
||||
|
||||
CdmSessionId session_id;
|
||||
CdmResponseType sts = OpenSession(KEY_SYSTEM, NULL, &session_id);
|
||||
CdmResponseType sts = OpenSession(KEY_SYSTEM, property_set, &session_id);
|
||||
|
||||
if (sts != NO_ERROR)
|
||||
return sts;
|
||||
|
||||
@@ -869,7 +869,11 @@ bool CdmLicense::RestoreLicenseForRelease(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Properties::use_certificates_as_identification()) {
|
||||
key_request_ = signed_request.msg();
|
||||
} else {
|
||||
if (!session_->GenerateDerivedKeys(signed_request.msg())) return false;
|
||||
}
|
||||
|
||||
SignedMessage signed_response;
|
||||
if (!signed_response.ParseFromString(license_response)) {
|
||||
@@ -885,19 +889,6 @@ bool CdmLicense::RestoreLicenseForRelease(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Properties::use_certificates_as_identification()) {
|
||||
if (!signed_response.has_session_key()) {
|
||||
LOGE("CdmLicense::RestoreLicenseForRelease: no session keys present");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!session_->GenerateDerivedKeys(key_request_,
|
||||
signed_response.session_key()))
|
||||
return false;
|
||||
} else {
|
||||
if (!session_->GenerateDerivedKeys(key_request_)) return false;
|
||||
}
|
||||
|
||||
if (!signed_response.has_signature()) {
|
||||
LOGE("CdmLicense::RestoreLicenseForRelease: license response is not"
|
||||
" signed");
|
||||
@@ -914,6 +905,21 @@ bool CdmLicense::RestoreLicenseForRelease(
|
||||
if (license.id().has_provider_session_token())
|
||||
provider_session_token_ = license.id().provider_session_token();
|
||||
|
||||
if (Properties::use_certificates_as_identification()) {
|
||||
if (!signed_response.has_session_key()) {
|
||||
LOGE("CdmLicense::RestoreLicenseForRelease: no session keys present");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (license.id().has_provider_session_token()) {
|
||||
if (!session_->GenerateDerivedKeys(key_request_,
|
||||
signed_response.session_key()))
|
||||
return false;
|
||||
} else {
|
||||
return KEY_ADDED == HandleKeyResponse(license_response);
|
||||
}
|
||||
}
|
||||
|
||||
if (license.policy().has_renewal_server_url())
|
||||
server_url_ = license.policy().renewal_server_url();
|
||||
|
||||
|
||||
@@ -778,11 +778,13 @@ extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
|
||||
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
|
||||
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
|
||||
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (fcn3 && fcn3->version > 8) {
|
||||
if (fcn1 && fcn1->version > 8) {
|
||||
sts = fcn1->DeactivateUsageEntry(pst, pst_length);
|
||||
}
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
if (fcn3 && fcn1 != fcn3 && fcn3->version > 8) {
|
||||
sts = fcn3->DeactivateUsageEntry(pst, pst_length);
|
||||
}
|
||||
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) {
|
||||
sts = fcn1->DeactivateUsageEntry(pst, pst_length);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ class WvContentDecryptionModule : public TimerHandler {
|
||||
const CdmInitData& init_data,
|
||||
const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters,
|
||||
CdmClientPropertySet* property_set,
|
||||
CdmKeyMessage* key_request,
|
||||
std::string* server_url);
|
||||
|
||||
|
||||
@@ -66,11 +66,12 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
|
||||
const CdmInitData& init_data,
|
||||
const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters,
|
||||
CdmClientPropertySet* property_set,
|
||||
CdmKeyMessage* key_request,
|
||||
std::string* server_url) {
|
||||
CdmResponseType sts;
|
||||
if (license_type == kLicenseTypeRelease) {
|
||||
sts = cdm_engine_->OpenKeySetSession(key_set_id);
|
||||
sts = cdm_engine_->OpenKeySetSession(key_set_id, property_set);
|
||||
if (sts != NO_ERROR)
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ class WvCdmExtendedDurationTest : public testing::Test {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id_, "video/mp4", init_data,
|
||||
license_type, app_parameters, &key_msg_, &server_url));
|
||||
license_type, app_parameters, NULL, &key_msg_, &server_url));
|
||||
EXPECT_EQ(0u, server_url.size());
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ class WvCdmExtendedDurationTest : public testing::Test {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id_, "video/mp4", init_data,
|
||||
license_type, app_parameters, &key_msg_, server_url));
|
||||
license_type, app_parameters, NULL, &key_msg_, server_url));
|
||||
// TODO(edwinwong, rfrias): Add tests cases for when license server url
|
||||
// is empty on renewal. Need appropriate key id at the server.
|
||||
EXPECT_NE(0u, server_url->size());
|
||||
@@ -270,7 +270,8 @@ class WvCdmExtendedDurationTest : public testing::Test {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id, key_set_id, "video/mp4", init_data,
|
||||
kLicenseTypeRelease, app_parameters, &key_msg_, &server_url));
|
||||
kLicenseTypeRelease, app_parameters, NULL, &key_msg_,
|
||||
&server_url));
|
||||
}
|
||||
|
||||
// Post a request and extract the drm message from the response
|
||||
|
||||
@@ -371,12 +371,16 @@ SessionSharingSubSampleInfo session_sharing_sub_samples[] = {
|
||||
struct UsageInfoSubSampleInfo {
|
||||
SubSampleInfo* sub_sample;
|
||||
uint32_t usage_info;
|
||||
wvcdm::SecurityLevel security_level;
|
||||
};
|
||||
|
||||
UsageInfoSubSampleInfo usage_info_sub_sample_info[] = {
|
||||
{&usage_info_sub_samples_icp[0], 1},
|
||||
{&usage_info_sub_samples_icp[0], 3},
|
||||
{&usage_info_sub_samples_icp[0], 5}};
|
||||
{&usage_info_sub_samples_icp[0], 1, wvcdm::kLevelDefault},
|
||||
{&usage_info_sub_samples_icp[0], 3, wvcdm::kLevelDefault},
|
||||
{&usage_info_sub_samples_icp[0], 5, wvcdm::kLevelDefault},
|
||||
{&usage_info_sub_samples_icp[0], 1, wvcdm::kLevel3},
|
||||
{&usage_info_sub_samples_icp[0], 3, wvcdm::kLevel3},
|
||||
{&usage_info_sub_samples_icp[0], 5, wvcdm::kLevel3}};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -460,18 +464,30 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
|
||||
void GenerateKeyRequest(const std::string& init_data,
|
||||
CdmLicenseType license_type) {
|
||||
GenerateKeyRequest(init_data, license_type, NULL);
|
||||
}
|
||||
|
||||
void GenerateKeyRequest(const std::string& init_data,
|
||||
CdmLicenseType license_type,
|
||||
CdmClientPropertySet* property_set) {
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
std::string server_url;
|
||||
std::string key_set_id;
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id, "video/mp4", init_data, license_type,
|
||||
app_parameters, &key_msg_, &server_url));
|
||||
app_parameters, property_set, &key_msg_, &server_url));
|
||||
EXPECT_EQ(0u, server_url.size());
|
||||
}
|
||||
|
||||
void GenerateRenewalRequest(CdmLicenseType license_type,
|
||||
std::string* server_url) {
|
||||
GenerateRenewalRequest(license_type, server_url, NULL);
|
||||
}
|
||||
|
||||
void GenerateRenewalRequest(CdmLicenseType license_type,
|
||||
std::string* server_url,
|
||||
CdmClientPropertySet* property_set) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate.
|
||||
std::string init_data;
|
||||
@@ -479,13 +495,19 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id_, "video/mp4", init_data,
|
||||
license_type, app_parameters, &key_msg_, server_url));
|
||||
license_type, app_parameters, property_set, &key_msg_,
|
||||
server_url));
|
||||
// TODO(edwinwong, rfrias): Add tests cases for when license server url
|
||||
// is empty on renewal. Need appropriate key id at the server.
|
||||
EXPECT_NE(0u, server_url->size());
|
||||
}
|
||||
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id) {
|
||||
GenerateKeyRelease(key_set_id, NULL);
|
||||
}
|
||||
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id,
|
||||
CdmClientPropertySet* property_set) {
|
||||
CdmSessionId session_id;
|
||||
CdmInitData init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
@@ -493,7 +515,8 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id, key_set_id, "video/mp4", init_data,
|
||||
kLicenseTypeRelease, app_parameters, &key_msg_, &server_url));
|
||||
kLicenseTypeRelease, app_parameters, property_set, &key_msg_,
|
||||
&server_url));
|
||||
}
|
||||
|
||||
// Post a request and extract the drm message from the response
|
||||
@@ -1019,6 +1042,70 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
Unprovision();
|
||||
|
||||
TestWvCdmClientPropertySet property_set;
|
||||
property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
|
||||
// override default settings unless configured through the command line
|
||||
std::string key_id;
|
||||
std::string client_auth;
|
||||
GetOfflineConfiguration(&key_id, &client_auth);
|
||||
|
||||
CdmResponseType sts =
|
||||
decryptor_.OpenSession(g_key_system, &property_set, &session_id_);
|
||||
|
||||
if (NEED_PROVISIONING == sts) {
|
||||
std::string provisioning_server_url;
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority, cert, wrapped_key;
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
|
||||
cert_type, cert_authority, &key_msg_,
|
||||
&provisioning_server_url));
|
||||
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
|
||||
&session_id_));
|
||||
} else {
|
||||
EXPECT_EQ(NO_ERROR, sts);
|
||||
}
|
||||
|
||||
decryptor_.OpenSession(g_key_system, &property_set, &session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
decryptor_.OpenSession(g_key_system, &property_set, &session_id_);
|
||||
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id, &property_set);
|
||||
|
||||
session_id_.clear();
|
||||
decryptor_.OpenSession(g_key_system, &property_set, &session_id_);
|
||||
EXPECT_EQ(
|
||||
wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id, &property_set);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
Unprovision();
|
||||
Provision(kLevelDefault);
|
||||
@@ -1101,6 +1188,15 @@ class WvCdmUsageInfoTest
|
||||
TEST_P(WvCdmUsageInfoTest, UsageInfo) {
|
||||
Unprovision();
|
||||
Provision(kLevelDefault);
|
||||
|
||||
UsageInfoSubSampleInfo* usage_info_data = GetParam();
|
||||
TestWvCdmClientPropertySet client_property_set;
|
||||
TestWvCdmClientPropertySet* property_set = NULL;
|
||||
if (kLevel3 == usage_info_data->security_level) {
|
||||
client_property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
property_set = &client_property_set;
|
||||
}
|
||||
|
||||
CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
||||
DeviceFiles handle;
|
||||
EXPECT_TRUE(handle.Init(security_level));
|
||||
@@ -1108,10 +1204,9 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
|
||||
handle.SetTestFile(&file);
|
||||
EXPECT_TRUE(handle.DeleteUsageInfo());
|
||||
|
||||
UsageInfoSubSampleInfo* usage_info_data = GetParam();
|
||||
for (size_t i = 0; i < usage_info_data->usage_info; ++i) {
|
||||
SubSampleInfo* data = usage_info_data->sub_sample + i;
|
||||
decryptor_.OpenSession(g_key_system, NULL, &session_id_);
|
||||
decryptor_.OpenSession(g_key_system, property_set, &session_id_);
|
||||
std::string key_id = a2bs_hex(
|
||||
"000000427073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
|
||||
@@ -1121,7 +1216,7 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
|
||||
char ch = 0x33 + i;
|
||||
key_id.append(1, ch);
|
||||
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, property_set);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
|
||||
@@ -209,7 +209,8 @@ status_t WVDrmPlugin::getKeyRequest(
|
||||
cdmInitDataType,
|
||||
processedInitData,
|
||||
cdmLicenseType, cdmParameters,
|
||||
&keyRequest, &cdmDefaultUrl);
|
||||
&mPropertySet, &keyRequest,
|
||||
&cdmDefaultUrl);
|
||||
|
||||
if (isCdmResponseTypeSuccess(res)) {
|
||||
defaultUrl.clear();
|
||||
|
||||
@@ -31,12 +31,13 @@ class MockCDM : public WvContentDecryptionModule {
|
||||
|
||||
MOCK_METHOD1(CloseSession, CdmResponseType(const CdmSessionId&));
|
||||
|
||||
MOCK_METHOD8(GenerateKeyRequest, CdmResponseType(const CdmSessionId&,
|
||||
MOCK_METHOD9(GenerateKeyRequest, CdmResponseType(const CdmSessionId&,
|
||||
const CdmKeySetId&,
|
||||
const std::string&,
|
||||
const CdmInitData&,
|
||||
const CdmLicenseType,
|
||||
CdmAppParameterMap&,
|
||||
CdmClientPropertySet*,
|
||||
CdmKeyMessage*, string*));
|
||||
|
||||
MOCK_METHOD3(AddKey, CdmResponseType(const CdmSessionId&,
|
||||
@@ -272,23 +273,23 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) {
|
||||
|
||||
EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData,
|
||||
kLicenseTypeOffline, cdmParameters, _,
|
||||
_))
|
||||
.WillOnce(DoAll(SetArgPointee<6>(cdmRequest),
|
||||
SetArgPointee<7>(kDefaultUrl),
|
||||
_, _))
|
||||
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest),
|
||||
SetArgPointee<8>(kDefaultUrl),
|
||||
Return(wvcdm::KEY_MESSAGE)));
|
||||
|
||||
EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData,
|
||||
kLicenseTypeStreaming, cdmParameters, _,
|
||||
_))
|
||||
.WillOnce(DoAll(SetArgPointee<6>(cdmRequest),
|
||||
SetArgPointee<7>(kDefaultUrl),
|
||||
_, _))
|
||||
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest),
|
||||
SetArgPointee<8>(kDefaultUrl),
|
||||
Return(wvcdm::KEY_MESSAGE)));
|
||||
|
||||
EXPECT_CALL(cdm, GenerateKeyRequest("", cdmKeySetId, mimeType, initData,
|
||||
kLicenseTypeRelease, cdmParameters, _,
|
||||
_))
|
||||
.WillOnce(DoAll(SetArgPointee<6>(cdmRequest),
|
||||
SetArgPointee<7>(kDefaultUrl),
|
||||
kLicenseTypeRelease, cdmParameters,
|
||||
NotNull(), _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<7>(cdmRequest),
|
||||
SetArgPointee<8>(kDefaultUrl),
|
||||
Return(wvcdm::KEY_MESSAGE)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user