Support Offline Licenses
Bug: 8621588 Merge of the following CLs from the Widevine CDM repository: https://widevine-internal-review.googlesource.com/#/c/5602/ https://widevine-internal-review.googlesource.com/#/c/5431/ https://widevine-internal-review.googlesource.com/#/c/5660/ Change-Id: If37940e2535e1a1eca95e4394d8cf9bf689e9c3a
This commit is contained in:
@@ -36,6 +36,16 @@ const std::string kProductionProvisioningServerUrl =
|
||||
"https://www.googleapis.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
|
||||
// TODO(edwinwong, rfrias): refactor to set these parameters though config
|
||||
std::string kServerSdkClientAuth = "";
|
||||
wvcdm::KeyId kServerSdkKeyId = wvcdm::a2bs_hex(
|
||||
"000000347073736800000000"
|
||||
"edef8ba979d64acea3c827dcd51d21ed00000014"
|
||||
"0801121030313233343536373839414243444546");
|
||||
std::string kServerSdkLicenseServer = "http://kir03fcpg174.widevine.net/"
|
||||
"widevine/cgi-bin/drm.cgi";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -57,34 +67,45 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
|
||||
protected:
|
||||
void GenerateKeyRequest(const std::string& key_system,
|
||||
const std::string& init_data) {
|
||||
const std::string& init_data,
|
||||
CdmLicenseType license_type) {
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
std::string server_url;
|
||||
EXPECT_EQ(decryptor_.GenerateKeyRequest(session_id_,
|
||||
init_data,
|
||||
kLicenseTypeStreaming,
|
||||
app_parameters,
|
||||
&key_msg_,
|
||||
&server_url), wvcdm::KEY_MESSAGE);
|
||||
std::string key_set_id;
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(session_id_, key_set_id, init_data,
|
||||
license_type, app_parameters,
|
||||
&key_msg_, &server_url));
|
||||
EXPECT_EQ(0, static_cast<int>(server_url.size()));
|
||||
}
|
||||
|
||||
void GenerateRenewalRequest(const std::string& key_system,
|
||||
const std::string& not_used) {
|
||||
CdmLicenseType license_type) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate.
|
||||
std::string init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
std::string server_url;
|
||||
EXPECT_EQ(decryptor_.GenerateKeyRequest(session_id_,
|
||||
init_data,
|
||||
kLicenseTypeStreaming,
|
||||
app_parameters,
|
||||
&key_msg_,
|
||||
&server_url), wvcdm::KEY_MESSAGE);
|
||||
std::string key_set_id;
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(session_id_, key_set_id, init_data,
|
||||
license_type, app_parameters,
|
||||
&key_msg_, &server_url));
|
||||
EXPECT_NE(0, static_cast<int>(server_url.size()));
|
||||
}
|
||||
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id) {
|
||||
CdmSessionId session_id;
|
||||
CdmInitData init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
std::string server_url;
|
||||
EXPECT_EQ(wvcdm::KEY_MESSAGE,
|
||||
decryptor_.GenerateKeyRequest(session_id, key_set_id, init_data,
|
||||
kLicenseTypeRelease, app_parameters,
|
||||
&key_msg_, &server_url));
|
||||
EXPECT_EQ(0, static_cast<int>(server_url.size()));
|
||||
}
|
||||
|
||||
void DumpResponse(const std::string& description,
|
||||
const std::string& response) {
|
||||
if (description.empty())
|
||||
@@ -176,7 +197,13 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
return "";
|
||||
}
|
||||
|
||||
url_request.PostRequest(key_msg_);
|
||||
// TODO(edwinwong, rfrias): need a cleaner solution to handle
|
||||
// HTTP servers that use chunking vs those that do not
|
||||
if (server_url.compare(kServerSdkLicenseServer) == 0)
|
||||
url_request.PostRequest(key_msg_);
|
||||
else
|
||||
url_request.PostRequestChunk(key_msg_);
|
||||
|
||||
std::string http_response;
|
||||
std::string message_body;
|
||||
int resp_bytes = url_request.GetResponse(http_response);
|
||||
@@ -248,20 +275,22 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
std::string resp = GetKeyRequestResponse(server_url,
|
||||
client_auth,
|
||||
200);
|
||||
|
||||
if (is_renewal) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp), wvcdm::KEY_ADDED);
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
}
|
||||
else {
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp), wvcdm::KEY_ADDED);
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
}
|
||||
}
|
||||
|
||||
wvcdm::WvContentDecryptionModule decryptor_;
|
||||
std::string key_msg_;
|
||||
std::string session_id_;
|
||||
CdmKeyMessage key_msg_;
|
||||
CdmSessionId session_id_;
|
||||
CdmKeySetId key_set_id_;
|
||||
};
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
|
||||
@@ -304,7 +333,7 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRetryTest) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, BaseMessageTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
GetKeyRequestResponse(g_license_server, g_client_auth, 200);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
@@ -313,31 +342,76 @@ TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
|
||||
std::string wrong_message = wvcdm::a2bs_hex(g_wrong_key_id);
|
||||
GenerateKeyRequest(g_key_system, wrong_message);
|
||||
GenerateKeyRequest(g_key_system, wrong_message, kLicenseTypeStreaming);
|
||||
GetKeyRequestResponse(g_license_server, g_client_auth, 500);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, AddKeyTest) {
|
||||
TEST_F(WvCdmRequestLicenseTest, AddSteamingKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, kServerSdkKeyId, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(kServerSdkLicenseServer, kServerSdkClientAuth,
|
||||
kServerSdkKeyId, false);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, kServerSdkKeyId, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(kServerSdkLicenseServer, kServerSdkClientAuth,
|
||||
kServerSdkKeyId, false);
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
session_id_.clear();
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, DISABLED_ReleaseOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, kServerSdkKeyId, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(kServerSdkLicenseServer, kServerSdkClientAuth,
|
||||
kServerSdkKeyId, 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, &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);
|
||||
VerifyKeyRequestResponse(kServerSdkLicenseServer, kServerSdkClientAuth,
|
||||
kServerSdkKeyId, false);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, LicenseRenewal) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
GenerateRenewalRequest(g_key_system, g_key_id);
|
||||
GenerateRenewalRequest(g_key_system, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, true);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
CdmQueryMap query_info;
|
||||
@@ -405,7 +479,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, QueryKeyControlInfo) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
CdmQueryMap query_info;
|
||||
@@ -425,7 +499,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyControlInfo) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ClearDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
// key 1, clear, 256b
|
||||
@@ -525,7 +599,7 @@ TEST_F(WvCdmRequestLicenseTest, ClearDecryptionNoKeyTest) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, DecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
// key 1, encrypted, 256b
|
||||
@@ -576,7 +650,7 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionTest) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, SwitchKeyDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
uint8_t data_blocks = 2;
|
||||
@@ -657,7 +731,7 @@ TEST_F(WvCdmRequestLicenseTest, SwitchKeyDecryptionTest) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, PartialBlockDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
// key 3, encrypted, 125b, offset 0
|
||||
@@ -700,7 +774,7 @@ TEST_F(WvCdmRequestLicenseTest, PartialBlockDecryptionTest) {
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, PartialBlockWithOffsetDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
// key 3, encrypted, 123b, offset 5
|
||||
@@ -746,7 +820,7 @@ TEST_F(WvCdmRequestLicenseTest, PartialBlockWithOffsetDecryptionTest) {
|
||||
/*
|
||||
TEST_F(WvCdmRequestLicenseTest, KeyControlBlockDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_system, g_key_id);
|
||||
GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false);
|
||||
|
||||
DecryptionData data;
|
||||
|
||||
Reference in New Issue
Block a user