Add client information to release and renewal messages
[ Merge of go/wvgerrit/14240 ] Client information is reported in release and renewal messages based on flag in the license. License proto has been updated to match server updates. There are two caveats * Client IDs will be reported unencrypted when usage reports are requested. * Release requests that enable privacy mode (encrypted client IDs) but do not specify a service certificate are not supported. b/19247020 Change-Id: I95e709922122370f310936fbad3d312262128e49
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "config_test_env.h"
|
||||
#include "device_files.h"
|
||||
#include "file_store.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "license_request.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
@@ -49,8 +50,7 @@ wvcdm::KeyId g_key_id;
|
||||
wvcdm::CdmKeySystem g_key_system;
|
||||
std::string g_license_server;
|
||||
wvcdm::KeyId g_wrong_key_id;
|
||||
wvcdm::LicenseServerId g_license_server_id =
|
||||
wvcdm::kContentProtectionServer;
|
||||
wvcdm::LicenseServerId g_license_server_id = wvcdm::kContentProtectionServer;
|
||||
|
||||
std::string kServiceCertificate =
|
||||
"0803121028703454C008F63618ADE7443DB6C4C8188BE7F99005228E023082010"
|
||||
@@ -399,9 +399,47 @@ UsageInfoSubSampleInfo usage_info_sub_sample_info[] = {
|
||||
{&usage_info_sub_samples_icp[0], 5, wvcdm::kLevel3, ""},
|
||||
{&usage_info_sub_samples_icp[0], 3, wvcdm::kLevel3, "other app id"}};
|
||||
|
||||
struct RenewWithClientIdTestConfiguration {
|
||||
bool renew_with_client_id;
|
||||
bool specify_app_parameters;
|
||||
bool enable_privacy_mode;
|
||||
bool specify_service_certificate;
|
||||
std::string test_description;
|
||||
};
|
||||
|
||||
RenewWithClientIdTestConfiguration
|
||||
streaming_renew_client_id_test_configuration[] = {
|
||||
{false, false, false, false,
|
||||
"Test: Streaming renewal without client Id"},
|
||||
{true, false, false, false, "Test: Streaming renewal with client Id"},
|
||||
{true, true, false, false,
|
||||
"Test: Streaming renewal with app parameters"},
|
||||
{true, false, true, false,
|
||||
"Test: Streaming renewal fetch service cert"},
|
||||
{true, false, true, true,
|
||||
"Test: Streaming renewal, service cert provided"}};
|
||||
|
||||
// Note: Offline renewal/release with encrypted client Ids and where a service
|
||||
// certificate needs to be fetched is not supported.
|
||||
RenewWithClientIdTestConfiguration
|
||||
offline_release_client_id_test_configuration[] = {
|
||||
{false, false, false, false,
|
||||
"Test: Offline renewal/release without client Id"},
|
||||
{true, false, false, false,
|
||||
"Test: Offline renewal/release with client Id"},
|
||||
{true, true, false, false,
|
||||
"Test: Offline renewal/release with app parameters"},
|
||||
{true, false, true, true,
|
||||
"Test: Offline renewal/release, service cert provided"}};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
// Protobuf generated classes
|
||||
using video_widevine_server::sdk::ClientIdentification;
|
||||
using video_widevine_server::sdk::ClientIdentification_NameValue;
|
||||
using video_widevine_server::sdk::SignedMessage;
|
||||
|
||||
class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
||||
public:
|
||||
TestWvCdmClientPropertySet()
|
||||
@@ -487,7 +525,14 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
void GenerateKeyRequest(const std::string& init_data,
|
||||
CdmLicenseType license_type,
|
||||
CdmClientPropertySet* property_set) {
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
CdmAppParameterMap app_parameters;
|
||||
GenerateKeyRequest(init_data, app_parameters, license_type, property_set);
|
||||
}
|
||||
|
||||
void GenerateKeyRequest(const std::string& init_data,
|
||||
CdmAppParameterMap& app_parameters,
|
||||
CdmLicenseType license_type,
|
||||
CdmClientPropertySet* property_set) {
|
||||
std::string server_url;
|
||||
std::string key_set_id;
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
@@ -499,13 +544,13 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
}
|
||||
|
||||
void GenerateRenewalRequest(CdmLicenseType license_type,
|
||||
std::string* server_url) {
|
||||
GenerateRenewalRequest(license_type, server_url, NULL);
|
||||
CdmKeyMessage* key_msg, std::string* server_url) {
|
||||
GenerateRenewalRequest(license_type, server_url);
|
||||
*key_msg = key_msg_;
|
||||
}
|
||||
|
||||
void GenerateRenewalRequest(CdmLicenseType license_type,
|
||||
std::string* server_url,
|
||||
CdmClientPropertySet* property_set) {
|
||||
std::string* server_url) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate.
|
||||
std::string init_data;
|
||||
@@ -514,8 +559,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id_, "video/mp4", init_data,
|
||||
license_type, app_parameters, property_set, EMPTY_ORIGIN,
|
||||
&key_msg_, &key_request_type, server_url));
|
||||
license_type, app_parameters, NULL, EMPTY_ORIGIN, &key_msg_,
|
||||
&key_request_type, server_url));
|
||||
EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type);
|
||||
// TODO(edwinwong, rfrias): Add tests cases for when license server url
|
||||
// is empty on renewal. Need appropriate key id at the server.
|
||||
@@ -523,11 +568,12 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
}
|
||||
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id) {
|
||||
GenerateKeyRelease(key_set_id, NULL);
|
||||
GenerateKeyRelease(key_set_id, NULL, NULL);
|
||||
}
|
||||
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id,
|
||||
CdmClientPropertySet* property_set) {
|
||||
CdmClientPropertySet* property_set,
|
||||
CdmKeyMessage* key_msg) {
|
||||
CdmSessionId session_id;
|
||||
CdmInitData init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
@@ -539,6 +585,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
kLicenseTypeRelease, app_parameters, property_set,
|
||||
EMPTY_ORIGIN, &key_msg_, &key_request_type, &server_url));
|
||||
EXPECT_EQ(kKeyRequestTypeRelease, key_request_type);
|
||||
if (key_msg) *key_msg = key_msg_;
|
||||
}
|
||||
|
||||
void LogResponseError(const std::string& message, int http_status_code) {
|
||||
@@ -622,15 +669,22 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth,
|
||||
bool is_renewal) {
|
||||
std::string resp = GetKeyRequestResponse(server_url, client_auth);
|
||||
std::string response;
|
||||
VerifyKeyRequestResponse(server_url, client_auth, is_renewal, &response);
|
||||
}
|
||||
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth, bool is_renewal,
|
||||
std::string* response) {
|
||||
*response = GetKeyRequestResponse(server_url, client_auth);
|
||||
|
||||
if (is_renewal) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_),
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
} else {
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_),
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
}
|
||||
}
|
||||
@@ -649,9 +703,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
property_set = &property_set_L3;
|
||||
}
|
||||
|
||||
CdmResponseType status =
|
||||
decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_);
|
||||
CdmResponseType status = decryptor_.OpenSession(
|
||||
g_key_system, property_set, EMPTY_ORIGIN, NULL, &session_id_);
|
||||
switch (status) {
|
||||
case NO_ERROR:
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -667,9 +720,9 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority, cert, wrapped_key;
|
||||
|
||||
status = decryptor_.GetProvisioningRequest(
|
||||
cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
|
||||
&provisioning_server_url);
|
||||
status = decryptor_.GetProvisioningRequest(cert_type, cert_authority,
|
||||
EMPTY_ORIGIN, &key_msg_,
|
||||
&provisioning_server_url);
|
||||
EXPECT_EQ(wvcdm::NO_ERROR, status);
|
||||
if (NO_ERROR != status) return;
|
||||
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
|
||||
@@ -678,8 +731,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response,
|
||||
&cert, &wrapped_key));
|
||||
EXPECT_EQ(0, static_cast<int>(cert.size()));
|
||||
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -687,9 +740,9 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
}
|
||||
|
||||
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, property_set,
|
||||
EMPTY_ORIGIN, NULL,
|
||||
&session_id_));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN,
|
||||
NULL, &session_id_));
|
||||
CdmQueryMap query_info;
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.QuerySessionStatus(session_id_, &query_info));
|
||||
@@ -704,7 +757,6 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CdmSecurityLevel GetDefaultSecurityLevel() {
|
||||
std::string level = GetSecurityLevel(NULL).c_str();
|
||||
CdmSecurityLevel security_level = kSecurityLevelUninitialized;
|
||||
@@ -738,9 +790,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
EXPECT_EQ(0, static_cast<int>(cert.size()));
|
||||
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -781,18 +832,16 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
EXPECT_EQ(0, static_cast<int>(cert.size()));
|
||||
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
|
||||
|
||||
response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
response = GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::EMPTY_PROVISIONING_CERTIFICATE,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(0, static_cast<int>(cert.size()));
|
||||
EXPECT_EQ(0, static_cast<int>(wrapped_key.size()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -814,9 +863,8 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
EXPECT_NE(0, static_cast<int>(cert.size()));
|
||||
EXPECT_NE(0, static_cast<int>(wrapped_key.size()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -833,31 +881,29 @@ TEST_F(WvCdmRequestLicenseTest, PropertySetTest) {
|
||||
property_set_L1.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L1);
|
||||
property_set_L1.set_use_privacy_mode(true);
|
||||
decryptor_.OpenSession(g_key_system, &property_set_L1, EMPTY_ORIGIN, NULL,
|
||||
&session_id_L1);
|
||||
&session_id_L1);
|
||||
property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
property_set_L3.set_use_privacy_mode(false);
|
||||
|
||||
CdmResponseType sts = decryptor_.OpenSession(g_key_system, &property_set_L3,
|
||||
EMPTY_ORIGIN, NULL,
|
||||
&session_id_L3);
|
||||
CdmResponseType sts = decryptor_.OpenSession(
|
||||
g_key_system, &property_set_L3, EMPTY_ORIGIN, NULL, &session_id_L3);
|
||||
|
||||
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, EMPTY_ORIGIN,
|
||||
&key_msg_, &provisioning_server_url));
|
||||
cert_type, cert_authority, EMPTY_ORIGIN, &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(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set_L3,
|
||||
EMPTY_ORIGIN, NULL,
|
||||
&session_id_L3));
|
||||
decryptor_.OpenSession(g_key_system, &property_set_L3,
|
||||
EMPTY_ORIGIN, NULL, &session_id_L3));
|
||||
} else {
|
||||
EXPECT_EQ(NO_ERROR, sts);
|
||||
}
|
||||
@@ -903,10 +949,9 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
|
||||
handle.SetTestFile(&file);
|
||||
EXPECT_TRUE(handle.DeleteAllFiles());
|
||||
|
||||
EXPECT_EQ(
|
||||
NEED_PROVISIONING,
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_));
|
||||
EXPECT_EQ(NEED_PROVISIONING,
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN,
|
||||
NULL, &session_id_));
|
||||
std::string provisioning_server_url;
|
||||
CdmCertificateType cert_type = kCertificateWidevine;
|
||||
std::string cert_authority, cert, wrapped_key;
|
||||
@@ -917,9 +962,8 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
|
||||
EMPTY_ORIGIN, NULL, &session_id_));
|
||||
@@ -1117,9 +1161,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
std::string client_auth;
|
||||
GetOfflineConfiguration(&key_id, &client_auth);
|
||||
|
||||
CdmResponseType sts =
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_);
|
||||
CdmResponseType sts = decryptor_.OpenSession(
|
||||
g_key_system, &property_set, EMPTY_ORIGIN, NULL, &session_id_);
|
||||
|
||||
if (NEED_PROVISIONING == sts) {
|
||||
std::string provisioning_server_url;
|
||||
@@ -1132,12 +1175,11 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
|
||||
EMPTY_ORIGIN, NULL,
|
||||
&session_id_));
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN,
|
||||
NULL, &session_id_));
|
||||
} else {
|
||||
EXPECT_EQ(NO_ERROR, sts);
|
||||
}
|
||||
@@ -1160,7 +1202,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id, &property_set);
|
||||
GenerateKeyRelease(key_set_id, &property_set, NULL);
|
||||
|
||||
session_id_.clear();
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
@@ -1171,7 +1213,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id, &property_set);
|
||||
GenerateKeyRelease(key_set_id, &property_set, NULL);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
}
|
||||
@@ -1199,11 +1241,11 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, &listener,
|
||||
&session_id_);
|
||||
CdmSessionId restore_session_id = session_id_;
|
||||
EXPECT_CALL(listener,
|
||||
OnSessionKeysChange(restore_session_id,
|
||||
AllOf(Each(Pair(_, kKeyStatusUsable)),
|
||||
Not(IsEmpty())),
|
||||
true));
|
||||
EXPECT_CALL(
|
||||
listener,
|
||||
OnSessionKeysChange(
|
||||
restore_session_id,
|
||||
AllOf(Each(Pair(_, kKeyStatusUsable)), Not(IsEmpty())), true));
|
||||
EXPECT_CALL(listener, OnExpirationUpdate(restore_session_id, _));
|
||||
EXPECT_EQ(wvcdm::KEY_ADDED,
|
||||
decryptor_.RestoreKey(restore_session_id, key_set_id));
|
||||
@@ -1213,11 +1255,11 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
// Maybe called since VerifyKeyRequestResponse could take some time.
|
||||
EXPECT_CALL(listener, OnSessionRenewalNeeded(restore_session_id))
|
||||
.Times(AtLeast(0));
|
||||
EXPECT_CALL(listener,
|
||||
OnSessionKeysChange(restore_session_id,
|
||||
AllOf(Each(Pair(_, kKeyStatusExpired)),
|
||||
Not(IsEmpty())),
|
||||
false));
|
||||
EXPECT_CALL(
|
||||
listener,
|
||||
OnSessionKeysChange(
|
||||
restore_session_id,
|
||||
AllOf(Each(Pair(_, kKeyStatusExpired)), Not(IsEmpty())), false));
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
@@ -1254,15 +1296,277 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) {
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
|
||||
ASSERT_EQ(NO_ERROR,
|
||||
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
|
||||
&session_id_));
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN,
|
||||
NULL, &session_id_));
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_));
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.CloseSession(session_id_));
|
||||
}
|
||||
|
||||
class WvCdmStreamingLicenseRenewalTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<
|
||||
RenewWithClientIdTestConfiguration*> {};
|
||||
|
||||
TEST_P(WvCdmStreamingLicenseRenewalTest, DISABLED_WithClientId) {
|
||||
RenewWithClientIdTestConfiguration* config = GetParam();
|
||||
std::string key_id;
|
||||
if (config->renew_with_client_id) {
|
||||
key_id = a2bs_hex(
|
||||
"000000427073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
|
||||
"08011a0d7769646576696e655f74657374220f73" // pssh data
|
||||
"747265616d696e675f636c697036");
|
||||
} else {
|
||||
key_id = g_key_id;
|
||||
}
|
||||
|
||||
const uint32_t kNameValueParamSize = 2;
|
||||
std::pair<std::string, std::string> name_value_params[kNameValueParamSize] = {
|
||||
{"Name1", "Value1"}, {"Name2", "Value2"}};
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
if (config->specify_app_parameters) {
|
||||
for (uint32_t i = 0; i < kNameValueParamSize; ++i) {
|
||||
app_parameters[name_value_params[i].first] = name_value_params[i].second;
|
||||
}
|
||||
}
|
||||
|
||||
TestWvCdmClientPropertySet property_set;
|
||||
if (config->enable_privacy_mode) {
|
||||
property_set.set_use_privacy_mode(true);
|
||||
if (config->specify_service_certificate)
|
||||
property_set.set_service_certificate(a2bs_hex(kServiceCertificate));
|
||||
}
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeStreaming,
|
||||
&property_set);
|
||||
if (config->enable_privacy_mode && !config->specify_service_certificate) {
|
||||
std::string resp = GetKeyRequestResponse(g_license_server, g_client_auth);
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_),
|
||||
wvcdm::NEED_KEY);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming);
|
||||
}
|
||||
std::string key_response;
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false,
|
||||
&key_response);
|
||||
|
||||
// Validate signed license
|
||||
SignedMessage signed_message;
|
||||
EXPECT_TRUE(signed_message.ParseFromString(key_response))
|
||||
<< config->test_description;
|
||||
EXPECT_EQ(SignedMessage::LICENSE, signed_message.type())
|
||||
<< config->test_description;
|
||||
EXPECT_TRUE(signed_message.has_signature()) << config->test_description;
|
||||
EXPECT_TRUE(!signed_message.msg().empty()) << config->test_description;
|
||||
|
||||
// Verify license request
|
||||
video_widevine_server::sdk::License license;
|
||||
EXPECT_TRUE(license.ParseFromString(signed_message.msg()))
|
||||
<< config->test_description;
|
||||
|
||||
// Verify renew_with_client_id
|
||||
EXPECT_EQ(config->renew_with_client_id,
|
||||
license.policy().has_renew_with_client_id());
|
||||
|
||||
std::string license_server;
|
||||
CdmKeyMessage key_msg;
|
||||
GenerateRenewalRequest(kLicenseTypeStreaming, &key_msg, &license_server);
|
||||
if (license_server.empty()) license_server = g_license_server;
|
||||
|
||||
// Validate signed renewal request
|
||||
EXPECT_TRUE(signed_message.ParseFromString(key_msg))
|
||||
<< config->test_description;
|
||||
EXPECT_EQ(SignedMessage::LICENSE_REQUEST, signed_message.type())
|
||||
<< config->test_description;
|
||||
EXPECT_TRUE(signed_message.has_signature()) << config->test_description;
|
||||
EXPECT_TRUE(!signed_message.msg().empty()) << config->test_description;
|
||||
|
||||
// Verify license request
|
||||
video_widevine_server::sdk::LicenseRequest license_renewal;
|
||||
EXPECT_TRUE(license_renewal.ParseFromString(signed_message.msg()))
|
||||
<< config->test_description;
|
||||
|
||||
// Verify ClientId
|
||||
EXPECT_EQ(config->renew_with_client_id && !config->enable_privacy_mode,
|
||||
license_renewal.has_client_id())
|
||||
<< config->test_description;
|
||||
|
||||
if (config->specify_app_parameters) {
|
||||
for (uint32_t i = 0; i < kNameValueParamSize; ++i) {
|
||||
bool found = false;
|
||||
for (int j = 0; j < license_renewal.client_id().client_info_size(); ++j) {
|
||||
ClientIdentification_NameValue client_info =
|
||||
license_renewal.client_id().client_info(i);
|
||||
if (name_value_params[i].first.compare(client_info.name()) == 0 &&
|
||||
name_value_params[i].second.compare(client_info.value()) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found) << config->test_description;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->enable_privacy_mode) {
|
||||
EXPECT_EQ(config->renew_with_client_id,
|
||||
license_renewal.has_encrypted_client_id())
|
||||
<< config->test_description;
|
||||
EXPECT_NE(
|
||||
0u, license_renewal.encrypted_client_id().encrypted_client_id().size());
|
||||
}
|
||||
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, true);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Cdm, WvCdmStreamingLicenseRenewalTest,
|
||||
::testing::Range(&streaming_renew_client_id_test_configuration[0],
|
||||
&streaming_renew_client_id_test_configuration[5]));
|
||||
|
||||
class WvCdmOfflineLicenseReleaseTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<
|
||||
RenewWithClientIdTestConfiguration*> {};
|
||||
|
||||
TEST_P(WvCdmOfflineLicenseReleaseTest, DISABLED_WithClientId) {
|
||||
Unprovision();
|
||||
Provision(kLevelDefault);
|
||||
|
||||
RenewWithClientIdTestConfiguration* config = GetParam();
|
||||
std::string key_id;
|
||||
std::string client_auth;
|
||||
GetOfflineConfiguration(&key_id, &client_auth);
|
||||
|
||||
if (config->renew_with_client_id) {
|
||||
key_id = a2bs_hex(
|
||||
"00000040" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"00000020" // pssh data size
|
||||
// pssh data:
|
||||
"08011a0d7769646576696e655f746573"
|
||||
"74220d6f66666c696e655f636c697033");
|
||||
}
|
||||
|
||||
const uint32_t kNameValueParamSize = 2;
|
||||
std::pair<std::string, std::string> name_value_params[kNameValueParamSize] = {
|
||||
{"Name1", "Value1"}, {"Name2", "Value2"}};
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
if (config->specify_app_parameters) {
|
||||
for (uint32_t i = 0; i < kNameValueParamSize; ++i) {
|
||||
app_parameters[name_value_params[i].first] = name_value_params[i].second;
|
||||
}
|
||||
}
|
||||
|
||||
TestWvCdmClientPropertySet property_set;
|
||||
if (config->enable_privacy_mode) {
|
||||
property_set.set_use_privacy_mode(true);
|
||||
if (config->specify_service_certificate)
|
||||
property_set.set_service_certificate(a2bs_hex(kServiceCertificate));
|
||||
}
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeOffline, NULL);
|
||||
if (config->enable_privacy_mode && !config->specify_service_certificate) {
|
||||
std::string resp = GetKeyRequestResponse(g_license_server, client_auth);
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_),
|
||||
wvcdm::NEED_KEY);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
}
|
||||
std::string key_response;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false, &key_response);
|
||||
|
||||
// Validate signed license
|
||||
SignedMessage signed_message;
|
||||
EXPECT_TRUE(signed_message.ParseFromString(key_response))
|
||||
<< config->test_description;
|
||||
EXPECT_EQ(SignedMessage::LICENSE, signed_message.type())
|
||||
<< config->test_description;
|
||||
EXPECT_TRUE(signed_message.has_signature()) << config->test_description;
|
||||
EXPECT_TRUE(!signed_message.msg().empty()) << config->test_description;
|
||||
|
||||
// Verify license request
|
||||
video_widevine_server::sdk::License license;
|
||||
EXPECT_TRUE(license.ParseFromString(signed_message.msg()))
|
||||
<< config->test_description;
|
||||
|
||||
// Verify renew_with_client_id
|
||||
EXPECT_EQ(config->renew_with_client_id,
|
||||
license.policy().has_renew_with_client_id());
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_TRUE(key_set_id_.size() > 0);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&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();
|
||||
CdmKeyMessage key_msg;
|
||||
GenerateKeyRelease(key_set_id, &property_set, &key_msg);
|
||||
key_set_id_ = key_set_id;
|
||||
|
||||
// Validate signed renewal request
|
||||
EXPECT_TRUE(signed_message.ParseFromString(key_msg))
|
||||
<< config->test_description;
|
||||
EXPECT_EQ(SignedMessage::LICENSE_REQUEST, signed_message.type())
|
||||
<< config->test_description;
|
||||
EXPECT_TRUE(signed_message.has_signature()) << config->test_description;
|
||||
EXPECT_TRUE(!signed_message.msg().empty()) << config->test_description;
|
||||
|
||||
// Verify license request
|
||||
video_widevine_server::sdk::LicenseRequest license_release;
|
||||
EXPECT_TRUE(license_release.ParseFromString(signed_message.msg()))
|
||||
<< config->test_description;
|
||||
|
||||
// Verify ClientId
|
||||
EXPECT_EQ(config->renew_with_client_id && !config->enable_privacy_mode,
|
||||
license_release.has_client_id())
|
||||
<< config->test_description;
|
||||
|
||||
if (config->specify_app_parameters) {
|
||||
for (uint32_t i = 0; i < kNameValueParamSize; ++i) {
|
||||
bool found = false;
|
||||
for (int j = 0; j < license_release.client_id().client_info_size(); ++j) {
|
||||
ClientIdentification_NameValue client_info =
|
||||
license_release.client_id().client_info(i);
|
||||
if (name_value_params[i].first.compare(client_info.name()) == 0 &&
|
||||
name_value_params[i].second.compare(client_info.value()) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found) << config->test_description;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->enable_privacy_mode) {
|
||||
EXPECT_EQ(config->renew_with_client_id,
|
||||
license_release.has_encrypted_client_id())
|
||||
<< config->test_description;
|
||||
EXPECT_NE(
|
||||
0u, license_release.encrypted_client_id().encrypted_client_id().size());
|
||||
}
|
||||
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Cdm, WvCdmOfflineLicenseReleaseTest,
|
||||
::testing::Range(&offline_release_client_id_test_configuration[0],
|
||||
&offline_release_client_id_test_configuration[4]));
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
|
||||
Unprovision();
|
||||
Provision(kLevelDefault);
|
||||
@@ -1318,10 +1622,15 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
|
||||
}
|
||||
status = decryptor_.GetUsageInfo(app_id, &usage_info);
|
||||
switch (status) {
|
||||
case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); break;
|
||||
case NO_ERROR: EXPECT_TRUE(usage_info.empty()); break;
|
||||
default: FAIL() << "GetUsageInfo failed with error "
|
||||
<< static_cast<int>(status) ; break;
|
||||
case KEY_MESSAGE:
|
||||
EXPECT_FALSE(usage_info.empty());
|
||||
break;
|
||||
case NO_ERROR:
|
||||
EXPECT_TRUE(usage_info.empty());
|
||||
break;
|
||||
default:
|
||||
FAIL() << "GetUsageInfo failed with error " << static_cast<int>(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1581,9 +1890,8 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
|
||||
std::string response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
std::vector<std::string> files;
|
||||
@@ -1630,20 +1938,17 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
|
||||
TestWvCdmClientPropertySet property_set;
|
||||
property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
|
||||
EXPECT_EQ(
|
||||
wvcdm::NEED_PROVISIONING,
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL,
|
||||
&session_id_));
|
||||
EXPECT_EQ(wvcdm::NEED_PROVISIONING,
|
||||
decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN,
|
||||
NULL, &session_id_));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
|
||||
cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_,
|
||||
&provisioning_server_url));
|
||||
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
|
||||
response =
|
||||
GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
response = GetCertRequestResponse(g_config->provisioning_server_url());
|
||||
EXPECT_NE(0, static_cast<int>(response.size()));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert,
|
||||
&wrapped_key));
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse(
|
||||
EMPTY_ORIGIN, response, &cert, &wrapped_key));
|
||||
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set,
|
||||
EMPTY_ORIGIN, NULL, &session_id_));
|
||||
@@ -1948,16 +2253,17 @@ TEST(VersionNumberTest, VersionNumberChangeCanary) {
|
||||
char release_number[PROPERTY_VALUE_MAX];
|
||||
ASSERT_GT(property_get("ro.build.version.release", release_number, "Unknown"),
|
||||
0);
|
||||
EXPECT_STREQ("MNC", release_number) <<
|
||||
"The Android version number has changed. You need to update this test "
|
||||
"and also possibly update the Widevine version number in "
|
||||
"properties_android.cpp.";
|
||||
EXPECT_STREQ("MNC", release_number)
|
||||
<< "The Android version number has changed. You need to update this test "
|
||||
"and also possibly update the Widevine version number in "
|
||||
"properties_android.cpp.";
|
||||
|
||||
std::string widevine_version;
|
||||
ASSERT_TRUE(Properties::GetWVCdmVersion(&widevine_version));
|
||||
EXPECT_EQ("v3.0.0-android", widevine_version) <<
|
||||
"The Widevine CDM version number has changed. Did you forget to update "
|
||||
"this test after changing it?";
|
||||
EXPECT_EQ("v3.0.0-android", widevine_version)
|
||||
<< "The Widevine CDM version number has changed. Did you forget to "
|
||||
"update "
|
||||
"this test after changing it?";
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
@@ -1981,8 +2287,8 @@ void show_menu(char* prog_name) {
|
||||
std::cout << std::setw(35) << std::left << " ";
|
||||
std::cout << "gp (case sensitive) for GooglePlay server" << std::endl;
|
||||
std::cout << std::setw(35) << std::left << " ";
|
||||
std::cout << "cp (case sensitive) for Content Protection server"
|
||||
<< std::endl << std::endl;
|
||||
std::cout << "cp (case sensitive) for Content Protection server" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
std::cout << std::setw(35) << std::left << " -k/--keyid=<key_id>";
|
||||
std::cout << "configure the key id or pssh, in hex format" << std::endl
|
||||
@@ -1997,7 +2303,8 @@ void show_menu(char* prog_name) {
|
||||
std::cout << std::setw(35) << std::left << " -u/--server=<server_url>";
|
||||
std::cout
|
||||
<< "configure the license server url, please include http[s] in the url"
|
||||
<< std::endl << std::endl;
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
Reference in New Issue
Block a user